blob: f4f853f0f77f0fc26d6cde8d24c237899e81ebd7 [file] [log] [blame]
#!/usr/bin/env python3
#
# Find which layout-extracted SPICE netlists in skywater-pdk-scratch are
# empty (that is, devices were not represented in magic).
import os
import sys
import re
cellroot = '../skywater-pdk-scratch/libraries/sky130_fd_pr/v0.20.1/cells'
celllist = os.listdir(cellroot)
for cellname in celllist:
cellpath = cellroot + '/' + cellname
netlists = []
other = []
cellfiles = os.listdir(cellpath)
stddevrex = re.compile('[xmqdcrl]([^ \t]+)[ \t]+(.*)', re.IGNORECASE)
subcktrex = re.compile('.subckt[ \t]+([^ \t]+)[ \t]+(.*)', re.IGNORECASE)
endsrex = re.compile('.ends', re.IGNORECASE)
for file in cellfiles:
if os.path.splitext(file)[1] == '.spice':
if len(file.split('.')) == 2:
netlists.append(cellpath + '/' + file)
else:
other.append(cellpath + '/' + file)
# Read all netlists that do not come from layout extraction and record
# all subcircuits that are defined in them.
defsubs = {}
for netlist in other:
with open(netlist, 'r') as ifile:
spicelines = ifile.read().splitlines()
insub = False
for line in spicelines:
if not insub:
smatch = subcktrex.match(line)
if smatch:
insub = True
subname = smatch.group(1)
defsubs[subname] = os.path.split(netlist)[1]
else:
ematch = endsrex.match(line)
if ematch:
insub = False
nnetlists = len(netlists)
ess = 's' if nnetlists != 1 else ''
if nnetlists > 0:
print(str(nnetlists) + ' netlist' + ess + ' to check.')
for netlist in netlists:
print('Checking ' + os.path.split(netlist)[1])
with open(netlist, 'r') as ifile:
spicelines = ifile.read().splitlines()
insub = False
has_devices = False
pins_missing = False
shadowed = None
found = False
npins = 0
pins = ''
for line in spicelines:
if not insub:
smatch = subcktrex.match(line)
if smatch:
found = True
insub = True
subname = smatch.group(1)
if subname in defsubs:
shadowed = defsubs[subname]
rest = smatch.group(2)
pins = rest.split(' ')
npins = len(pins)
if npins < 3:
pins_missing = True
else:
ematch = endsrex.match(line)
if ematch:
insub = False
else:
dmatch = stddevrex.match(line)
if dmatch:
has_devices = True
if not found:
print(' ERROR: Nothing in file')
testsubname = os.path.splitext(os.path.split(netlist)[1])[0]
if testsubname in defsubs:
print(' NOTE: Subcircuit exists in ' + defsubs[subname])
if not has_devices:
print(' ERROR: No devices')
if pins_missing:
ess = 's' if npins != 1 else ''
print(' ERROR: Pins missing (' + str(npins) + ' pin' + ess + ' found)')
if shadowed:
print(' ERROR: Subcircuit shadows ' + shadowed)