blob: 79e64ee554231ecec93800ec61fd091ed0266dd9 [file] [log] [blame]
# 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)