| # Copyright lowRISC contributors. | 
 | # Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
 | # SPDX-License-Identifier: Apache-2.0 | 
 |  | 
 | import logging as log | 
 | import sys | 
 | import os | 
 |  | 
 | from CfgJson import load_hjson | 
 |  | 
 | import FormalCfg | 
 | import CdcCfg | 
 | import RdcCfg | 
 | import LintCfg | 
 | import SimCfg | 
 | import SynCfg | 
 |  | 
 |  | 
 | def _load_cfg(path, initial_values): | 
 |     '''Worker function for make_cfg. | 
 |  | 
 |     initial_values is passed to load_hjson (see documentation there). | 
 |  | 
 |     Returns a pair (cls, hjson_data) on success or raises a RuntimeError on | 
 |     failure. | 
 |  | 
 |     ''' | 
 |     # Set the `self_dir` template variable to the path of the currently | 
 |     # processed Hjson file. | 
 |     assert 'self_dir' in initial_values | 
 |     initial_values['self_dir'] = os.path.dirname(path) | 
 |  | 
 |     # Start by loading up the hjson file and any included files | 
 |     hjson_data = load_hjson(path, initial_values) | 
 |  | 
 |     # Look up the value of flow in the loaded data. This is a required field, | 
 |     # and tells us what sort of FlowCfg to make. | 
 |     flow = hjson_data.get('flow') | 
 |     if flow is None: | 
 |         raise RuntimeError('{!r}: No value for the "flow" key. Are you sure ' | 
 |                            'this is a dvsim configuration file?' | 
 |                            .format(path)) | 
 |  | 
 |     classes = [ | 
 |         RdcCfg.RdcCfg, | 
 |         CdcCfg.CdcCfg, | 
 |         LintCfg.LintCfg, | 
 |         SynCfg.SynCfg, | 
 |         FormalCfg.FormalCfg, | 
 |         SimCfg.SimCfg | 
 |     ] | 
 |     found_cls = None | 
 |     known_types = [] | 
 |     for cls in classes: | 
 |         assert cls.flow is not None | 
 |         known_types.append(cls.flow) | 
 |         if cls.flow == flow: | 
 |             found_cls = cls | 
 |             break | 
 |     if found_cls is None: | 
 |         raise RuntimeError('{}: Configuration file sets "flow" to {!r}, but ' | 
 |                            'this is not a known flow (known: {}).' | 
 |                            .format(path, flow, ', '.join(known_types))) | 
 |  | 
 |     return (found_cls, hjson_data) | 
 |  | 
 |  | 
 | def _make_child_cfg(path, args, initial_values): | 
 |     try: | 
 |         cls, hjson_data = _load_cfg(path, initial_values) | 
 |     except RuntimeError as err: | 
 |         log.error(str(err)) | 
 |         sys.exit(1) | 
 |  | 
 |     # Since this is a child configuration (from some primary configuration), | 
 |     # make sure that we aren't ourselves a primary configuration. We don't need | 
 |     # multi-level hierarchies and this avoids circular dependencies. | 
 |     if 'use_cfgs' in hjson_data: | 
 |         raise RuntimeError('{}: Configuration file has use_cfgs, but is ' | 
 |                            'itself included from another configuration.' | 
 |                            .format(path)) | 
 |  | 
 |     # Call cls as a constructor. Note that we pass None as the mk_config | 
 |     # argument: this is not supposed to load anything else. | 
 |     return cls(path, hjson_data, args, None) | 
 |  | 
 |  | 
 | def make_cfg(path, args, proj_root): | 
 |     '''Make a flow config by loading the config file at path | 
 |  | 
 |     args is the arguments passed to the dvsim.py tool and proj_root is the top | 
 |     of the project. | 
 |  | 
 |     ''' | 
 |     initial_values = { | 
 |         'proj_root': proj_root, | 
 |         'self_dir': os.path.dirname(path), | 
 |     } | 
 |     if args.tool is not None: | 
 |         initial_values['tool'] = args.tool | 
 |  | 
 |     try: | 
 |         cls, hjson_data = _load_cfg(path, initial_values) | 
 |     except RuntimeError as err: | 
 |         log.error(str(err)) | 
 |         sys.exit(1) | 
 |  | 
 |     def factory(child_path): | 
 |         child_ivs = initial_values.copy() | 
 |         child_ivs['flow'] = hjson_data['flow'] | 
 |         return _make_child_cfg(child_path, args, child_ivs) | 
 |  | 
 |     return cls(path, hjson_data, args, factory) |