# Copyright (c) 2017-2020 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2004-2006 The Regents of The University of Michigan
# Copyright (c) 2010-20013 Advanced Micro Devices, Inc.
# Copyright (c) 2013 Mark D. Hill and David A. Wood
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import sys
from types import FunctionType, MethodType, ModuleType
from functools import wraps
import inspect

import m5
from m5.util import *
from m5.util.pybind import *
# Use the pyfdt and not the helper class, because the fdthelper
# relies on the SimObject definition
from m5.ext.pyfdt import pyfdt

# Have to import params up top since Param is referenced on initial
# load (when SimObject class references Param to create a class
# variable, the 'name' param)...
from m5.params import *
# There are a few things we need that aren't in params.__all__ since
# normal users don't need them
from m5.params import ParamDesc, VectorParamDesc, \
     isNullPointer, SimObjectVector, Port

from m5.proxy import *
from m5.proxy import isproxy

#####################################################################
#
# M5 Python Configuration Utility
#
# The basic idea is to write simple Python programs that build Python
# objects corresponding to M5 SimObjects for the desired simulation
# configuration.  For now, the Python emits a .ini file that can be
# parsed by M5.  In the future, some tighter integration between M5
# and the Python interpreter may allow bypassing the .ini file.
#
# Each SimObject class in M5 is represented by a Python class with the
# same name.  The Python inheritance tree mirrors the M5 C++ tree
# (e.g., SimpleCPU derives from BaseCPU in both cases, and all
# SimObjects inherit from a single SimObject base class).  To specify
# an instance of an M5 SimObject in a configuration, the user simply
# instantiates the corresponding Python object.  The parameters for
# that SimObject are given by assigning to attributes of the Python
# object, either using keyword assignment in the constructor or in
# separate assignment statements.  For example:
#
# cache = BaseCache(size='64KB')
# cache.hit_latency = 3
# cache.assoc = 8
#
# The magic lies in the mapping of the Python attributes for SimObject
# classes to the actual SimObject parameter specifications.  This
# allows parameter validity checking in the Python code.  Continuing
# the example above, the statements "cache.blurfl=3" or
# "cache.assoc='hello'" would both result in runtime errors in Python,
# since the BaseCache object has no 'blurfl' parameter and the 'assoc'
# parameter requires an integer, respectively.  This magic is done
# primarily by overriding the special __setattr__ method that controls
# assignment to object attributes.
#
# Once a set of Python objects have been instantiated in a hierarchy,
# calling 'instantiate(obj)' (where obj is the root of the hierarchy)
# will generate a .ini file.
#
#####################################################################

# list of all SimObject classes
allClasses = {}

# dict to look up SimObjects based on path
instanceDict = {}

# Did any of the SimObjects lack a header file?
noCxxHeader = False

def public_value(key, value):
    return key.startswith('_') or \
               isinstance(value, (FunctionType, MethodType, ModuleType,
                                  classmethod, type))

def createCxxConfigDirectoryEntryFile(code, name, simobj, is_header):
    entry_class = 'CxxConfigDirectoryEntry_%s' % name
    param_class = '%sCxxConfigParams' % name

    code('#include "params/%s.hh"' % name)

    if not is_header:
        for param in simobj._params.values():
            if isSimObjectClass(param.ptype):
                code('#include "%s"' % param.ptype._value_dict['cxx_header'])
                code('#include "params/%s.hh"' % param.ptype.__name__)
            else:
                param.ptype.cxx_ini_predecls(code)

    if is_header:
        member_prefix = ''
        end_of_decl = ';'
        code('#include "sim/cxx_config.hh"')
        code()
        code('namespace gem5')
        code('{')
        code()
        code('class ${param_class} : public CxxConfigParams,'
            ' public ${name}Params')
        code('{')
        code('  private:')
        code.indent()
        code('class DirectoryEntry : public CxxConfigDirectoryEntry')
        code('{')
        code('  public:')
        code.indent()
        code('DirectoryEntry();');
        code()
        code('CxxConfigParams *makeParamsObject() const')
        code('{ return new ${param_class}; }')
        code.dedent()
        code('};')
        code()
        code.dedent()
        code('  public:')
        code.indent()
    else:
        member_prefix = '%s::' % param_class
        end_of_decl = ''
        code('#include "%s"' % simobj._value_dict['cxx_header'])
        code('#include "base/str.hh"')
        code('#include "cxx_config/${name}.hh"')

        code('namespace gem5')
        code('{')
        code()
        code('${member_prefix}DirectoryEntry::DirectoryEntry()');
        code('{')

        def cxx_bool(b):
            return 'true' if b else 'false'

        code.indent()
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            code('parameters["%s"] = new ParamDesc("%s", %s, %s);' %
                (param.name, param.name, cxx_bool(is_vector),
                cxx_bool(is_simobj)));

        for port in simobj._ports.values():
            is_vector = isinstance(port, m5.params.VectorPort)
            is_requestor = port.role == 'GEM5 REQUESTOR'

            code('ports["%s"] = new PortDesc("%s", %s, %s);' %
                (port.name, port.name, cxx_bool(is_vector),
                cxx_bool(is_requestor)))

        code.dedent()
        code('}')
        code()

    code('bool ${member_prefix}setSimObject(const std::string &name,')
    code('    SimObject *simObject)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false) {')
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            if is_simobj and not is_vector:
                code('} else if (name == "${{param.name}}") {')
                code.indent()
                code('this->${{param.name}} = '
                    'dynamic_cast<${{param.ptype.cxx_type}}>(simObject);')
                code('if (simObject && !this->${{param.name}})')
                code('   ret = false;')
                code.dedent()
        code('} else {')
        code('    ret = false;')
        code('}')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('bool ${member_prefix}setSimObjectVector('
        'const std::string &name,')
    code('    const std::vector<SimObject *> &simObjects)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false) {')
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            if is_simobj and is_vector:
                code('} else if (name == "${{param.name}}") {')
                code.indent()
                code('this->${{param.name}}.clear();')
                code('for (auto i = simObjects.begin(); '
                    'ret && i != simObjects.end(); i ++)')
                code('{')
                code.indent()
                code('${{param.ptype.cxx_type}} object = '
                    'dynamic_cast<${{param.ptype.cxx_type}}>(*i);')
                code('if (*i && !object)')
                code('    ret = false;')
                code('else')
                code('    this->${{param.name}}.push_back(object);')
                code.dedent()
                code('}')
                code.dedent()
        code('} else {')
        code('    ret = false;')
        code('}')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('void ${member_prefix}setName(const std::string &name_)'
        '${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('this->name = name_;')
        code.dedent()
        code('}')

    if is_header:
        code('const std::string &${member_prefix}getName()')
        code('{ return this->name; }')

    code()
    code('bool ${member_prefix}setParam(const std::string &name,')
    code('    const std::string &value, const Flags flags)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false) {')
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            if not is_simobj and not is_vector:
                code('} else if (name == "${{param.name}}") {')
                code.indent()
                param.ptype.cxx_ini_parse(code,
                    'value', 'this->%s' % param.name, 'ret =')
                code.dedent()
        code('} else {')
        code('    ret = false;')
        code('}')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('bool ${member_prefix}setParamVector('
        'const std::string &name,')
    code('    const std::vector<std::string> &values,')
    code('    const Flags flags)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false) {')
        for param in simobj._params.values():
            is_vector = isinstance(param, m5.params.VectorParamDesc)
            is_simobj = issubclass(param.ptype, m5.SimObject.SimObject)

            if not is_simobj and is_vector:
                code('} else if (name == "${{param.name}}") {')
                code.indent()
                code('${{param.name}}.clear();')
                code('for (auto i = values.begin(); '
                    'ret && i != values.end(); i ++)')
                code('{')
                code.indent()
                code('${{param.ptype.cxx_type}} elem;')
                param.ptype.cxx_ini_parse(code,
                    '*i', 'elem', 'ret =')
                code('if (ret)')
                code('    this->${{param.name}}.push_back(elem);')
                code.dedent()
                code('}')
                code.dedent()
        code('} else {')
        code('    ret = false;')
        code('}')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('bool ${member_prefix}setPortConnectionCount('
        'const std::string &name,')
    code('    unsigned int count)${end_of_decl}')

    if not is_header:
        code('{')
        code.indent()
        code('bool ret = true;')
        code()
        code('if (false)')
        code('    ;')
        for port in simobj._ports.values():
            code('else if (name == "${{port.name}}")')
            code('    this->port_${{port.name}}_connection_count = count;')
        code('else')
        code('    ret = false;')
        code()
        code('return ret;')
        code.dedent()
        code('}')

    code()
    code('SimObject *${member_prefix}simObjectCreate()${end_of_decl}')

    if not is_header:
        code('{')
        if hasattr(simobj, 'abstract') and simobj.abstract:
            code('    return NULL;')
        else:
            code('    return this->create();')
        code('}')

    if is_header:
        code()
        code('static CxxConfigDirectoryEntry'
            ' *${member_prefix}makeDirectoryEntry()')
        code('{ return new DirectoryEntry; }')

    if is_header:
        code.dedent()
        code('};')

    code('} // namespace gem5')

# The metaclass for SimObject.  This class controls how new classes
# that derive from SimObject are instantiated, and provides inherited
# class behavior (just like a class controls how instances of that
# class are instantiated, and provides inherited instance behavior).
class MetaSimObject(type):
    # Attributes that can be set only at initialization time
    init_keywords = {
        'abstract' : bool,
        'cxx_class' : str,
        'cxx_type' : str,
        'cxx_header' : str,
        'type' : str,
        'cxx_base' : (str, type(None)),
        'cxx_extra_bases' : list,
        'cxx_exports' : list,
        'cxx_param_exports' : list,
        'cxx_template_params' : list,
    }
    # Attributes that can be set any time
    keywords = { 'check' : FunctionType }

    # __new__ is called before __init__, and is where the statements
    # in the body of the class definition get loaded into the class's
    # __dict__.  We intercept this to filter out parameter & port assignments
    # and only allow "private" attributes to be passed to the base
    # __new__ (starting with underscore).
    def __new__(mcls, name, bases, dict):
        assert name not in allClasses, "SimObject %s already present" % name

        # Copy "private" attributes, functions, and classes to the
        # official dict.  Everything else goes in _init_dict to be
        # filtered in __init__.
        cls_dict = {}
        value_dict = {}
        cxx_exports = []
        for key,val in dict.items():
            try:
                cxx_exports.append(getattr(val, "__pybind"))
            except AttributeError:
                pass

            if public_value(key, val):
                cls_dict[key] = val
            else:
                # must be a param/port setting
                value_dict[key] = val
        if 'abstract' not in value_dict:
            value_dict['abstract'] = False
        if 'cxx_extra_bases' not in value_dict:
            value_dict['cxx_extra_bases'] = []
        if 'cxx_exports' not in value_dict:
            value_dict['cxx_exports'] = cxx_exports
        else:
            value_dict['cxx_exports'] += cxx_exports
        if 'cxx_param_exports' not in value_dict:
            value_dict['cxx_param_exports'] = []
        if 'cxx_template_params' not in value_dict:
            value_dict['cxx_template_params'] = []
        cls_dict['_value_dict'] = value_dict
        cls = super(MetaSimObject, mcls).__new__(mcls, name, bases, cls_dict)
        if 'type' in value_dict:
            allClasses[name] = cls
        return cls

    # subclass initialization
    def __init__(cls, name, bases, dict):
        # calls type.__init__()... I think that's a no-op, but leave
        # it here just in case it's not.
        super(MetaSimObject, cls).__init__(name, bases, dict)

        # initialize required attributes

        # class-only attributes
        cls._params = multidict() # param descriptions
        cls._ports = multidict()  # port descriptions

        # Parameter names that are deprecated. Dict[str, DeprecatedParam]
        # The key is the "old_name" so that when the old_name is used in
        # python config files, we will use the DeprecatedParam object to
        # translate to the new type.
        cls._deprecated_params = multidict()

        # class or instance attributes
        cls._values = multidict()   # param values
        cls._hr_values = multidict() # human readable param values
        cls._children = multidict() # SimObject children
        cls._port_refs = multidict() # port ref objects
        cls._instantiated = False # really instantiated, cloned, or subclassed
        cls._init_called = False # Used to check if __init__ overridden

        # We don't support multiple inheritance of sim objects.  If you want
        # to, you must fix multidict to deal with it properly. Non sim-objects
        # are ok, though
        bTotal = 0
        for c in bases:
            if isinstance(c, MetaSimObject):
                bTotal += 1
            if bTotal > 1:
                raise TypeError(
                      "SimObjects do not support multiple inheritance")

        base = bases[0]

        # Set up general inheritance via multidicts.  A subclass will
        # inherit all its settings from the base class.  The only time
        # the following is not true is when we define the SimObject
        # class itself (in which case the multidicts have no parent).
        if isinstance(base, MetaSimObject):
            cls._base = base
            cls._params.parent = base._params
            cls._ports.parent = base._ports
            cls._deprecated_params.parent = base._deprecated_params
            cls._values.parent = base._values
            cls._hr_values.parent = base._hr_values
            cls._children.parent = base._children
            cls._port_refs.parent = base._port_refs
            # mark base as having been subclassed
            base._instantiated = True
        else:
            cls._base = None

        # default keyword values
        if 'type' in cls._value_dict:
            if 'cxx_class' not in cls._value_dict:
                cls._value_dict['cxx_class'] = cls._value_dict['type']

            cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class']

            if 'cxx_header' not in cls._value_dict:
                global noCxxHeader
                noCxxHeader = True
                warn("No header file specified for SimObject: %s", name)

        # Now process the _value_dict items.  They could be defining
        # new (or overriding existing) parameters or ports, setting
        # class keywords (e.g., 'abstract'), or setting parameter
        # values or port bindings.  The first 3 can only be set when
        # the class is defined, so we handle them here.  The others
        # can be set later too, so just emulate that by calling
        # setattr().
        for key,val in cls._value_dict.items():
            # param descriptions
            if isinstance(val, ParamDesc):
                cls._new_param(key, val)

            # port objects
            elif isinstance(val, Port):
                cls._new_port(key, val)

            # Deprecated variable names
            elif isinstance(val, DeprecatedParam):
                new_name, new_val = cls._get_param_by_value(val.newParam)
                # Note: We don't know the (string) name of this variable until
                # here, so now we can finish setting up the dep_param.
                val.oldName = key
                val.newName = new_name
                cls._deprecated_params[key] = val

            # init-time-only keywords
            elif key in cls.init_keywords:
                cls._set_keyword(key, val, cls.init_keywords[key])

            # default: use normal path (ends up in __setattr__)
            else:
                setattr(cls, key, val)

    def _set_keyword(cls, keyword, val, kwtype):
        if not isinstance(val, kwtype):
            raise TypeError('keyword %s has bad type %s (expecting %s)' % \
                  (keyword, type(val), kwtype))
        if isinstance(val, FunctionType):
            val = classmethod(val)
        type.__setattr__(cls, keyword, val)

    def _new_param(cls, name, pdesc):
        # each param desc should be uniquely assigned to one variable
        assert(not hasattr(pdesc, 'name'))
        pdesc.name = name
        cls._params[name] = pdesc
        if hasattr(pdesc, 'default'):
            cls._set_param(name, pdesc.default, pdesc)

    def _set_param(cls, name, value, param):
        assert(param.name == name)
        try:
            hr_value = value
            value = param.convert(value)
        except Exception as e:
            msg = "%s\nError setting param %s.%s to %s\n" % \
                  (e, cls.__name__, name, value)
            e.args = (msg, )
            raise
        cls._values[name] = value
        # if param value is a SimObject, make it a child too, so that
        # it gets cloned properly when the class is instantiated
        if isSimObjectOrVector(value) and not value.has_parent():
            cls._add_cls_child(name, value)
        # update human-readable values of the param if it has a literal
        # value and is not an object or proxy.
        if not (isSimObjectOrVector(value) or\
                isinstance(value, m5.proxy.BaseProxy)):
            cls._hr_values[name] = hr_value

    def _add_cls_child(cls, name, child):
        # It's a little funky to have a class as a parent, but these
        # objects should never be instantiated (only cloned, which
        # clears the parent pointer), and this makes it clear that the
        # object is not an orphan and can provide better error
        # messages.
        child.set_parent(cls, name)
        if not isNullPointer(child):
            cls._children[name] = child

    def _new_port(cls, name, port):
        # each port should be uniquely assigned to one variable
        assert(not hasattr(port, 'name'))
        port.name = name
        cls._ports[name] = port

    # same as _get_port_ref, effectively, but for classes
    def _cls_get_port_ref(cls, attr):
        # Return reference that can be assigned to another port
        # via __setattr__.  There is only ever one reference
        # object per port, but we create them lazily here.
        ref = cls._port_refs.get(attr)
        if not ref:
            ref = cls._ports[attr].makeRef(cls)
            cls._port_refs[attr] = ref
        return ref

    def _get_param_by_value(cls, value):
        """Given an object, value, return the name and the value from the
        internal list of parameter values. If this value can't be found, raise
        a runtime error. This will search both the current object and its
        parents.
        """
        for k,v in cls._value_dict.items():
            if v == value:
                return k,v
        raise RuntimeError("Cannot find parameter {} in parameter list"
                           .format(value))

    # Set attribute (called on foo.attr = value when foo is an
    # instance of class cls).
    def __setattr__(cls, attr, value):
        # normal processing for private attributes
        if public_value(attr, value):
            type.__setattr__(cls, attr, value)
            return

        if attr in cls.keywords:
            cls._set_keyword(attr, value, cls.keywords[attr])
            return

        if attr in cls._ports:
            cls._cls_get_port_ref(attr).connect(value)
            return

        if isSimObjectOrSequence(value) and cls._instantiated:
            raise RuntimeError(
                  "cannot set SimObject parameter '%s' after\n" \
                  "    class %s has been instantiated or subclassed" \
                  % (attr, cls.__name__))

        # check for param
        param = cls._params.get(attr)
        if param:
            cls._set_param(attr, value, param)
            return

        if isSimObjectOrSequence(value):
            # If RHS is a SimObject, it's an implicit child assignment.
            cls._add_cls_child(attr, coerceSimObjectOrVector(value))
            return

        # no valid assignment... raise exception
        raise AttributeError(
              "Class %s has no parameter \'%s\'" % (cls.__name__, attr))

    def __getattr__(cls, attr):
        if attr == 'cxx_class_path':
            return cls.cxx_class.split('::')

        if attr == 'cxx_class_name':
            return cls.cxx_class_path[-1]

        if attr == 'cxx_namespaces':
            return cls.cxx_class_path[:-1]

        if attr == 'pybind_class':
            return  '_COLONS_'.join(cls.cxx_class_path)

        if attr in cls._values:
            return cls._values[attr]

        if attr in cls._children:
            return cls._children[attr]

        try:
            return getattr(cls.getCCClass(), attr)
        except AttributeError:
            raise AttributeError(
                "object '%s' has no attribute '%s'" % (cls.__name__, attr))

    def __str__(cls):
        return cls.__name__

    def getCCClass(cls):
        return getattr(m5.internal.params, cls.pybind_class)

    # See ParamValue.cxx_predecls for description.
    def cxx_predecls(cls, code):
        code('#include "params/$cls.hh"')

    def pybind_predecls(cls, code):
        code('#include "${{cls.cxx_header}}"')

    def params_create_decl(cls, code, python_enabled):
        py_class_name = cls.pybind_class

        # The 'local' attribute restricts us to the params declared in
        # the object itself, not including inherited params (which
        # will also be inherited from the base class's param struct
        # here). Sort the params based on their key
        params = list(map(lambda k_v: k_v[1],
                          sorted(cls._params.local.items())))
        ports = cls._ports.local

        # only include pybind if python is enabled in the build
        if python_enabled:

            code('''#include "pybind11/pybind11.h"
#include "pybind11/stl.h"

#include <type_traits>

#include "base/compiler.hh"
#include "params/$cls.hh"
#include "sim/init.hh"
#include "sim/sim_object.hh"

#include "${{cls.cxx_header}}"

''')
        else:
            code('''
#include <type_traits>

#include "base/compiler.hh"
#include "params/$cls.hh"

#include "${{cls.cxx_header}}"

''')
        # only include the python params code if python is enabled.
        if python_enabled:
            for param in params:
                param.pybind_predecls(code)

            code('''namespace py = pybind11;

namespace gem5
{

static void
module_init(py::module_ &m_internal)
{
    py::module_ m = m_internal.def_submodule("param_${cls}");
''')
            code.indent()
            if cls._base:
                code('py::class_<${cls}Params, ${{cls._base.type}}Params, ' \
                    'std::unique_ptr<${{cls}}Params, py::nodelete>>(' \
                    'm, "${cls}Params")')
            else:
                code('py::class_<${cls}Params, ' \
                    'std::unique_ptr<${cls}Params, py::nodelete>>(' \
                    'm, "${cls}Params")')

            code.indent()
            if not hasattr(cls, 'abstract') or not cls.abstract:
                code('.def(py::init<>())')
                code('.def("create", &${cls}Params::create)')

            param_exports = cls.cxx_param_exports + [
                PyBindProperty(k)
                for k, v in sorted(cls._params.local.items())
            ] + [
                PyBindProperty("port_%s_connection_count" % port.name)
                for port in ports.values()
            ]
            for exp in param_exports:
                exp.export(code, "%sParams" % cls)

            code(';')
            code()
            code.dedent()

            bases = []
            if 'cxx_base' in cls._value_dict:
                # If the c++ base class implied by python inheritance was
                # overridden, use that value.
                if cls.cxx_base:
                    bases.append(cls.cxx_base)
            elif cls._base:
                # If not and if there was a SimObject base, use its c++ class
                # as this class' base.
                bases.append(cls._base.cxx_class)
            # Add in any extra bases that were requested.
            bases.extend(cls.cxx_extra_bases)

            if bases:
                base_str = ", ".join(bases)
                code('py::class_<${{cls.cxx_class}}, ${base_str}, ' \
                    'std::unique_ptr<${{cls.cxx_class}}, py::nodelete>>(' \
                    'm, "${py_class_name}")')
            else:
                code('py::class_<${{cls.cxx_class}}, ' \
                    'std::unique_ptr<${{cls.cxx_class}}, py::nodelete>>(' \
                    'm, "${py_class_name}")')
            code.indent()
            for exp in cls.cxx_exports:
                exp.export(code, cls.cxx_class)
            code(';')
            code.dedent()
            code()
            code.dedent()
            code('}')
            code()
            code('static EmbeddedPyBind '
                 'embed_obj("${0}", module_init, "${1}");',
                cls, cls._base.type if cls._base else "")
            code()
            code('} // namespace gem5')

        # include the create() methods whether or not python is enabled.
        if not hasattr(cls, 'abstract') or not cls.abstract:
            if 'type' in cls.__dict__:
                code()
                code('namespace gem5')
                code('{')
                code()
                code('namespace')
                code('{')
                code()
                # If we can't define a default create() method for this params
                # struct because the SimObject doesn't have the right
                # constructor, use template magic to make it so we're actually
                # defining a create method for this class instead.
                code('class Dummy${cls}ParamsClass')
                code('{')
                code('  public:')
                code('    ${{cls.cxx_class}} *create() const;')
                code('};')
                code()
                code('template <class CxxClass, class Enable=void>')
                code('class Dummy${cls}Shunt;')
                code()
                # This version directs to the real Params struct and the
                # default behavior of create if there's an appropriate
                # constructor.
                code('template <class CxxClass>')
                code('class Dummy${cls}Shunt<CxxClass, std::enable_if_t<')
                code('    std::is_constructible_v<CxxClass,')
                code('        const ${cls}Params &>>>')
                code('{')
                code('  public:')
                code('    using Params = ${cls}Params;')
                code('    static ${{cls.cxx_class}} *')
                code('    create(const Params &p)')
                code('    {')
                code('        return new CxxClass(p);')
                code('    }')
                code('};')
                code()
                # This version diverts to the DummyParamsClass and a dummy
                # implementation of create if the appropriate constructor does
                # not exist.
                code('template <class CxxClass>')
                code('class Dummy${cls}Shunt<CxxClass, std::enable_if_t<')
                code('    !std::is_constructible_v<CxxClass,')
                code('        const ${cls}Params &>>>')
                code('{')
                code('  public:')
                code('    using Params = Dummy${cls}ParamsClass;')
                code('    static ${{cls.cxx_class}} *')
                code('    create(const Params &p)')
                code('    {')
                code('        return nullptr;')
                code('    }')
                code('};')
                code()
                code('} // anonymous namespace')
                code()
                # An implementation of either the real Params struct's create
                # method, or the Dummy one. Either an implementation is
                # mandantory since this was shunted off to the dummy class, or
                # one is optional which will override this weak version.
                code('[[maybe_unused]] ${{cls.cxx_class}} *')
                code('Dummy${cls}Shunt<${{cls.cxx_class}}>::Params::create() '
                     'const')
                code('{')
                code('    return Dummy${cls}Shunt<${{cls.cxx_class}}>::')
                code('        create(*this);')
                code('}')
                code()
                code('} // namespace gem5')

    _warned_about_nested_templates = False

    # Generate the C++ declaration (.hh file) for this SimObject's
    # param struct.  Called from src/SConscript.
    def cxx_param_decl(cls, code):
        # The 'local' attribute restricts us to the params declared in
        # the object itself, not including inherited params (which
        # will also be inherited from the base class's param struct
        # here). Sort the params based on their key
        params = list(map(lambda k_v: k_v[1], sorted(cls._params.local.items())))
        ports = cls._ports.local
        try:
            ptypes = [p.ptype for p in params]
        except:
            print(cls, p, p.ptype_str)
            print(params)
            raise

        class CxxClass(object):
            def __init__(self, sig, template_params=[]):
                # Split the signature into its constituent parts. This could
                # potentially be done with regular expressions, but
                # it's simple enough to pick appart a class signature
                # manually.
                parts = sig.split('<', 1)
                base = parts[0]
                t_args = []
                if len(parts) > 1:
                    # The signature had template arguments.
                    text = parts[1].rstrip(' \t\n>')
                    arg = ''
                    # Keep track of nesting to avoid splitting on ","s embedded
                    # in the arguments themselves.
                    depth = 0
                    for c in text:
                        if c == '<':
                            depth = depth + 1
                            if depth > 0 and not \
                                    self._warned_about_nested_templates:
                                self._warned_about_nested_templates = True
                                print('Nested template argument in cxx_class.'
                                      ' This feature is largely untested and '
                                      ' may not work.')
                        elif c == '>':
                            depth = depth - 1
                        elif c == ',' and depth == 0:
                            t_args.append(arg.strip())
                            arg = ''
                        else:
                            arg = arg + c
                    if arg:
                        t_args.append(arg.strip())
                # Split the non-template part on :: boundaries.
                class_path = base.split('::')

                # The namespaces are everything except the last part of the
                # class path.
                self.namespaces = class_path[:-1]
                # And the class name is the last part.
                self.name = class_path[-1]

                self.template_params = template_params
                self.template_arguments = []
                # Iterate through the template arguments and their values. This
                # will likely break if parameter packs are used.
                for arg, param in zip(t_args, template_params):
                    type_keys = ('class', 'typename')
                    # If a parameter is a type, parse it recursively. Otherwise
                    # assume it's a constant, and store it verbatim.
                    if any(param.strip().startswith(kw) for kw in type_keys):
                        self.template_arguments.append(CxxClass(arg))
                    else:
                        self.template_arguments.append(arg)

            def declare(self, code):
                # First declare any template argument types.
                for arg in self.template_arguments:
                    if isinstance(arg, CxxClass):
                        arg.declare(code)
                # Re-open the target namespace.
                for ns in self.namespaces:
                    code('namespace $ns {')
                # If this is a class template...
                if self.template_params:
                    code('template <${{", ".join(self.template_params)}}>')
                # The actual class declaration.
                code('class ${{self.name}};')
                # Close the target namespaces.
                for ns in reversed(self.namespaces):
                    code('} // namespace $ns')

        code('''\
#ifndef __PARAMS__${cls}__
#define __PARAMS__${cls}__

''')


        # The base SimObject has a couple of params that get
        # automatically set from Python without being declared through
        # the normal Param mechanism; we slip them in here (needed
        # predecls now, actual declarations below)
        if cls == SimObject:
            code('''#include <string>''')

        cxx_class = CxxClass(cls._value_dict['cxx_class'],
                             cls._value_dict['cxx_template_params'])

        # A forward class declaration is sufficient since we are just
        # declaring a pointer.
        cxx_class.declare(code)

        for param in params:
            param.cxx_predecls(code)
        for port in ports.values():
            port.cxx_predecls(code)
        code()

        if cls._base:
            code('#include "params/${{cls._base.type}}.hh"')
            code()

        for ptype in ptypes:
            if issubclass(ptype, Enum):
                code('#include "enums/${{ptype.__name__}}.hh"')
                code()

        code('namespace gem5')
        code('{')
        code('')

        # now generate the actual param struct
        code("struct ${cls}Params")
        if cls._base:
            code("    : public ${{cls._base.type}}Params")
        code("{")
        if not hasattr(cls, 'abstract') or not cls.abstract:
            if 'type' in cls.__dict__:
                code("    ${{cls.cxx_type}} create() const;")

        code.indent()
        if cls == SimObject:
            code('''
    SimObjectParams() {}
    virtual ~SimObjectParams() {}

    std::string name;
            ''')

        for param in params:
            param.cxx_decl(code)
        for port in ports.values():
            port.cxx_decl(code)

        code.dedent()
        code('};')
        code()
        code('} // namespace gem5')

        code()
        code('#endif // __PARAMS__${cls}__')
        return code

    # Generate the C++ declaration/definition files for this SimObject's
    # param struct to allow C++ initialisation
    def cxx_config_param_file(cls, code, is_header):
        createCxxConfigDirectoryEntryFile(code, cls.__name__, cls, is_header)
        return code

# This *temporary* definition is required to support calls from the
# SimObject class definition to the MetaSimObject methods (in
# particular _set_param, which gets called for parameters with default
# values defined on the SimObject class itself).  It will get
# overridden by the permanent definition (which requires that
# SimObject be defined) lower in this file.
def isSimObjectOrVector(value):
    return False

def cxxMethod(*args, **kwargs):
    """Decorator to export C++ functions to Python"""

    def decorate(func):
        name = func.__name__
        override = kwargs.get("override", False)
        cxx_name = kwargs.get("cxx_name", name)
        return_value_policy = kwargs.get("return_value_policy", None)
        static = kwargs.get("static", False)

        args, varargs, keywords, defaults = inspect.getargspec(func)
        if varargs or keywords:
            raise ValueError("Wrapped methods must not contain variable " \
                             "arguments")

        # Create tuples of (argument, default)
        if defaults:
            args = args[:-len(defaults)] + \
                   list(zip(args[-len(defaults):], defaults))
        # Don't include self in the argument list to PyBind
        args = args[1:]


        @wraps(func)
        def cxx_call(self, *args, **kwargs):
            ccobj = self.getCCClass() if static else self.getCCObject()
            return getattr(ccobj, name)(*args, **kwargs)

        @wraps(func)
        def py_call(self, *args, **kwargs):
            return func(self, *args, **kwargs)

        f = py_call if override else cxx_call
        f.__pybind = PyBindMethod(name, cxx_name=cxx_name, args=args,
                                  return_value_policy=return_value_policy,
                                  static=static)

        return f

    if len(args) == 0:
        return decorate
    elif len(args) == 1 and len(kwargs) == 0:
        return decorate(*args)
    else:
        raise TypeError("One argument and no kwargs, or only kwargs expected")

# This class holds information about each simobject parameter
# that should be displayed on the command line for use in the
# configuration system.
class ParamInfo(object):
  def __init__(self, type, desc, type_str, example, default_val, access_str):
    self.type = type
    self.desc = desc
    self.type_str = type_str
    self.example_str = example
    self.default_val = default_val
    # The string representation used to access this param through python.
    # The method to access this parameter presented on the command line may
    # be different, so this needs to be stored for later use.
    self.access_str = access_str
    self.created = True

  # Make it so we can only set attributes at initialization time
  # and effectively make this a const object.
  def __setattr__(self, name, value):
    if not "created" in self.__dict__:
      self.__dict__[name] = value

class SimObjectCliWrapperException(Exception):
    def __init__(self, message):
        super(Exception, self).__init__(message)

class SimObjectCliWrapper(object):
    """
    Wrapper class to restrict operations that may be done
    from the command line on SimObjects.

    Only parameters may be set, and only children may be accessed.

    Slicing allows for multiple simultaneous assignment of items in
    one statement.
    """

    def __init__(self, sim_objects):
        self.__dict__['_sim_objects'] = list(sim_objects)

    def __getattr__(self, key):
        return SimObjectCliWrapper(sim_object._children[key]
                for sim_object in self._sim_objects)

    def __setattr__(self, key, val):
        for sim_object in self._sim_objects:
            if key in sim_object._params:
                if sim_object._params[key].isCmdLineSettable():
                    setattr(sim_object, key, val)
                else:
                    raise SimObjectCliWrapperException(
                            'tried to set or unsettable' \
                            'object parameter: ' + key)
            else:
                raise SimObjectCliWrapperException(
                            'tried to set or access non-existent' \
                            'object parameter: ' + key)

    def __getitem__(self, idx):
        """
        Extends the list() semantics to also allow tuples,
        for example object[1, 3] selects items 1 and 3.
        """
        out = []
        if isinstance(idx, tuple):
            for t in idx:
                out.extend(self[t]._sim_objects)
        else:
            if isinstance(idx, int):
                _range = range(idx, idx + 1)
            elif not isinstance(idx, slice):
                raise SimObjectCliWrapperException( \
                        'invalid index type: ' + repr(idx))
            for sim_object in self._sim_objects:
                if isinstance(idx, slice):
                    _range = range(*idx.indices(len(sim_object)))
                out.extend(sim_object[i] for i in _range)
        return SimObjectCliWrapper(out)

    def __iter__(self):
        return iter(self._sim_objects)

# The SimObject class is the root of the special hierarchy.  Most of
# the code in this class deals with the configuration hierarchy itself
# (parent/child node relationships).
class SimObject(object, metaclass=MetaSimObject):
    # Specify metaclass.  Any class inheriting from SimObject will
    # get this metaclass.
    type = 'SimObject'
    abstract = True

    cxx_header = "sim/sim_object.hh"
    cxx_class = 'gem5::SimObject'
    cxx_extra_bases = [ "Drainable", "Serializable", "statistics::Group" ]
    eventq_index = Param.UInt32(Parent.eventq_index, "Event Queue Index")

    cxx_exports = [
        PyBindMethod("init"),
        PyBindMethod("initState"),
        PyBindMethod("memInvalidate"),
        PyBindMethod("memWriteback"),
        PyBindMethod("regProbePoints"),
        PyBindMethod("regProbeListeners"),
        PyBindMethod("startup"),
    ]

    cxx_param_exports = [
        PyBindProperty("name"),
    ]

    @cxxMethod
    def loadState(self, cp):
        """Load SimObject state from a checkpoint"""
        pass

    # Returns a dict of all the option strings that can be
    # generated as command line options for this simobject instance
    # by tracing all reachable params in the top level instance and
    # any children it contains.
    def enumerateParams(self, flags_dict = {},
                        cmd_line_str = "", access_str = ""):
        if hasattr(self, "_paramEnumed"):
            print("Cycle detected enumerating params")
        else:
            self._paramEnumed = True
            # Scan the children first to pick up all the objects in this SimObj
            for keys in self._children:
                child = self._children[keys]
                next_cmdline_str = cmd_line_str + keys
                next_access_str = access_str + keys
                if not isSimObjectVector(child):
                    next_cmdline_str = next_cmdline_str + "."
                    next_access_str = next_access_str + "."
                flags_dict = child.enumerateParams(flags_dict,
                                                   next_cmdline_str,
                                                   next_access_str)

            # Go through the simple params in the simobject in this level
            # of the simobject hierarchy and save information about the
            # parameter to be used for generating and processing command line
            # options to the simulator to set these parameters.
            for keys,values in self._params.items():
                if values.isCmdLineSettable():
                    type_str = ''
                    ex_str = values.example_str()
                    ptype = None
                    if isinstance(values, VectorParamDesc):
                        type_str = 'Vector_%s' % values.ptype_str
                        ptype = values
                    else:
                        type_str = '%s' % values.ptype_str
                        ptype = values.ptype

                    if keys in self._hr_values\
                       and keys in self._values\
                       and not isinstance(self._values[keys],
                                          m5.proxy.BaseProxy):
                        cmd_str = cmd_line_str + keys
                        acc_str = access_str + keys
                        flags_dict[cmd_str] = ParamInfo(ptype,
                                    self._params[keys].desc, type_str, ex_str,
                                    values.pretty_print(self._hr_values[keys]),
                                    acc_str)
                    elif not keys in self._hr_values\
                         and not keys in self._values:
                        # Empty param
                        cmd_str = cmd_line_str + keys
                        acc_str = access_str + keys
                        flags_dict[cmd_str] = ParamInfo(ptype,
                                    self._params[keys].desc,
                                    type_str, ex_str, '', acc_str)

        return flags_dict

    # Initialize new instance.  For objects with SimObject-valued
    # children, we need to recursively clone the classes represented
    # by those param values as well in a consistent "deep copy"-style
    # fashion.  That is, we want to make sure that each instance is
    # cloned only once, and that if there are multiple references to
    # the same original object, we end up with the corresponding
    # cloned references all pointing to the same cloned instance.
    def __init__(self, **kwargs):
        ancestor = kwargs.get('_ancestor')
        memo_dict = kwargs.get('_memo')
        if memo_dict is None:
            # prepare to memoize any recursively instantiated objects
            memo_dict = {}
        elif ancestor:
            # memoize me now to avoid problems with recursive calls
            memo_dict[ancestor] = self

        if not ancestor:
            ancestor = self.__class__
        ancestor._instantiated = True

        # initialize required attributes
        self._parent = None
        self._name = None
        self._ccObject = None  # pointer to C++ object
        self._ccParams = None
        self._instantiated = False # really "cloned"
        self._init_called = True # Checked so subclasses don't forget __init__

        # Clone children specified at class level.  No need for a
        # multidict here since we will be cloning everything.
        # Do children before parameter values so that children that
        # are also param values get cloned properly.
        self._children = {}
        for key,val in ancestor._children.items():
            self.add_child(key, val(_memo=memo_dict))

        # Inherit parameter values from class using multidict so
        # individual value settings can be overridden but we still
        # inherit late changes to non-overridden class values.
        self._values = multidict(ancestor._values)
        self._hr_values = multidict(ancestor._hr_values)
        # clone SimObject-valued parameters
        for key,val in ancestor._values.items():
            val = tryAsSimObjectOrVector(val)
            if val is not None:
                self._values[key] = val(_memo=memo_dict)

        # clone port references.  no need to use a multidict here
        # since we will be creating new references for all ports.
        self._port_refs = {}
        for key,val in ancestor._port_refs.items():
            self._port_refs[key] = val.clone(self, memo_dict)
        # apply attribute assignments from keyword args, if any
        for key,val in kwargs.items():
            setattr(self, key, val)

    def _check_init(self):
        """Utility function to check to make sure that all subclasses call
        __init__
        """
        if not self._init_called:
            raise RuntimeError(f"{str(self.__class__)} is missing a call "
                "to super().__init__()")

    # "Clone" the current instance by creating another instance of
    # this instance's class, but that inherits its parameter values
    # and port mappings from the current instance.  If we're in a
    # "deep copy" recursive clone, check the _memo dict to see if
    # we've already cloned this instance.
    def __call__(self, **kwargs):
        memo_dict = kwargs.get('_memo')
        if memo_dict is None:
            # no memo_dict: must be top-level clone operation.
            # this is only allowed at the root of a hierarchy
            if self._parent:
                raise RuntimeError("attempt to clone object %s " \
                      "not at the root of a tree (parent = %s)" \
                      % (self, self._parent))
            # create a new dict and use that.
            memo_dict = {}
            kwargs['_memo'] = memo_dict
        elif self in memo_dict:
            # clone already done & memoized
            return memo_dict[self]
        return self.__class__(_ancestor = self, **kwargs)

    def _get_port_ref(self, attr):
        # Return reference that can be assigned to another port
        # via __setattr__.  There is only ever one reference
        # object per port, but we create them lazily here.
        ref = self._port_refs.get(attr)
        if ref == None:
            ref = self._ports[attr].makeRef(self)
            self._port_refs[attr] = ref
        return ref

    def __getattr__(self, attr):
        # Check for infinite recursion. If this SimObject hasn't been
        # initialized with SimObject.__init__ this function will experience an
        # infinite recursion checking for attributes that don't exist.
        self._check_init()

        if attr in self._deprecated_params:
            dep_param = self._deprecated_params[attr]
            dep_param.printWarning(self._name, self.__class__.__name__)
            return getattr(self, self._deprecated_params[attr].newName)

        if attr in self._ports:
            return self._get_port_ref(attr)

        if attr in self._values:
            return self._values[attr]

        if attr in self._children:
            return self._children[attr]

        # If the attribute exists on the C++ object, transparently
        # forward the reference there.  This is typically used for
        # methods exported to Python (e.g., init(), and startup())
        if self._ccObject and hasattr(self._ccObject, attr):
            return getattr(self._ccObject, attr)

        err_string = "object '%s' has no attribute '%s'" \
              % (self.__class__.__name__, attr)

        if not self._ccObject:
            err_string += "\n  (C++ object is not yet constructed," \
                          " so wrapped C++ methods are unavailable.)"

        raise AttributeError(err_string)

    # Set attribute (called on foo.attr = value when foo is an
    # instance of class cls).
    def __setattr__(self, attr, value):
        # normal processing for private attributes
        if attr.startswith('_'):
            object.__setattr__(self, attr, value)
            return

        if attr in self._deprecated_params:
            dep_param = self._deprecated_params[attr]
            dep_param.printWarning(self._name, self.__class__.__name__)
            return setattr(self, self._deprecated_params[attr].newName, value)

        if attr in self._ports:
            # set up port connection
            self._get_port_ref(attr).connect(value)
            return

        param = self._params.get(attr)
        if param:
            try:
                hr_value = value
                value = param.convert(value)
            except Exception as e:
                msg = "%s\nError setting param %s.%s to %s\n" % \
                      (e, self.__class__.__name__, attr, value)
                e.args = (msg, )
                raise
            self._values[attr] = value

            # If we assign NULL to an attr that is a SimObject,
            # remove the corresponding children
            if attr in self._children and isNullPointer(value):
                self.clear_child(attr)

            # implicitly parent unparented objects assigned as params
            if isSimObjectOrVector(value) and not value.has_parent():
                self.add_child(attr, value)
            # set the human-readable value dict if this is a param
            # with a literal value and is not being set as an object
            # or proxy.
            if not (isSimObjectOrVector(value) or\
                    isinstance(value, m5.proxy.BaseProxy)):
                self._hr_values[attr] = hr_value

            return

        # if RHS is a SimObject, it's an implicit child assignment
        if isSimObjectOrSequence(value):
            self.add_child(attr, value)
            return

        # no valid assignment... raise exception
        raise AttributeError("Class %s has no parameter %s" \
              % (self.__class__.__name__, attr))


    # this hack allows tacking a '[0]' onto parameters that may or may
    # not be vectors, and always getting the first element (e.g. cpus)
    def __getitem__(self, key):
        if key == 0:
            return self
        raise IndexError("Non-zero index '%s' to SimObject" % key)

    # this hack allows us to iterate over a SimObject that may
    # not be a vector, so we can call a loop over it and get just one
    # element.
    def __len__(self):
        return 1

    # Also implemented by SimObjectVector
    def clear_parent(self, old_parent):
        assert self._parent is old_parent
        self._parent = None

    # Also implemented by SimObjectVector
    def set_parent(self, parent, name):
        self._parent = parent
        self._name = name

    # Return parent object of this SimObject, not implemented by
    # SimObjectVector because the elements in a SimObjectVector may not share
    # the same parent
    def get_parent(self):
        return self._parent

    # Also implemented by SimObjectVector
    def get_name(self):
        return self._name

    # Also implemented by SimObjectVector
    def has_parent(self):
        return self._parent is not None

    # clear out child with given name. This code is not likely to be exercised.
    # See comment in add_child.
    def clear_child(self, name):
        child = self._children[name]
        child.clear_parent(self)
        del self._children[name]

    # Add a new child to this object.
    def add_child(self, name, child):
        child = coerceSimObjectOrVector(child)
        if child.has_parent():
            warn(f"{self}.{name} already has parent not resetting parent.\n"
                 f"\tNote: {name} is not a parameter of {type(self).__name__}")
            warn(f"(Previously declared as {child._parent}.{name}")
            return
        if name in self._children:
            # This code path had an undiscovered bug that would make it fail
            # at runtime. It had been here for a long time and was only
            # exposed by a buggy script. Changes here will probably not be
            # exercised without specialized testing.
            self.clear_child(name)
        if not isNullPointer(child):
            child.set_parent(self, name)
            self._children[name] = child

    # Take SimObject-valued parameters that haven't been explicitly
    # assigned as children and make them children of the object that
    # they were assigned to as a parameter value.  This guarantees
    # that when we instantiate all the parameter objects we're still
    # inside the configuration hierarchy.
    def adoptOrphanParams(self):
        for key,val in self._values.items():
            if not isSimObjectVector(val) and isSimObjectSequence(val):
                # need to convert raw SimObject sequences to
                # SimObjectVector class so we can call has_parent()
                val = SimObjectVector(val)
                self._values[key] = val
            if isSimObjectOrVector(val) and not val.has_parent():
                warn("%s adopting orphan SimObject param '%s'", self, key)
                self.add_child(key, val)

    def path(self):
        if not self._parent:
            return '<orphan %s>' % self.__class__
        elif isinstance(self._parent, MetaSimObject):
            return str(self.__class__)

        ppath = self._parent.path()
        if ppath == 'root':
            return self._name
        return ppath + "." + self._name

    def path_list(self):
        if self._parent:
            return self._parent.path_list() + [ self._name, ]
        else:
            # Don't include the root node
            return []

    def __str__(self):
        return self.path()

    def config_value(self):
        return self.path()

    def ini_str(self):
        return self.path()

    def find_any(self, ptype):
        if isinstance(self, ptype):
            return self, True

        found_obj = None
        for child in self._children.values():
            visited = False
            if hasattr(child, '_visited'):
              visited = getattr(child, '_visited')

            if isinstance(child, ptype) and not visited:
                if found_obj != None and child != found_obj:
                    raise AttributeError(
                          'parent.any matched more than one: %s %s' % \
                          (found_obj.path, child.path))
                found_obj = child
        # search param space
        for pname,pdesc in self._params.items():
            if issubclass(pdesc.ptype, ptype):
                match_obj = self._values[pname]
                if found_obj != None and found_obj != match_obj:
                    raise AttributeError(
                          'parent.any matched more than one: %s and %s' % \
                          (found_obj.path, match_obj.path))
                found_obj = match_obj
        return found_obj, found_obj != None

    def find_all(self, ptype):
        all = {}
        # search children
        for child in self._children.values():
            # a child could be a list, so ensure we visit each item
            if isinstance(child, list):
                children = child
            else:
                children = [child]

            for child in children:
                if isinstance(child, ptype) and not isproxy(child) and \
                        not isNullPointer(child):
                    all[child] = True
                if isSimObject(child):
                    # also add results from the child itself
                    child_all, done = child.find_all(ptype)
                    all.update(dict(zip(child_all, [done] * len(child_all))))
        # search param space
        for pname,pdesc in self._params.items():
            if issubclass(pdesc.ptype, ptype):
                match_obj = self._values[pname]
                if not isproxy(match_obj) and not isNullPointer(match_obj):
                    all[match_obj] = True
        # Also make sure to sort the keys based on the objects' path to
        # ensure that the order is the same on all hosts
        return sorted(all.keys(), key = lambda o: o.path()), True

    def unproxy(self, base):
        return self

    def unproxyParams(self):
        for param in self._params.keys():
            value = self._values.get(param)
            if value != None and isproxy(value):
                try:
                    value = value.unproxy(self)
                except:
                    print("Error in unproxying param '%s' of %s" %
                          (param, self.path()))
                    raise
                setattr(self, param, value)

        # Unproxy ports in sorted order so that 'append' operations on
        # vector ports are done in a deterministic fashion.
        port_names = list(self._ports.keys())
        port_names.sort()
        for port_name in port_names:
            port = self._port_refs.get(port_name)
            if port != None:
                port.unproxy(self)

    def print_ini(self, ini_file):
        print('[' + self.path() + ']', file=ini_file)    # .ini section header

        instanceDict[self.path()] = self

        if hasattr(self, 'type'):
            print('type=%s' % self.type, file=ini_file)

        if len(self._children.keys()):
            print('children=%s' %
                  ' '.join(self._children[n].get_name()
                           for n in sorted(self._children.keys())),
                  file=ini_file)

        for param in sorted(self._params.keys()):
            value = self._values.get(param)
            if value != None:
                print('%s=%s' % (param, self._values[param].ini_str()),
                      file=ini_file)

        for port_name in sorted(self._ports.keys()):
            port = self._port_refs.get(port_name, None)
            if port != None:
                print('%s=%s' % (port_name, port.ini_str()), file=ini_file)

        print(file=ini_file)        # blank line between objects

    # generate a tree of dictionaries expressing all the parameters in the
    # instantiated system for use by scripts that want to do power, thermal
    # visualization, and other similar tasks
    def get_config_as_dict(self):
        d = attrdict()
        if hasattr(self, 'type'):
            d.type = self.type
        if hasattr(self, 'cxx_class'):
            d.cxx_class = self.cxx_class
        # Add the name and path of this object to be able to link to
        # the stats
        d.name = self.get_name()
        d.path = self.path()

        for param in sorted(self._params.keys()):
            value = self._values.get(param)
            if value != None:
                d[param] = value.config_value()

        for n in sorted(self._children.keys()):
            child = self._children[n]
            # Use the name of the attribute (and not get_name()) as
            # the key in the JSON dictionary to capture the hierarchy
            # in the Python code that assembled this system
            d[n] = child.get_config_as_dict()

        for port_name in sorted(self._ports.keys()):
            port = self._port_refs.get(port_name, None)
            if port != None:
                # Represent each port with a dictionary containing the
                # prominent attributes
                d[port_name] = port.get_config_as_dict()

        return d

    def getCCParams(self):
        if self._ccParams:
            return self._ccParams

        # Ensure that m5.internal.params is available.
        import m5.internal.params

        cc_params_struct = getattr(m5.internal.params, '%sParams' % self.type)
        cc_params = cc_params_struct()
        cc_params.name = str(self)

        param_names = list(self._params.keys())
        param_names.sort()
        for param in param_names:
            value = self._values.get(param)
            if value is None:
                fatal("%s.%s without default or user set value",
                      self.path(), param)

            value = value.getValue()
            if isinstance(self._params[param], VectorParamDesc):
                assert isinstance(value, list)
                vec = getattr(cc_params, param)
                assert not len(vec)
                # Some types are exposed as opaque types. They support
                # the append operation unlike the automatically
                # wrapped types.
                if isinstance(vec, list):
                    setattr(cc_params, param, list(value))
                else:
                    for v in value:
                        getattr(cc_params, param).append(v)
            else:
                setattr(cc_params, param, value)

        port_names = list(self._ports.keys())
        port_names.sort()
        for port_name in port_names:
            port = self._port_refs.get(port_name, None)
            if port != None:
                port_count = len(port)
            else:
                port_count = 0
            setattr(cc_params, 'port_' + port_name + '_connection_count',
                    port_count)
        self._ccParams = cc_params
        return self._ccParams

    # Get C++ object corresponding to this object, calling C++ if
    # necessary to construct it.  Does *not* recursively create
    # children.
    def getCCObject(self):
        if not self._ccObject:
            # Make sure this object is in the configuration hierarchy
            if not self._parent and not isRoot(self):
                raise RuntimeError("Attempt to instantiate orphan node")
            # Cycles in the configuration hierarchy are not supported. This
            # will catch the resulting recursion and stop.
            self._ccObject = -1
            if not self.abstract:
                params = self.getCCParams()
                self._ccObject = params.create()
        elif self._ccObject == -1:
            raise RuntimeError("%s: Cycle found in configuration hierarchy." \
                  % self.path())
        return self._ccObject

    def descendants(self):
        yield self
        # The order of the dict is implementation dependent, so sort
        # it based on the key (name) to ensure the order is the same
        # on all hosts
        for (name, child) in sorted(self._children.items()):
            for obj in child.descendants():
                yield obj

    # Call C++ to create C++ object corresponding to this object
    def createCCObject(self):
        self.getCCParams()
        self.getCCObject() # force creation

    def getValue(self):
        return self.getCCObject()

    @cxxMethod(return_value_policy="reference")
    def getPort(self, if_name, idx):
        pass

    # Create C++ port connections corresponding to the connections in
    # _port_refs
    def connectPorts(self):
        # Sort the ports based on their attribute name to ensure the
        # order is the same on all hosts
        for (attr, portRef) in sorted(self._port_refs.items()):
            portRef.ccConnect()

    # Default function for generating the device structure.
    # Can be overloaded by the inheriting class
    def generateDeviceTree(self, state):
        return # return without yielding anything
        yield  # make this function a (null) generator

    def recurseDeviceTree(self, state):
        for child in self._children.values():
            for item in child: # For looping over SimObjectVectors
                for dt in item.generateDeviceTree(state):
                    yield dt

    # On a separate method otherwise certain buggy Python versions
    # would fail with: SyntaxError: unqualified exec is not allowed
    # in function 'apply_config'
    def _apply_config_get_dict(self):
        return {
            child_name: SimObjectCliWrapper(
                iter(self._children[child_name]))
            for child_name in self._children
        }

    def apply_config(self, params):
        """
        exec a list of Python code strings contained in params.

        The only exposed globals to those strings are the child
        SimObjects of this node.

        This function is intended to allow users to modify SimObject
        parameters from the command line with Python statements.
        """
        d = self._apply_config_get_dict()
        for param in params:
            exec(param, d)

    def get_simobj(self, simobj_path):
        """
        Get all sim objects that match a given string.

        The format is the same as that supported by SimObjectCliWrapper.

        :param simobj_path: Current state to be in.
        :type simobj_path: str
        """
        d = self._apply_config_get_dict()
        return eval(simobj_path, d)

# Function to provide to C++ so it can look up instances based on paths
def resolveSimObject(name):
    obj = instanceDict[name]
    return obj.getCCObject()

def isSimObject(value):
    return isinstance(value, SimObject)

def isSimObjectClass(value):
    return issubclass(value, SimObject)

def isSimObjectVector(value):
    return isinstance(value, SimObjectVector)

def isSimObjectSequence(value):
    if not isinstance(value, (list, tuple)) or len(value) == 0:
        return False

    for val in value:
        if not isNullPointer(val) and not isSimObject(val):
            return False

    return True

def isSimObjectOrSequence(value):
    return isSimObject(value) or isSimObjectSequence(value)

def isRoot(obj):
    from m5.objects import Root
    return obj and obj is Root.getInstance()

def isSimObjectOrVector(value):
    return isSimObject(value) or isSimObjectVector(value)

def tryAsSimObjectOrVector(value):
    if isSimObjectOrVector(value):
        return value
    if isSimObjectSequence(value):
        return SimObjectVector(value)
    return None

def coerceSimObjectOrVector(value):
    value = tryAsSimObjectOrVector(value)
    if value is None:
        raise TypeError("SimObject or SimObjectVector expected")
    return value

baseClasses = allClasses.copy()
baseInstances = instanceDict.copy()

def clear():
    global allClasses, instanceDict, noCxxHeader

    allClasses = baseClasses.copy()
    instanceDict = baseInstances.copy()
    noCxxHeader = False

# __all__ defines the list of symbols that get exported when
# 'from config import *' is invoked.  Try to keep this reasonably
# short to avoid polluting other namespaces.
__all__ = [
    'SimObject',
    'cxxMethod',
    'PyBindMethod',
    'PyBindProperty',
]
