blob: 18af64d5985f6f953795733e150ffae8f20b3ffa [file] [log] [blame]
Jeff DiCorpod8253762021-01-24 23:46:40 -08001import sys
2import os
3import subprocess
4from pathlib import Path
5import argparse
6from tempfile import mkstemp
7import re
8
9
10def remove_inouts(jsonpath, replacewith='input'):
11 """Replaces inouts with either input or output statements.
12
13 Netlistsvg does not parse inout ports as for now, so they need to be
14 replaced with either input or output to produce a diagram.
15
16 Parameters
17 ----------
18 jsonpath : str
19 Path to JSON file to fix
20 replacewith : str
21 The string to replace 'inout', can be 'input' or 'output'
22 """
23 assert replacewith in ['input', 'output']
24 with open(jsonpath, 'r') as withinouts:
25 lines = withinouts.readlines()
26 with open(jsonpath, 'w') as withoutinouts:
27 for line in lines:
28 withoutinouts.write(re.sub('inout', replacewith, line))
29
30
31def main(argv):
32 parser = argparse.ArgumentParser(argv[0])
33 parser.add_argument(
34 'verilog_rtl_dir',
35 help="Path to the project's verilog/rtl directory",
36 type=Path)
37 parser.add_argument(
38 'output',
39 help="Path to the output SVG file",
40 type=Path)
41 parser.add_argument(
42 '--num-iopads',
43 help='Number of iopads to render',
44 type=int,
45 default=38)
46 parser.add_argument(
47 '--yosys-executable',
48 help='Path to yosys executable',
49 type=Path,
50 default='yosys')
51 parser.add_argument(
52 '--netlistsvg-executable',
53 help='Path to netlistsvg executable',
54 type=Path,
55 default='netlistsvg')
56 parser.add_argument(
57 '--inouts-as',
58 help='To what kind of IO should inout ports be replaced',
59 choices=['input', 'output'],
60 default='input'
61 )
62
63 args = parser.parse_args(argv[1:])
64
65 fd, jsonpath = mkstemp(suffix='-yosys.json')
66 os.close(fd)
67
68 yosyscommand = [
69 f'{str(args.yosys_executable)}',
70 '-p',
71 'read_verilog pads.v defines.v; ' +
72 'read_verilog -lib -overwrite *.v; ' +
73 f'verilog_defines -DMPRJ_IO_PADS={args.num_iopads}; ' +
74 'read_verilog -overwrite caravel.v; ' +
75 'hierarchy -top caravel; ' +
76 'proc; ' +
77 'opt; ' +
78 f'write_json {jsonpath}; '
79 ]
80
81 result = subprocess.run(
82 yosyscommand,
83 cwd=args.verilog_rtl_dir,
84 stdout=subprocess.PIPE,
85 stderr=subprocess.STDOUT
86 )
87
88 exitcode = 0
89 if result.returncode != 0:
90 print(f'Failed to run: {" ".join(yosyscommand)}', file=sys.stderr)
91 print(result.stdout.decode())
92 exitcode = result.returncode
93 else:
94 # TODO once netlistsvg supports inout ports, this should be removed
95 remove_inouts(jsonpath, args.inouts_as)
96 command = f'{args.netlistsvg_executable} {jsonpath} -o {args.output}'
97 result = subprocess.run(
98 command.split(),
99 stdout=subprocess.PIPE,
100 stderr=subprocess.STDOUT
101 )
102 if result.returncode != 0:
103 print(f'Failed to run: {command}', file=sys.stderr)
104 print(result.stdout.decode())
105 exitcode = result.returncode
106
107 os.unlink(jsonpath)
108 sys.exit(exitcode)
109
110
111if __name__ == '__main__':
112 sys.exit(main(sys.argv))