12
12
from argparse import ArgumentParser
13
13
from configparser import ConfigParser
14
14
from logging import getLogger
15
- from os .path import dirname , isdir , isfile , join as joinpath , normpath
15
+ from os .path import abspath , dirname , isdir , isfile , join as joinpath , normpath
16
16
from traceback import format_exc
17
17
from typing import Optional
18
18
import re
@@ -53,12 +53,18 @@ def __init__(self):
53
53
self ._roms : dict [Optional [int ], dict [str , str ]] = {}
54
54
self ._otp : dict [str , str ] = {}
55
55
self ._lc : dict [str , str ] = {}
56
+ self ._top_name : Optional [str ] = None
57
+
58
+ @property
59
+ def top_name (self ) -> Optional [str ]:
60
+ return self ._top_name
56
61
57
62
def load_top_config (self , toppath : str ) -> None :
58
63
"""Load data from HJSON top configuration file."""
59
64
assert not _HJSON_ERROR
60
65
with open (toppath , 'rt' ) as tfp :
61
66
cfg = hjload (tfp )
67
+ self ._top_name = cfg .get ('name' )
62
68
for module in cfg .get ('module' ) or []:
63
69
modtype = module .get ('type' )
64
70
if modtype == 'rom_ctrl' :
@@ -232,9 +238,9 @@ def main():
232
238
desc = sys .modules [__name__ ].__doc__ .split ('.' , 1 )[0 ].strip ()
233
239
argparser = ArgumentParser (description = f'{ desc } .' )
234
240
files = argparser .add_argument_group (title = 'Files' )
235
- files .add_argument ('opentitan' , nargs = 1 , metavar = 'TOPDIR ' ,
241
+ files .add_argument ('opentitan' , nargs = '*' , metavar = 'OTDIR ' ,
236
242
help = 'OpenTitan top directory' )
237
- files .add_argument ('-T' , '--top' , choices = top_map .keys (), required = True ,
243
+ files .add_argument ('-T' , '--top' , choices = top_map .keys (),
238
244
help = 'OpenTitan top name' )
239
245
files .add_argument ('-o' , '--out' , metavar = 'CFG' ,
240
246
help = 'Filename of the config file to generate' )
@@ -258,25 +264,63 @@ def main():
258
264
args = argparser .parse_args ()
259
265
debug = args .debug
260
266
261
- configure_loggers (args .verbose , 'cfggen' , 'otp' )
267
+ log = configure_loggers (args .verbose , 'cfggen' , 'otp' )[ 0 ]
262
268
263
269
if _HJSON_ERROR :
264
270
argparser .error ('Missing HJSON module: {_HJSON_ERROR}' )
265
271
266
- topdir = args .opentitan [0 ]
267
- if not isdir (topdir ):
268
- argparser .error ('Invalid OpenTitan top directory' )
269
- ot_dir = normpath (topdir )
270
- ltop = args .top .lower ()
271
- top = f'top_{ ltop } '
272
- var = top_map [args .top ]
273
- if not args .topcfg :
274
- cfgpath = joinpath (ot_dir , f'hw/{ top } /data/autogen/{ top } .gen.hjson' )
275
- else :
276
- cfgpath = args .topcfg
277
- if not isfile (cfgpath ):
278
- argparser .error (f"No such file '{ cfgpath } '" )
272
+ cfg = OtConfiguration ()
279
273
274
+ topcfg = args .topcfg
275
+ if not topcfg :
276
+ if not args .opentitan :
277
+ argparser .error ('TOPDIR is required is no top file is '
278
+ 'specified' )
279
+ ot_dir = args .opentitan [0 ]
280
+ if not isdir (ot_dir ):
281
+ argparser .error ('Invalid OpenTitan top directory' )
282
+ ot_dir = abspath (ot_dir )
283
+ if not args .top :
284
+ argparser .error ('Top name is required if no top file is '
285
+ 'specified' )
286
+ ltop = args .top .lower ()
287
+ top = f'top_{ ltop } '
288
+ topvar = top_map [args .top ]
289
+ topcfg = joinpath (ot_dir , f'hw/{ top } /data/autogen/{ top } .gen.hjson' )
290
+ if not isfile (topcfg ):
291
+ argparser .error (f"No such file '{ topcfg } '" )
292
+ log .info ("Top config: '%s'" , topcfg )
293
+ cfg .load_top_config (topcfg )
294
+ else :
295
+ if not isfile (topcfg ):
296
+ argparser .error (f'No such top file: { topcfg } ' )
297
+ cfg .load_top_config (topcfg )
298
+ ltop = cfg .top_name
299
+ if not ltop :
300
+ argparser .error ('Unknown top name' )
301
+ log .info ("Top: '%s'" , cfg .top_name )
302
+ ltop = ltop .lower ()
303
+ topvar = {k .lower (): v for k , v in top_map .items ()}.get (ltop )
304
+ if not topvar :
305
+ argparser .error (f'Unsupported top name: { cfg .top_name } ' )
306
+ top = f'top_{ ltop } '
307
+ ot_dir = args .opentitan [0 ] if args .opentitan else None
308
+ if not ot_dir :
309
+ check_dir = f'hw/{ top } /data'
310
+ cur_dir = dirname (topcfg )
311
+ while cur_dir :
312
+ check_path = joinpath (cur_dir , check_dir )
313
+ if isdir (check_path ):
314
+ ot_dir = cur_dir
315
+ break
316
+ cur_dir = dirname (cur_dir )
317
+ if not ot_dir :
318
+ argparser .error ('Cannot find OT directory' )
319
+ elif not isdir (ot_dir ):
320
+ argparser .error ('Invalid OpenTitan top directory' )
321
+ ot_dir = abspath (ot_dir )
322
+ log .info ("OT directory: '%s'" , ot_dir )
323
+ log .info ("Variant: '%s'" , topvar )
280
324
if not args .lifecycle :
281
325
lcpath = joinpath (ot_dir , 'hw/ip/lc_ctrl/rtl/lc_ctrl_state_pkg.sv' )
282
326
else :
@@ -293,10 +337,9 @@ def main():
293
337
argparser .error (f"No such file '{ ocpath } '" )
294
338
295
339
cfg = OtConfiguration ()
296
- cfg .load_top_config (cfgpath )
297
340
cfg .load_lifecycle (lcpath )
298
341
cfg .load_otp_constants (ocpath )
299
- cfg .save (var , args .socid , args .count , args .out )
342
+ cfg .save (topvar , args .socid , args .count , args .out )
300
343
301
344
except (IOError , ValueError , ImportError ) as exc :
302
345
print (f'\n Error: { exc } ' , file = sys .stderr )
0 commit comments