Added fetching FETs by regular expression

Signed-off-by: Grzegorz Latosinski <glatosinski@antmicro.com>
This commit is contained in:
Grzegorz Latosinski 2020-11-17 16:13:44 +01:00
parent f177fa7797
commit 222572af4d
2 changed files with 82 additions and 54 deletions

View File

@ -108,32 +108,35 @@ def read_bins(fname):
def generate_fet_plots( def generate_fet_plots(
fet_type,
corner_path, corner_path,
bins_csv, bins_csv,
outdir, outdir,
outprefix, outprefix,
only_W=None, only_W=None,
ext='svg'): ext='svg'):
print(f'[generate_fet_plots] {fet_type} {corner_path} {bins_csv}' + print(f'[generate_fet_plots] {corner_path} {bins_csv}' +
f'{outdir} {outprefix} {only_W}') f'{outdir} {outprefix} {only_W}')
iparam = f'@m.xm1.m{fet_type}[%s]'
# fet_W and fet_L values here are only for initialization, they are
# later changed in the for loop
c = create_test_circuit(fet_type, iparam, 0.15, 1, corner_path)
bins = read_bins(bins_csv) bins = read_bins(bins_csv)
bins_by_W = defaultdict(list) bins_by_W = defaultdict(list)
# group bins by W # group bins by W
for line in bins: for line in bins:
bins_by_W[line[2]].append(line) bins_by_W[(line[0], float(line[2]))].append(line)
Ws = only_W if only_W is not None else list(bins_by_W.keys()) Ws = [key for key in bins_by_W.keys() if only_W is None or key[1] in only_W]
for fet_type, W in Ws:
if outprefix is None:
outprefix = fet_type
print(f'======> {fet_type}: {W}')
iparam = f'@m.xm1.m{fet_type}[%s]'
# fet_W and fet_L values here are only for initialization, they are
# later changed in the for loop
c = create_test_circuit(fet_type, iparam, 0.15, 1, corner_path)
for W in Ws:
figs, plts = init_plots(fet_type, W) figs, plts = init_plots(fet_type, W)
for dev, bin, fet_W, fet_L in bins_by_W[W]: for dev, bin, fet_W, fet_L in bins_by_W[(fet_type, W)]:
fet_W, fet_L = float(fet_W), float(fet_L) fet_W, fet_L = float(fet_W), float(fet_L)
if only_W is not None and fet_W not in only_W: if only_W is not None and fet_W not in only_W:
continue continue
@ -151,7 +154,7 @@ def generate_fet_plots(
fg.tight_layout() fg.tight_layout()
fg.savefig( fg.savefig(
Path(outdir) / ( Path(outdir) / (
outprefix + f'_{name}_W{str(W).replace(".", "_")}.{ext}'), outprefix + f'_{fet_type}_{name}_W{str(W).replace(".", "_")}.{ext}'),
bbox_extra_artists=(lg,), bbox_extra_artists=(lg,),
bbox_inches='tight' bbox_inches='tight'
) )
@ -162,10 +165,6 @@ def main(argv):
import argparse import argparse
parser = argparse.ArgumentParser(prog=argv[0]) parser = argparse.ArgumentParser(prog=argv[0])
parser.add_argument(
'fet_type',
help='FET type to simulate'
)
parser.add_argument( parser.add_argument(
'corner_path', 'corner_path',
help='Path to corner SPICE file containing FET definition', help='Path to corner SPICE file containing FET definition',
@ -198,11 +197,7 @@ def main(argv):
) )
args = parser.parse_args(argv[1:]) args = parser.parse_args(argv[1:])
if args.outprefix is None:
args.outprefix = args.fet_type
generate_fet_plots( generate_fet_plots(
args.fet_type,
args.corner_path, args.corner_path,
args.bins_csv, args.bins_csv,
args.outdir, args.outdir,

View File

@ -20,6 +20,8 @@
import argparse import argparse
from pathlib import Path from pathlib import Path
import sys import sys
import contextlib
import traceback
from fet_simulator import generate_fet_plots from fet_simulator import generate_fet_plots
@ -27,51 +29,82 @@ from fet_simulator import generate_fet_plots
def main(argv): def main(argv):
parser = argparse.ArgumentParser(prog=argv[0]) parser = argparse.ArgumentParser(prog=argv[0])
parser.add_argument( parser.add_argument(
'fd_pr_dir', 'libraries_dir',
help='Path to the particular version of the primitive library', help='Path to the libraries directory of skywater-pdk',
type=Path type=Path
) )
parser.add_argument( parser.add_argument(
'device_details_dir', 'corner_file',
help='Path to the directory with device details to save images to', help='Path to the corner SPICE file',
type=Path
)
parser.add_argument(
'output_dir',
help='Path to the output directory',
type=Path
)
parser.add_argument(
'--libname',
help='Library name to generate the Symbolator diagrams for',
type=str
)
parser.add_argument(
'--version',
help='Version for which the Symbolator diagrams should be generated',
type=str
)
parser.add_argument(
'--create-dirs',
help='Create directories for output when not present',
action='store_true'
)
parser.add_argument(
'--failed-inputs',
help='Path to files for which Symbolator failed to generate diagram',
type=Path type=Path
) )
args = parser.parse_args(argv[1:]) args = parser.parse_args(argv[1:])
typicalcorner = args.fd_pr_dir / 'models/corners/tt.spice' fetbins = list(args.libraries_dir.rglob('*fet*bins.csv'))
fets = [ nc = contextlib.nullcontext()
['esd_nfet', 'esd_nfet_01v8', None],
['nfet_01v8', 'nfet_01v8', None], with open(args.failed_inputs, 'w') if args.failed_inputs else nc as err:
['nfet_01v8_lvt', 'nfet_01v8_lvt', None], for fetbin in fetbins:
['nfet_03v3_nvt', 'nfet_03v3_nvt', None], outdir = (args.output_dir /
['nfet_03v3_nvt-and-nfet_05v0_nvt', 'nfet_05v0_nvt', None], fetbin.resolve()
['nfet_03v3_nvt-and-nfet_05v0_nvt', 'nfet_03v3_nvt', None], .relative_to(args.libraries_dir.resolve()))
['nfet_05v0_nvt', 'nfet_05v0_nvt', None], if args.libname and args.libname != outdir.parts[0]:
# ['nfet_20v0'], TODO provide continue
# ['nfet_20v0_iso', 'nfet_20v0_nvt_iso', None], TODO invalid bins.csv if args.version and args.version != outdir.parts[1]:
# ['nfet_20v0_nvt', 'nfet_20v0_nvt', None], TODO invalid bins.csv file continue
# ['nfet_20v0_zvt', 'nfet_20v0_zvt', None], TODO invalid bins.csv file print(f'===> {str(fetbin)}')
# ['nfet_g11v0d16v0'], TODO provide try:
['nfet_g5v0d10v5', 'nfet_g5v0d10v5', None], if not outdir.exists():
['pfet_01v8', 'pfet_01v8', None], if args.create_dirs:
['pfet_01v8_hvt', 'pfet_01v8_hvt', None], outdir.mkdir(parents=True)
['pfet_01v8_lvt', 'pfet_01v8_lvt', None], else:
# ['pfet_20v0', 'pfet_20v0', None], TODO some plot issues print('The output directory {str(outdir)} is missing')
['pfet_g5v0d10v5', 'pfet_g5v0d10v5', None], print('Run the script with --create-dirs')
# ['pfet_g5v0d16v0', 'pfet_g5v0d16v0', None] TODO invalid bins.csv file return errno.ENOENT
]
prefix = fetbin.name.replace('.bins.csv', '')
generate_fet_plots(
args.corner_file,
fetbin,
outdir,
f'{prefix}_',
ext='sim.svg'
)
except Exception:
print(
f'Failed to generate FET plot for {str(fetbin)}',
file=sys.stderr
)
traceback.print_exc()
err.write(f'{fetbin}\n')
for outdir, fetname, onlyw in fets:
generate_fet_plots(
f'sky130_fd_pr__{fetname}',
typicalcorner,
args.fd_pr_dir/f'cells/{fetname}/sky130_fd_pr__{fetname}.bins.csv',
args.device_details_dir/outdir,
f'sim_{fetname}_',
onlyw
)
return 0 return 0