Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added netlistsvg wrapper/generator #247

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Moved to argparse, pathlib, subprocess
Signed-off-by: Wojciech Gryncewicz <wgryncewicz@antmicro.com>
  • Loading branch information
wgryncewicz committed Nov 18, 2020
commit 17c37e15cc3330e011a4e937364b51be8ff4c3b6
99 changes: 74 additions & 25 deletions scripts/python-skywater-pdk/skywater_pdk/netlistsvg-generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,25 @@
import json
import os
import sys
import argparse
import pathlib
import glob
import subprocess

def outfile(cellpath, define_data, ftype='', extra='', exists=False):
''' Determines output file path and name.

# prerequisities: netlistsvg
# input: paths to cell dirs, containing Yosys netlist
# output: generates [cell_prefix].schematic.svg
# example usage 1: ./netlistsvg-generate.py \
# ../../../libraries/sky130_fd_sc_ms/latest/cells/a2111o \
# ../../../libraries/sky130_fd_sc_ms/latest/cells/a2111oi
# example usage 2: ./netlistsvg-generate.py ALLLIBS
Args:
cellpath - path to a cell [str of pathlib.Path]
define_data - cell definition data [dic]
ftype - file type suffix [str]
extra - extra suffix [str]
exist - optional check if file exists [bool or None]

Returns:
outpath - output file namepath [str]
'''

def outfile(cellpath, define_data, ftype='', extra='', exists=False):
fname = define_data['name'].lower().replace('$', '_')
if ftype:
ftype = '.'+ftype
Expand All @@ -40,18 +48,29 @@ def outfile(cellpath, define_data, ftype='', extra='', exists=False):


def write_netlistsvg(cellpath, define_data):
''' Generates netlistsvg for a given cell.

Args:
cellpath - path to a cell [str of pathlib.Path]
define_data - cell definition data [dic]
'''

netlist_json = os.path.join(cellpath, define_data['file_prefix']+'.json')
if not os.path.exists(netlist_json):
print("No " + define_data['file_prefix'] + ".json in", cellpath)
print("No netlist in", cellpath)
assert os.path.exists(netlist_json), netlist_json
outpath = outfile(cellpath, define_data, 'schematic')
oscmd = 'netlistsvg ' + netlist_json + ' -o ' + outpath
r = os.system(oscmd)>>8
assert r == 0
return r

if subprocess.call(['netlistsvg', netlist_json, '-o', outpath]):
raise ChildProcessError("netlistsvg execution failed")

def process(cellpath):
''' Processes cell indicated by path.
Opens cell definiton and calls further processing

Args:
cellpath - path to a cell [str of pathlib.Path]
'''

print()
print(cellpath)
define_json = os.path.join(cellpath, 'definition.json')
Expand All @@ -66,20 +85,50 @@ def process(cellpath):
return


def main(args):
if len(args) and args[0] == 'ALLLIBS':
scrpath = os.path.dirname(os.path.realpath(__file__))
relpath = '/../../../libraries/*/latest/cells/*'
#relpath = '/../../../libraries/*ms/latest/cells/x*' # DBG: limited
args = os.popen('ls -d ' + scrpath + relpath).read().strip().split('\n')
def main():
''' Generates netlistsvg schematic from cell netlist.'''

prereq_txt = 'prerequisities:\n netlistsvg'
output_txt = 'output:\n generates [cell_prefix].schematic.svg'
allcellpath = '../../../libraries/*/latest/cells/*'

parser = argparse.ArgumentParser(
description = main.__doc__,
epilog = prereq_txt +'\n\n'+ output_txt,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument(
"--all_libs",
help="process all cells in "+allcellpath,
action="store_true")
parser.add_argument(
"cell_dir",
help="path to the cell directory",
type=pathlib.Path,
nargs="*")

args = parser.parse_args()

if args.all_libs:
path = pathlib.Path(allcellpath).expanduser()
parts = path.parts[1:] if path.is_absolute() else path.parts
paths = pathlib.Path(path.root).glob(str(pathlib.Path("").joinpath(*parts)))
args.cell_dir = list(paths)

cell_dirs = [d.resolve() for d in args.cell_dir if d.is_dir()]

errors = 0
for a in args:
for d in cell_dirs:
try:
process(os.path.realpath(a))
except:
process(d)
except KeyboardInterrupt:
sys.exit(1)
except (AssertionError, FileNotFoundError, ChildProcessError) as ex:
print (f'Error: {type(ex).__name__}')
print (f'{ex.args}')
errors +=1
print (f'\n{len(args)} files processed, {errors} errors.')
print (f'\n{len(cell_dirs)} files processed, {errors} errors.')
return 0 if errors else 1

if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
sys.exit(main())