Add files via upload
diff --git a/scripts/count_lvs.py b/scripts/count_lvs.py
new file mode 100644
index 0000000..21b7771
--- /dev/null
+++ b/scripts/count_lvs.py
@@ -0,0 +1,132 @@
+#!/usr/bin/python3
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+
+#
+#---------------------------------------------------------
+# LVS failure check
+#
+# This is a Python script that parses the comp.json
+# output from netgen and reports on the number of
+# errors in the top-level netlist.
+#
+#---------------------------------------------------------
+# Written by Tim Edwards
+# efabless, inc.
+# Pulled from qflow GUI as standalone script Aug 20, 2018
+#---------------------------------------------------------
+
+import os
+import re
+import sys
+import json
+import argparse
+
+def count_LVS_failures(filename):
+ with open(filename, 'r') as cfile:
+ lvsdata = json.load(cfile)
+
+ # Count errors in the JSON file
+ failures = 0
+ devfail = 0
+ netfail = 0
+ pinfail = 0
+ propfail = 0
+ netdiff = 0
+ devdiff = 0
+ ncells = len(lvsdata)
+ for c in range(0, ncells):
+ cellrec = lvsdata[c]
+
+ if c == ncells - 1:
+ topcell = True
+ else:
+ topcell = False
+
+ # Most errors must only be counted for the top cell, because individual
+ # failing cells are flattened and the matching attempted again on the
+ # flattened netlist.
+
+ if topcell:
+ if 'devices' in cellrec:
+ devices = cellrec['devices']
+ devlist = [val for pair in zip(devices[0], devices[1]) for val in pair]
+ devpair = list(devlist[p:p + 2] for p in range(0, len(devlist), 2))
+ for dev in devpair:
+ c1dev = dev[0]
+ c2dev = dev[1]
+ diffdevs = abs(c1dev[1] - c2dev[1])
+ failures += diffdevs
+ devdiff += diffdevs
+
+ if 'nets' in cellrec:
+ nets = cellrec['nets']
+ diffnets = abs(nets[0] - nets[1])
+ failures += diffnets
+ netdiff += diffnets
+
+ if 'badnets' in cellrec:
+ badnets = cellrec['badnets']
+ failures += len(badnets)
+ netfail += len(badnets)
+
+ if 'badelements' in cellrec:
+ badelements = cellrec['badelements']
+ failures += len(badelements)
+ devfail += len(badelements)
+
+ if 'pins' in cellrec:
+ pins = cellrec['pins']
+ pinlist = [val for pair in zip(pins[0], pins[1]) for val in pair]
+ pinpair = list(pinlist[p:p + 2] for p in range(0, len(pinlist), 2))
+ for pin in pinpair:
+ # Avoid flagging global vs. local names, e.g., "gnd" vs. "gnd!,"
+ # and ignore case when comparing pins.
+ pin0 = re.sub('!$', '', pin[0].lower())
+ pin1 = re.sub('!$', '', pin[1].lower())
+ if pin0 != pin1:
+ failures += 1
+ pinfail += 1
+
+ # Property errors must be counted for every cell
+ if 'properties' in cellrec:
+ properties = cellrec['properties']
+ failures += len(properties)
+ propfail += len(properties)
+
+ return [failures, netfail, devfail, pinfail, propfail, netdiff, devdiff]
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser(description='Parses netgen lvs')
+ parser.add_argument('--file', '-f', required=True)
+ args = parser.parse_args()
+ failures = count_LVS_failures(args.file)
+ total = failures[0]
+ if total > 0:
+ failed = True
+ print('LVS reports:')
+ print(' net count difference = ' + str(failures[5]))
+ print(' device count difference = ' + str(failures[6]))
+ print(' unmatched nets = ' + str(failures[1]))
+ print(' unmatched devices = ' + str(failures[2]))
+ print(' unmatched pins = ' + str(failures[3]))
+ print(' property failures = ' + str(failures[4]))
+ else:
+ print('LVS reports no net, device, pin, or property mismatches.')
+
+ print('')
+ print('Total errors = ' + str(total))
+