Added fetching FETs by regular expression
Signed-off-by: Grzegorz Latosinski <glatosinski@antmicro.com>
This commit is contained in:
parent
f177fa7797
commit
222572af4d
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue