blob: 2c0072d3e7329f1ab1a9cbbdeb1f6788c5ca789c [file] [log] [blame]
lowRISC Contributors802543a2019-08-31 12:12:56 +01001#!/usr/bin/env python3
2# Copyright lowRISC contributors.
3# Licensed under the Apache License, Version 2.0, see LICENSE for details.
4# SPDX-License-Identifier: Apache-2.0
5r"""Command-line tool to validate and convert register hjson
6
7"""
8import argparse
9import logging as log
lowRISC Contributors802543a2019-08-31 12:12:56 +010010import re
11import sys
12from pathlib import PurePath
13
14import hjson
lowRISC Contributors802543a2019-08-31 12:12:56 +010015
16from reggen import (gen_cheader, gen_ctheader, gen_dv, gen_html, gen_json,
Cindy Chen0bad7832019-11-07 11:25:00 -080017 gen_rtl, gen_fpv, gen_selfdoc, validate, version)
lowRISC Contributors802543a2019-08-31 12:12:56 +010018
Philipp Wagner14a3fee2019-11-21 10:07:02 +000019DESC = """regtool, generate register info from Hjson source"""
lowRISC Contributors802543a2019-08-31 12:12:56 +010020
21USAGE = '''
22 regtool [options]
23 regtool [options] <input>
24 regtool (-h | --help)
25 regtool (-V | --version)
26'''
27
28
29def main():
30 format = 'hjson'
31 verbose = 0
32
33 parser = argparse.ArgumentParser(
34 prog="regtool",
35 formatter_class=argparse.RawDescriptionHelpFormatter,
36 usage=USAGE,
37 description=DESC)
Eunchan Kim6ec3b892019-10-01 15:02:56 -070038 parser.add_argument('input',
39 nargs='?',
40 metavar='file',
41 type=argparse.FileType('r'),
42 default=sys.stdin,
Philipp Wagner14a3fee2019-11-21 10:07:02 +000043 help='input file in Hjson type')
Eunchan Kim6ec3b892019-10-01 15:02:56 -070044 parser.add_argument('-d',
45 action='store_true',
46 help='Output register documentation (html)')
47 parser.add_argument('--cdefines',
48 '-D',
49 action='store_true',
50 help='Output C defines header')
51 parser.add_argument('--ctdefines',
52 '-T',
53 action='store_true',
54 help='Output C defines header (Titan style)')
55 parser.add_argument('--doc',
56 action='store_true',
57 help='Output source file documentation (gfm)')
58 parser.add_argument('-j',
59 action='store_true',
60 help='Output as formatted JSON')
lowRISC Contributors802543a2019-08-31 12:12:56 +010061 parser.add_argument('-c', action='store_true', help='Output as JSON')
Eunchan Kim6ec3b892019-10-01 15:02:56 -070062 parser.add_argument('-r',
63 action='store_true',
64 help='Output as SystemVerilog RTL')
65 parser.add_argument('-s',
66 action='store_true',
67 help='Output as UVM Register class')
Cindy Chen0bad7832019-11-07 11:25:00 -080068 parser.add_argument('-f',
69 action='store_true',
70 help='Output as FPV CSR rw assertion module')
Eunchan Kim0bd75662020-04-24 10:21:18 -070071 parser.add_argument('--outdir',
72 '-t',
73 help='Target directory for generated RTL; '
74 'tool uses ../rtl if blank.')
Eunchan Kim6ec3b892019-10-01 15:02:56 -070075 parser.add_argument('--outfile',
76 '-o',
77 type=argparse.FileType('w'),
78 default=sys.stdout,
79 help='Target filename for json, html, gfm.')
80 parser.add_argument('--verbose',
81 '-v',
82 action='store_true',
83 help='Verbose and run validate twice')
84 parser.add_argument('--param',
85 '-p',
86 type=str,
Eunchan Kim276af5e2019-10-01 17:02:46 -070087 default="",
Eunchan Kim6ec3b892019-10-01 15:02:56 -070088 help='''Change the Parameter values.
89 Only integer value is supported.
90 You can add multiple param arguments.
91
92 Format: ParamA=ValA;ParamB=ValB
93 ''')
94 parser.add_argument('--version',
95 '-V',
96 action='store_true',
97 help='Show version')
98 parser.add_argument('--novalidate',
99 action='store_true',
100 help='Skip validate, just output json')
lowRISC Contributors802543a2019-08-31 12:12:56 +0100101
102 args = parser.parse_args()
103
104 if args.version:
105 version.show_and_exit(__file__, ["Hjson", "Mako"])
106
107 verbose = args.verbose
108
Eunchan Kim0bd75662020-04-24 10:21:18 -0700109 if args.j:
110 format = 'json'
111 elif args.c:
112 format = 'compact'
113 elif args.d:
114 format = 'html'
115 elif args.doc:
116 format = 'doc'
117 elif args.r:
118 format = 'rtl'
119 elif args.s:
120 format = 'dv'
121 elif args.f:
122 format = 'fpv'
123 elif args.cdefines:
124 format = 'cdh'
125 elif args.ctdefines:
126 format = 'cth'
lowRISC Contributors802543a2019-08-31 12:12:56 +0100127
128 if (verbose):
129 log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG)
130 else:
131 log.basicConfig(format="%(levelname)s: %(message)s")
132
133 outfile = args.outfile
134
135 infile = args.input
136
Eunchan Kim6ec3b892019-10-01 15:02:56 -0700137 params = args.param.split(';')
138
lowRISC Contributors802543a2019-08-31 12:12:56 +0100139 if format == 'rtl':
140 if args.outdir:
141 outdir = args.outdir
142 elif infile != sys.stdin:
143 outdir = str(PurePath(infile.name).parents[1].joinpath("rtl"))
144 else:
145 # Using sys.stdin. not possible to generate RTL
146 log.error("-r option cannot be used with pipe or stdin")
147 elif format == 'dv':
148 if args.outdir:
149 outdir = args.outdir
150 elif infile != sys.stdin:
151 outdir = str(PurePath(infile.name).parents[1].joinpath("dv"))
152 else:
153 # Using sys.stdin. not possible to generate RTL
154 log.error("-s option cannot be used with pipe or stdin")
Cindy Chen0bad7832019-11-07 11:25:00 -0800155 elif format == 'fpv':
156 if args.outdir:
157 outdir = args.outdir
158 elif infile != sys.stdin:
159 outdir = str(PurePath(infile.name).parents[1].joinpath("fpv/vip"))
160 else:
161 # Using sys.stdin. not possible to generate RTL
162 log.error("-s option cannot be used with pipe or stdin")
lowRISC Contributors802543a2019-08-31 12:12:56 +0100163 else:
164 # Ignore
165 outdir = "."
166
167 if format == 'doc':
168 with outfile:
169 gen_selfdoc.document(outfile)
170 exit(0)
171
172 with infile:
173 try:
174 srcfull = infile.read()
Eunchan Kim6ec3b892019-10-01 15:02:56 -0700175 obj = hjson.loads(srcfull,
176 use_decimal=True,
177 object_pairs_hook=validate.checking_dict)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100178 except ValueError:
179 raise SystemExit(sys.exc_info()[1])
180
181 if args.novalidate:
182 with outfile:
183 gen_json.gen_json(obj, outfile, format)
184 outfile.write('\n')
Eunchan Kim6ec3b892019-10-01 15:02:56 -0700185 elif (validate.validate(obj, params=params) == 0):
lowRISC Contributors802543a2019-08-31 12:12:56 +0100186 if (verbose):
187 log.info("Second validate pass (should show added optional keys)")
Eunchan Kim6ec3b892019-10-01 15:02:56 -0700188 validate.validate(obj, params=params)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100189
190 if format == 'rtl':
191 gen_rtl.gen_rtl(obj, outdir)
192 return 0
193 if format == 'dv':
194 gen_dv.gen_dv(obj, outdir)
195 return 0
Cindy Chen0bad7832019-11-07 11:25:00 -0800196 if format == 'fpv':
197 gen_fpv.gen_fpv(obj, outdir)
198 return 0
lowRISC Contributors802543a2019-08-31 12:12:56 +0100199 src_lic = None
200 src_copy = ''
201 found_spdx = None
202 found_lunder = None
203 copy = re.compile(r'.*(copyright.*)|(.*\(c\).*)', re.IGNORECASE)
204 spdx = re.compile(r'.*(SPDX-License-Identifier:.+)')
205 lunder = re.compile(r'.*(Licensed under.+)', re.IGNORECASE)
206 for line in srcfull.splitlines():
207 mat = copy.match(line)
Eunchan Kim0bd75662020-04-24 10:21:18 -0700208 if mat is not None:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100209 src_copy += mat.group(1)
210 mat = spdx.match(line)
Eunchan Kim0bd75662020-04-24 10:21:18 -0700211 if mat is not None:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100212 found_spdx = mat.group(1)
213 mat = lunder.match(line)
Eunchan Kim0bd75662020-04-24 10:21:18 -0700214 if mat is not None:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100215 found_lunder = mat.group(1)
216 if found_lunder:
217 src_lic = found_lunder
218 if found_spdx:
219 src_lic += '\n' + found_spdx
220
221 with outfile:
222 if format == 'html':
223 gen_html.gen_html(obj, outfile)
224 elif format == 'cdh':
225 gen_cheader.gen_cdefines(obj, outfile, src_lic, src_copy)
226 elif format == 'cth':
227 gen_ctheader.gen_cdefines(obj, outfile, src_lic, src_copy)
228 else:
229 gen_json.gen_json(obj, outfile, format)
230
231 outfile.write('\n')
232
233
234if __name__ == '__main__':
235 main()