# Copyright (c) 2012-2014, 2017-2019, 2021 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-2011 Advanced Micro Devices, Inc.
# 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.

#####################################################################
#
# Parameter description classes
#
# The _params dictionary in each class maps parameter names to either
# a Param or a VectorParam object.  These objects contain the
# parameter description string, the parameter type, and the default
# value (if any).  The convert() method on these objects is used to
# force whatever value is assigned to the parameter to the appropriate
# type.
#
# Note that the default values are loaded into the class's attribute
# space when the parameter dictionary is initialized (in
# MetaSimObject._new_param()); after that point they aren't used.
#
#####################################################################

import copy
import datetime
import re
import sys
import time
import math

from . import proxy
from . import ticks
from .util import *

def isSimObject(*args, **kwargs):
    from . import SimObject
    return SimObject.isSimObject(*args, **kwargs)

def isSimObjectSequence(*args, **kwargs):
    from . import SimObject
    return SimObject.isSimObjectSequence(*args, **kwargs)

def isSimObjectClass(*args, **kwargs):
    from . import SimObject
    return SimObject.isSimObjectClass(*args, **kwargs)

allParams = {}

class MetaParamValue(type):
    def __new__(mcls, name, bases, dct):
        cls = super().__new__(mcls, name, bases, dct)
        if name in allParams:
            warn("%s already exists in allParams. This may be caused by the " \
                 "Python 2.7 compatibility layer." % (name, ))
        allParams[name] = cls
        return cls


# Dummy base class to identify types that are legitimate for SimObject
# parameters.
class ParamValue(object, metaclass=MetaParamValue):
    cmd_line_settable = False

    # Generate the code needed as a prerequisite for declaring a C++
    # object of this type.  Typically generates one or more #include
    # statements.  Used when declaring parameters of this type.
    @classmethod
    def cxx_predecls(cls, code):
        pass

    @classmethod
    def pybind_predecls(cls, code):
        cls.cxx_predecls(code)

    # default for printing to .ini file is regular string conversion.
    # will be overridden in some cases
    def ini_str(self):
        return str(self)

    # default for printing to .json file is regular string conversion.
    # will be overridden in some cases, mostly to use native Python
    # types where there are similar JSON types
    def config_value(self):
        return str(self)

    # Prerequisites for .ini parsing with cxx_ini_parse
    @classmethod
    def cxx_ini_predecls(cls, code):
        pass

    # parse a .ini file entry for this param from string expression
    # src into lvalue dest (of the param's C++ type)
    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code('// Unhandled param type: %s' % cls.__name__)
        code('%s false;' % ret)

    # allows us to blithely call unproxy() on things without checking
    # if they're really proxies or not
    def unproxy(self, base):
        return self

    # Produce a human readable version of the stored value
    def pretty_print(self, value):
        return str(value)

# Regular parameter description.
class ParamDesc(object):
    def __init__(self, ptype_str, ptype, *args, **kwargs):
        self.ptype_str = ptype_str
        # remember ptype only if it is provided
        if ptype != None:
            self.ptype = ptype

        if args:
            if len(args) == 1:
                self.desc = args[0]
            elif len(args) == 2:
                self.default = args[0]
                self.desc = args[1]
            else:
                raise TypeError('too many arguments')

        if 'desc' in kwargs:
            assert(not hasattr(self, 'desc'))
            self.desc = kwargs['desc']
            del kwargs['desc']

        if 'default' in kwargs:
            assert(not hasattr(self, 'default'))
            self.default = kwargs['default']
            del kwargs['default']

        if kwargs:
            raise TypeError('extra unknown kwargs %s' % kwargs)

        if not hasattr(self, 'desc'):
            raise TypeError('desc attribute missing')

    def __getattr__(self, attr):
        if attr == 'ptype':
            from . import SimObject
            ptype = SimObject.allClasses[self.ptype_str]
            assert isSimObjectClass(ptype)
            self.ptype = ptype
            return ptype

        raise AttributeError("'%s' object has no attribute '%s'" % \
              (type(self).__name__, attr))

    def example_str(self):
        if hasattr(self.ptype, "ex_str"):
            return self.ptype.ex_str
        else:
            return self.ptype_str

    # Is the param available to be exposed on the command line
    def isCmdLineSettable(self):
        if hasattr(self.ptype, "cmd_line_settable"):
            return self.ptype.cmd_line_settable
        else:
            return False

    def convert(self, value):
        if isinstance(value, proxy.BaseProxy):
            value.set_param_desc(self)
            return value
        if 'ptype' not in self.__dict__ and isNullPointer(value):
            # deferred evaluation of SimObject; continue to defer if
            # we're just assigning a null pointer
            return value
        if isinstance(value, self.ptype):
            return value
        if isNullPointer(value) and isSimObjectClass(self.ptype):
            return value
        return self.ptype(value)

    def pretty_print(self, value):
        if isinstance(value, proxy.BaseProxy):
           return str(value)
        if isNullPointer(value):
           return NULL
        return self.ptype(value).pretty_print(value)

    def cxx_predecls(self, code):
        code('#include <cstddef>')
        self.ptype.cxx_predecls(code)

    def pybind_predecls(self, code):
        self.ptype.pybind_predecls(code)

    def cxx_decl(self, code):
        code('${{self.ptype.cxx_type}} ${{self.name}};')

# Vector-valued parameter description.  Just like ParamDesc, except
# that the value is a vector (list) of the specified type instead of a
# single value.

class VectorParamValue(list, metaclass=MetaParamValue):
    def __setattr__(self, attr, value):
        raise AttributeError("Not allowed to set %s on '%s'" % \
                             (attr, type(self).__name__))

    def config_value(self):
        return [v.config_value() for v in self]

    def ini_str(self):
        return ' '.join([v.ini_str() for v in self])

    def getValue(self):
        return [ v.getValue() for v in self ]

    def unproxy(self, base):
        if len(self) == 1 and isinstance(self[0], proxy.BaseProxy):
            # The value is a proxy (e.g. Parent.any, Parent.all or
            # Parent.x) therefore try resolve it
            return self[0].unproxy(base)
        else:
            return [v.unproxy(base) for v in self]

class SimObjectVector(VectorParamValue):
    # support clone operation
    def __call__(self, **kwargs):
        return SimObjectVector([v(**kwargs) for v in self])

    def clear_parent(self, old_parent):
        for v in self:
            v.clear_parent(old_parent)

    def set_parent(self, parent, name):
        if len(self) == 1:
            self[0].set_parent(parent, name)
        else:
            width = int(math.ceil(math.log(len(self))/math.log(10)))
            for i,v in enumerate(self):
                v.set_parent(parent, "%s%0*d" % (name, width, i))

    def has_parent(self):
        return any([e.has_parent() for e in self if not isNullPointer(e)])

    # return 'cpu0 cpu1' etc. for print_ini()
    def get_name(self):
        return ' '.join([v._name for v in self])

    # By iterating through the constituent members of the vector here
    # we can nicely handle iterating over all a SimObject's children
    # without having to provide lots of special functions on
    # SimObjectVector directly.
    def descendants(self):
        for v in self:
            for obj in v.descendants():
                yield obj

    def get_config_as_dict(self):
        a = []
        for v in self:
            a.append(v.get_config_as_dict())
        return a

    # If we are replacing an item in the vector, make sure to set the
    # parent reference of the new SimObject to be the same as the parent
    # of the SimObject being replaced. Useful to have if we created
    # a SimObjectVector of temporary objects that will be modified later in
    # configuration scripts.
    def __setitem__(self, key, value):
        val = self[key]
        if value.has_parent():
            warn("SimObject %s already has a parent" % value.get_name() +\
                 " that is being overwritten by a SimObjectVector")
        value.set_parent(val.get_parent(), val._name)
        super().__setitem__(key, value)

    # Enumerate the params of each member of the SimObject vector. Creates
    # strings that will allow indexing into the vector by the python code and
    # allow it to be specified on the command line.
    def enumerateParams(self, flags_dict = {},
                        cmd_line_str = "",
                        access_str = ""):
        if hasattr(self, "_paramEnumed"):
            print("Cycle detected enumerating params at %s?!" % (cmd_line_str))
        else:
            x = 0
            for vals in self:
                # Each entry in the SimObjectVector should be an
                # instance of a SimObject
                flags_dict = vals.enumerateParams(flags_dict,
                                                  cmd_line_str + "%d." % x,
                                                  access_str + "[%d]." % x)
                x = x + 1

        return flags_dict

class VectorParamDesc(ParamDesc):
    # Convert assigned value to appropriate type.  If the RHS is not a
    # list or tuple, it generates a single-element list.
    def convert(self, value):
        if isinstance(value, (list, tuple)):
            # list: coerce each element into new list
            tmp_list = [ ParamDesc.convert(self, v) for v in value ]
        elif isinstance(value, str):
            # If input is a csv string
            tmp_list = [ ParamDesc.convert(self, v) \
                         for v in value.strip('[').strip(']').split(',') ]
        else:
            # singleton: coerce to a single-element list
            tmp_list = [ ParamDesc.convert(self, value) ]

        if isSimObjectSequence(tmp_list):
            return SimObjectVector(tmp_list)
        else:
            return VectorParamValue(tmp_list)

    # Produce a human readable example string that describes
    # how to set this vector parameter in the absence of a default
    # value.
    def example_str(self):
        s = super().example_str()
        help_str = "[" + s + "," + s + ", ...]"
        return help_str

    # Produce a human readable representation of the value of this vector param.
    def pretty_print(self, value):
        if isinstance(value, (list, tuple)):
            tmp_list = [ ParamDesc.pretty_print(self, v) for v in value ]
        elif isinstance(value, str):
            tmp_list = [ ParamDesc.pretty_print(self, v) for v in value.split(',') ]
        else:
            tmp_list = [ ParamDesc.pretty_print(self, value) ]

        return tmp_list

    # This is a helper function for the new config system
    def __call__(self, value):
        if isinstance(value, (list, tuple)):
            # list: coerce each element into new list
            tmp_list = [ ParamDesc.convert(self, v) for v in value ]
        elif isinstance(value, str):
            # If input is a csv string
            tmp_list = [ ParamDesc.convert(self, v) \
                         for v in value.strip('[').strip(']').split(',') ]
        else:
            # singleton: coerce to a single-element list
            tmp_list = [ ParamDesc.convert(self, value) ]

        return VectorParamValue(tmp_list)

    def cxx_predecls(self, code):
        code('#include <vector>')
        self.ptype.cxx_predecls(code)

    def pybind_predecls(self, code):
        code('#include <vector>')
        self.ptype.pybind_predecls(code)

    def cxx_decl(self, code):
        code('std::vector< ${{self.ptype.cxx_type}} > ${{self.name}};')

class ParamFactory(object):
    def __init__(self, param_desc_class, ptype_str = None):
        self.param_desc_class = param_desc_class
        self.ptype_str = ptype_str

    def __getattr__(self, attr):
        if self.ptype_str:
            attr = self.ptype_str + '.' + attr
        return ParamFactory(self.param_desc_class, attr)

    # E.g., Param.Int(5, "number of widgets")
    def __call__(self, *args, **kwargs):
        ptype = None
        try:
            ptype = allParams[self.ptype_str]
        except KeyError:
            # if name isn't defined yet, assume it's a SimObject, and
            # try to resolve it later
            pass
        return self.param_desc_class(self.ptype_str, ptype, *args, **kwargs)

Param = ParamFactory(ParamDesc)
VectorParam = ParamFactory(VectorParamDesc)

#####################################################################
#
# Parameter Types
#
# Though native Python types could be used to specify parameter types
# (the 'ptype' field of the Param and VectorParam classes), it's more
# flexible to define our own set of types.  This gives us more control
# over how Python expressions are converted to values (via the
# __init__() constructor) and how these values are printed out (via
# the __str__() conversion method).
#
#####################################################################

# String-valued parameter.  Just mixin the ParamValue class with the
# built-in str class.
class String(ParamValue,str):
    cxx_type = 'std::string'
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(self, code):
        code('#include <string>')

    def __call__(self, value):
        self = value
        return value

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code('%s = %s;' % (dest, src))
        code('%s true;' % ret)

    def getValue(self):
        return self

# superclass for "numeric" parameter values, to emulate math
# operations in a type-safe way.  e.g., a Latency times an int returns
# a new Latency object.
class NumericParamValue(ParamValue):
    @staticmethod
    def unwrap(v):
        return v.value if isinstance(v, NumericParamValue) else v

    def __str__(self):
        return str(self.value)

    def __float__(self):
        return float(self.value)

    def __int__(self):
        return int(self.value)

    # hook for bounds checking
    def _check(self):
        return

    def __mul__(self, other):
        newobj = self.__class__(self)
        newobj.value *= NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    __rmul__ = __mul__

    def __truediv__(self, other):
        newobj = self.__class__(self)
        newobj.value /= NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    def __floordiv__(self, other):
        newobj = self.__class__(self)
        newobj.value //= NumericParamValue.unwrap(other)
        newobj._check()
        return newobj


    def __add__(self, other):
        newobj = self.__class__(self)
        newobj.value += NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    def __sub__(self, other):
        newobj = self.__class__(self)
        newobj.value -= NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    def __iadd__(self, other):
        self.value += NumericParamValue.unwrap(other)
        self._check()
        return self

    def __isub__(self, other):
        self.value -= NumericParamValue.unwrap(other)
        self._check()
        return self

    def __imul__(self, other):
        self.value *= NumericParamValue.unwrap(other)
        self._check()
        return self

    def __itruediv__(self, other):
        self.value /= NumericParamValue.unwrap(other)
        self._check()
        return self

    def __ifloordiv__(self, other):
        self.value //= NumericParamValue.unwrap(other)
        self._check()
        return self

    def __lt__(self, other):
        return self.value < NumericParamValue.unwrap(other)

    def config_value(self):
        return self.value

    @classmethod
    def cxx_ini_predecls(cls, code):
        # Assume that base/str.hh will be included anyway
        # code('#include "base/str.hh"')
        pass

    # The default for parsing PODs from an .ini entry is to extract from an
    # istringstream and let overloading choose the right type according to
    # the dest type.
    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code('%s to_number(%s, %s);' % (ret, src, dest))

# Metaclass for bounds-checked integer parameters.  See CheckedInt.
class CheckedIntType(MetaParamValue):
    def __init__(cls, name, bases, dict):
        super().__init__(name, bases, dict)

        # CheckedInt is an abstract base class, so we actually don't
        # want to do any processing on it... the rest of this code is
        # just for classes that derive from CheckedInt.
        if name == 'CheckedInt':
            return

        if not (hasattr(cls, 'min') and hasattr(cls, 'max')):
            if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')):
                panic("CheckedInt subclass %s must define either\n" \
                      "    'min' and 'max' or 'size' and 'unsigned'\n",
                      name);
            if cls.unsigned:
                cls.min = 0
                cls.max = 2 ** cls.size - 1
            else:
                cls.min = -(2 ** (cls.size - 1))
                cls.max = (2 ** (cls.size - 1)) - 1

# Abstract superclass for bounds-checked integer parameters.  This
# class is subclassed to generate parameter classes with specific
# bounds.  Initialization of the min and max bounds is done in the
# metaclass CheckedIntType.__init__.
class CheckedInt(NumericParamValue, metaclass=CheckedIntType):
    cmd_line_settable = True

    def _check(self):
        if not self.min <= self.value <= self.max:
            raise TypeError('Integer param out of bounds %d < %d < %d' % \
                  (self.min, self.value, self.max))

    def __init__(self, value):
        if isinstance(value, str):
            self.value = convert.toInteger(value)
        elif isinstance(value, (int, float, NumericParamValue)):
            self.value = int(value)
        else:
            raise TypeError("Can't convert object of type %s to CheckedInt" \
                  % type(value).__name__)
        self._check()

    def __call__(self, value):
        self.__init__(value)
        return value

    def __index__(self):
        return int(self.value)

    @classmethod
    def cxx_predecls(cls, code):
        # most derived types require this, so we just do it here once
        code('#include "base/types.hh"')

    def getValue(self):
        return int(self.value)

class Int(CheckedInt):      cxx_type = 'int';      size = 32; unsigned = False
class Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True

class Int8(CheckedInt):     cxx_type =   'int8_t'; size =  8; unsigned = False
class UInt8(CheckedInt):    cxx_type =  'uint8_t'; size =  8; unsigned = True
class Int16(CheckedInt):    cxx_type =  'int16_t'; size = 16; unsigned = False
class UInt16(CheckedInt):   cxx_type = 'uint16_t'; size = 16; unsigned = True
class Int32(CheckedInt):    cxx_type =  'int32_t'; size = 32; unsigned = False
class UInt32(CheckedInt):   cxx_type = 'uint32_t'; size = 32; unsigned = True
class Int64(CheckedInt):    cxx_type =  'int64_t'; size = 64; unsigned = False
class UInt64(CheckedInt):   cxx_type = 'uint64_t'; size = 64; unsigned = True

class Counter(CheckedInt):  cxx_type = 'Counter';  size = 64; unsigned = True
class Tick(CheckedInt):     cxx_type = 'Tick';     size = 64; unsigned = True
class TcpPort(CheckedInt):  cxx_type = 'uint16_t'; size = 16; unsigned = True
class UdpPort(CheckedInt):  cxx_type = 'uint16_t'; size = 16; unsigned = True

class Percent(CheckedInt):  cxx_type = 'int'; min = 0; max = 100

class Cycles(CheckedInt):
    cxx_type = 'Cycles'
    size = 64
    unsigned = True

    def getValue(self):
        from _m5.core import Cycles
        return Cycles(self.value)

    @classmethod
    def cxx_ini_predecls(cls, code):
        # Assume that base/str.hh will be included anyway
        # code('#include "base/str.hh"')
        pass

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code('uint64_t _temp;')
        code('bool _ret = to_number(%s, _temp);' % src)
        code('if (_ret)')
        code('    %s = Cycles(_temp);' % dest)
        code('%s _ret;' % ret)

class Float(ParamValue, float):
    cxx_type = 'double'
    cmd_line_settable = True

    def __init__(self, value):
        if isinstance(value, (int, float, NumericParamValue, Float, str)):
            self.value = float(value)
        else:
            raise TypeError("Can't convert object of type %s to Float" \
                  % type(value).__name__)

    def __call__(self, value):
        self.__init__(value)
        return value

    def getValue(self):
        return float(self.value)

    def config_value(self):
        return self

    @classmethod
    def cxx_ini_predecls(cls, code):
        code('#include <sstream>')

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code('%s (std::istringstream(%s) >> %s).eof();' % (ret, src, dest))

class MemorySize(CheckedInt):
    cxx_type = 'uint64_t'
    ex_str = '512MiB'
    size = 64
    unsigned = True
    def __init__(self, value):
        if isinstance(value, MemorySize):
            self.value = value.value
        else:
            self.value = convert.toMemorySize(value)
        self._check()

class MemorySize32(CheckedInt):
    cxx_type = 'uint32_t'
    ex_str = '512MiB'
    size = 32
    unsigned = True
    def __init__(self, value):
        if isinstance(value, MemorySize):
            self.value = value.value
        else:
            self.value = convert.toMemorySize(value)
        self._check()

class Addr(CheckedInt):
    cxx_type = 'Addr'
    size = 64
    unsigned = True
    def __init__(self, value):
        if isinstance(value, Addr):
            self.value = value.value
        else:
            try:
                # Often addresses are referred to with sizes. Ex: A device
                # base address is at "512MiB".  Use toMemorySize() to convert
                # these into addresses. If the address is not specified with a
                # "size", an exception will occur and numeric translation will
                # proceed below.
                self.value = convert.toMemorySize(value)
            except (TypeError, ValueError):
                # Convert number to string and use long() to do automatic
                # base conversion (requires base=0 for auto-conversion)
                self.value = int(str(value), base=0)

        self._check()
    def __add__(self, other):
        if isinstance(other, Addr):
            return self.value + other.value
        else:
            return self.value + other
    def pretty_print(self, value):
        try:
            val = convert.toMemorySize(value)
        except TypeError:
            val = int(value)
        return "0x%x" % int(val)

class AddrRange(ParamValue):
    cxx_type = 'AddrRange'

    def __init__(self, *args, **kwargs):
        # Disable interleaving and hashing by default
        self.intlvBits = 0
        self.intlvMatch = 0
        self.masks = []

        def handle_kwargs(self, kwargs):
            # An address range needs to have an upper limit, specified
            # either explicitly with an end, or as an offset using the
            # size keyword.
            if 'end' in kwargs:
                self.end = Addr(kwargs.pop('end'))
            elif 'size' in kwargs:
                self.end = self.start + Addr(kwargs.pop('size'))
            else:
                raise TypeError("Either end or size must be specified")

            # Now on to the optional bit
            if 'intlvMatch' in kwargs:
                self.intlvMatch = int(kwargs.pop('intlvMatch'))

            if 'masks' in kwargs:
                self.masks = [ int(x) for x in list(kwargs.pop('masks')) ]
                self.intlvBits = len(self.masks)
            else:
                if 'intlvBits' in kwargs:
                    self.intlvBits = int(kwargs.pop('intlvBits'))
                    self.masks = [0] * self.intlvBits
                    if 'intlvHighBit' not in kwargs:
                        raise TypeError("No interleave bits specified")
                    intlv_high_bit = int(kwargs.pop('intlvHighBit'))
                    xor_high_bit = 0
                    if 'xorHighBit' in kwargs:
                        xor_high_bit = int(kwargs.pop('xorHighBit'))
                    for i in range(0, self.intlvBits):
                        bit1 = intlv_high_bit - i
                        mask = 1 << bit1
                        if xor_high_bit != 0:
                            bit2 = xor_high_bit - i
                            mask |= 1 << bit2
                        self.masks[self.intlvBits - i - 1] = mask

        if len(args) == 0:
            self.start = Addr(kwargs.pop('start'))
            handle_kwargs(self, kwargs)

        elif len(args) == 1:
            if kwargs:
                self.start = Addr(args[0])
                handle_kwargs(self, kwargs)
            elif isinstance(args[0], (list, tuple)):
                self.start = Addr(args[0][0])
                self.end = Addr(args[0][1])
            else:
                self.start = Addr(0)
                self.end = Addr(args[0])

        elif len(args) == 2:
            self.start = Addr(args[0])
            self.end = Addr(args[1])
        else:
            raise TypeError("Too many arguments specified")

        if kwargs:
            raise TypeError("Too many keywords: %s" % list(kwargs.keys()))

    def __str__(self):
        if len(self.masks) == 0:
            return '%s:%s' % (self.start, self.end)
        else:
            return '%s:%s:%s:%s' % (self.start, self.end, self.intlvMatch,
                                    ':'.join(str(m) for m in self.masks))

    def size(self):
        # Divide the size by the size of the interleaving slice
        return (int(self.end) - int(self.start)) >> self.intlvBits

    @classmethod
    def cxx_predecls(cls, code):
        Addr.cxx_predecls(code)
        code('#include "base/addr_range.hh"')

    @classmethod
    def pybind_predecls(cls, code):
        Addr.pybind_predecls(code)
        code('#include "base/addr_range.hh"')

    @classmethod
    def cxx_ini_predecls(cls, code):
        code('#include <sstream>')
        code('#include <vector>')
        code('#include "base/types.hh"')

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code('bool _ret = true;')
        code('uint64_t _start, _end, _intlvMatch = 0;')
        code('std::vector<Addr> _masks;')
        code('char _sep;')
        code('std::istringstream _stream(${src});')
        code('_stream >> _start;')
        code('_stream.get(_sep);')
        code('_ret = _sep == \':\';')
        code('_stream >> _end;')
        code('if (!_stream.fail() && !_stream.eof()) {')
        code('    _stream.get(_sep);')
        code('    _ret = ret && _sep == \':\';')
        code('    _stream >> _intlvMatch;')
        code('    while (!_stream.fail() && !_stream.eof()) {')
        code('        _stream.get(_sep);')
        code('        _ret = ret && _sep == \':\';')
        code('        Addr mask;')
        code('        _stream >> mask;')
        code('        _masks.push_back(mask);')
        code('    }')
        code('}')
        code('_ret = _ret && !_stream.fail() && _stream.eof();')
        code('if (_ret)')
        code('   ${dest} = AddrRange(_start, _end, _masks, _intlvMatch);')
        code('${ret} _ret;')

    def getValue(self):
        # Go from the Python class to the wrapped C++ class
        from _m5.range import AddrRange

        return AddrRange(int(self.start), int(self.end),
                         self.masks, int(self.intlvMatch))

    def exclude(self, ranges):
        pybind_exclude = list([ r.getValue() for r in ranges ])
        pybind_include = self.getValue().exclude(pybind_exclude)

        return list([ AddrRange(r.start(), r.end()) for r in pybind_include ])

# Boolean parameter type.  Python doesn't let you subclass bool, since
# it doesn't want to let you create multiple instances of True and
# False.  Thus this is a little more complicated than String.
class Bool(ParamValue):
    cxx_type = 'bool'
    cmd_line_settable = True

    def __init__(self, value):
        try:
            self.value = convert.toBool(value)
        except TypeError:
            self.value = bool(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def getValue(self):
        return bool(self.value)

    def __str__(self):
        return str(self.value)

    # implement truth value testing for Bool parameters so that these params
    # evaluate correctly during the python configuration phase
    def __bool__(self):
        return bool(self.value)

    # Python 2.7 uses __nonzero__ instead of __bool__
    __nonzero__ = __bool__

    def ini_str(self):
        if self.value:
            return 'true'
        return 'false'

    def config_value(self):
        return self.value

    @classmethod
    def cxx_ini_predecls(cls, code):
        # Assume that base/str.hh will be included anyway
        # code('#include "base/str.hh"')
        pass

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code('%s to_bool(%s, %s);' % (ret, src, dest))

def IncEthernetAddr(addr, val = 1):
    bytes = [ int(x, 16) for x in addr.split(':') ]
    bytes[5] += val
    for i in (5, 4, 3, 2, 1):
        val,rem = divmod(bytes[i], 256)
        bytes[i] = rem
        if val == 0:
            break
        bytes[i - 1] += val
    assert(bytes[0] <= 255)
    return ':'.join(map(lambda x: '%02x' % x, bytes))

_NextEthernetAddr = "00:90:00:00:00:01"
def NextEthernetAddr():
    global _NextEthernetAddr

    value = _NextEthernetAddr
    _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1)
    return value

class EthernetAddr(ParamValue):
    cxx_type = 'networking::EthAddr'
    ex_str = "00:90:00:00:00:01"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/inet.hh"')

    def __init__(self, value):
        if value == NextEthernetAddr:
            self.value = value
            return

        if not isinstance(value, str):
            raise TypeError("expected an ethernet address and didn't get one")

        bytes = value.split(':')
        if len(bytes) != 6:
            raise TypeError('invalid ethernet address %s' % value)

        for byte in bytes:
            if not 0 <= int(byte, base=16) <= 0xff:
                raise TypeError('invalid ethernet address %s' % value)

        self.value = value

    def __call__(self, value):
        self.__init__(value)
        return value

    def unproxy(self, base):
        if self.value == NextEthernetAddr:
            return EthernetAddr(self.value())
        return self

    def getValue(self):
        from _m5.net import EthAddr
        return EthAddr(self.value)

    def __str__(self):
        return self.value

    def ini_str(self):
        return self.value

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code('%s = networking::EthAddr(%s);' % (dest, src))
        code('%s true;' % ret)

# When initializing an IpAddress, pass in an existing IpAddress, a string of
# the form "a.b.c.d", or an integer representing an IP.
class IpAddress(ParamValue):
    cxx_type = 'networking::IpAddress'
    ex_str = "127.0.0.1"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/inet.hh"')

    def __init__(self, value):
        if isinstance(value, IpAddress):
            self.ip = value.ip
        else:
            try:
                self.ip = convert.toIpAddress(value)
            except TypeError:
                self.ip = int(value)
        self.verifyIp()

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        tup = [(self.ip >> i)  & 0xff for i in (24, 16, 8, 0)]
        return '%d.%d.%d.%d' % tuple(tup)

    def __eq__(self, other):
        if isinstance(other, IpAddress):
            return self.ip == other.ip
        elif isinstance(other, str):
            try:
                return self.ip == convert.toIpAddress(other)
            except:
                return False
        else:
            return self.ip == other

    def __ne__(self, other):
        return not (self == other)

    def verifyIp(self):
        if self.ip < 0 or self.ip >= (1 << 32):
            raise TypeError("invalid ip address %#08x" % self.ip)

    def getValue(self):
        from _m5.net import IpAddress
        return IpAddress(self.ip)

# When initializing an IpNetmask, pass in an existing IpNetmask, a string of
# the form "a.b.c.d/n" or "a.b.c.d/e.f.g.h", or an ip and netmask as
# positional or keyword arguments.
class IpNetmask(IpAddress):
    cxx_type = 'networking::IpNetmask'
    ex_str = "127.0.0.0/24"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/inet.hh"')

    def __init__(self, *args, **kwargs):
        def handle_kwarg(self, kwargs, key, elseVal = None):
            if key in kwargs:
                setattr(self, key, kwargs.pop(key))
            elif elseVal:
                setattr(self, key, elseVal)
            else:
                raise TypeError("No value set for %s" % key)

        if len(args) == 0:
            handle_kwarg(self, kwargs, 'ip')
            handle_kwarg(self, kwargs, 'netmask')

        elif len(args) == 1:
            if kwargs:
                if not 'ip' in kwargs and not 'netmask' in kwargs:
                    raise TypeError("Invalid arguments")
                handle_kwarg(self, kwargs, 'ip', args[0])
                handle_kwarg(self, kwargs, 'netmask', args[0])
            elif isinstance(args[0], IpNetmask):
                self.ip = args[0].ip
                self.netmask = args[0].netmask
            else:
                (self.ip, self.netmask) = convert.toIpNetmask(args[0])

        elif len(args) == 2:
            self.ip = args[0]
            self.netmask = args[1]
        else:
            raise TypeError("Too many arguments specified")

        if kwargs:
            raise TypeError("Too many keywords: %s" % list(kwargs.keys()))

        self.verify()

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        return "%s/%d" % (super().__str__(), self.netmask)

    def __eq__(self, other):
        if isinstance(other, IpNetmask):
            return self.ip == other.ip and self.netmask == other.netmask
        elif isinstance(other, str):
            try:
                return (self.ip, self.netmask) == convert.toIpNetmask(other)
            except:
                return False
        else:
            return False

    def verify(self):
        self.verifyIp()
        if self.netmask < 0 or self.netmask > 32:
            raise TypeError("invalid netmask %d" % netmask)

    def getValue(self):
        from _m5.net import IpNetmask
        return IpNetmask(self.ip, self.netmask)

# When initializing an IpWithPort, pass in an existing IpWithPort, a string of
# the form "a.b.c.d:p", or an ip and port as positional or keyword arguments.
class IpWithPort(IpAddress):
    cxx_type = 'networking::IpWithPort'
    ex_str = "127.0.0.1:80"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/inet.hh"')

    def __init__(self, *args, **kwargs):
        def handle_kwarg(self, kwargs, key, elseVal = None):
            if key in kwargs:
                setattr(self, key, kwargs.pop(key))
            elif elseVal:
                setattr(self, key, elseVal)
            else:
                raise TypeError("No value set for %s" % key)

        if len(args) == 0:
            handle_kwarg(self, kwargs, 'ip')
            handle_kwarg(self, kwargs, 'port')

        elif len(args) == 1:
            if kwargs:
                if not 'ip' in kwargs and not 'port' in kwargs:
                    raise TypeError("Invalid arguments")
                handle_kwarg(self, kwargs, 'ip', args[0])
                handle_kwarg(self, kwargs, 'port', args[0])
            elif isinstance(args[0], IpWithPort):
                self.ip = args[0].ip
                self.port = args[0].port
            else:
                (self.ip, self.port) = convert.toIpWithPort(args[0])

        elif len(args) == 2:
            self.ip = args[0]
            self.port = args[1]
        else:
            raise TypeError("Too many arguments specified")

        if kwargs:
            raise TypeError("Too many keywords: %s" % list(kwargs.keys()))

        self.verify()

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        return "%s:%d" % (super().__str__(), self.port)

    def __eq__(self, other):
        if isinstance(other, IpWithPort):
            return self.ip == other.ip and self.port == other.port
        elif isinstance(other, str):
            try:
                return (self.ip, self.port) == convert.toIpWithPort(other)
            except:
                return False
        else:
            return False

    def verify(self):
        self.verifyIp()
        if self.port < 0 or self.port > 0xffff:
            raise TypeError("invalid port %d" % self.port)

    def getValue(self):
        from _m5.net import IpWithPort
        return IpWithPort(self.ip, self.port)

time_formats = [ "%a %b %d %H:%M:%S %Z %Y",
                 "%a %b %d %H:%M:%S %Y",
                 "%Y/%m/%d %H:%M:%S",
                 "%Y/%m/%d %H:%M",
                 "%Y/%m/%d",
                 "%m/%d/%Y %H:%M:%S",
                 "%m/%d/%Y %H:%M",
                 "%m/%d/%Y",
                 "%m/%d/%y %H:%M:%S",
                 "%m/%d/%y %H:%M",
                 "%m/%d/%y"]


def parse_time(value):
    from time import gmtime, strptime, struct_time, time
    from datetime import datetime, date

    if isinstance(value, struct_time):
        return value

    if isinstance(value, int):
        return gmtime(value)

    if isinstance(value, (datetime, date)):
        return value.timetuple()

    if isinstance(value, str):
        if value in ('Now', 'Today'):
            return time.gmtime(time.time())

        for format in time_formats:
            try:
                return strptime(value, format)
            except ValueError:
                pass

    raise ValueError("Could not parse '%s' as a time" % value)

class Time(ParamValue):
    cxx_type = 'tm'

    @classmethod
    def cxx_predecls(cls, code):
        code('#include <time.h>')

    def __init__(self, value):
        self.value = parse_time(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def getValue(self):
        from _m5.core import tm
        import calendar

        return tm.gmtime(calendar.timegm(self.value))

    def __str__(self):
        return time.asctime(self.value)

    def ini_str(self):
        return str(self)

    def get_config_as_dict(self):
        assert false
        return str(self)

    @classmethod
    def cxx_ini_predecls(cls, code):
        code('#include <time.h>')

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code('char *_parse_ret = strptime((${src}).c_str(),')
        code('    "%a %b %d %H:%M:%S %Y", &(${dest}));')
        code('${ret} _parse_ret && *_parse_ret == \'\\0\';');

# Enumerated types are a little more complex.  The user specifies the
# type as Enum(foo) where foo is either a list or dictionary of
# alternatives (typically strings, but not necessarily so).  (In the
# long run, the integer value of the parameter will be the list index
# or the corresponding dictionary value.  For now, since we only check
# that the alternative is valid and then spit it into a .ini file,
# there's not much point in using the dictionary.)

# What Enum() must do is generate a new type encapsulating the
# provided list/dictionary so that specific values of the parameter
# can be instances of that type.  We define two hidden internal
# classes (_ListEnum and _DictEnum) to serve as base classes, then
# derive the new type from the appropriate base class on the fly.

allEnums = {}
# Metaclass for Enum types
class MetaEnum(MetaParamValue):
    def __new__(mcls, name, bases, dict):

        cls = super().__new__(mcls, name, bases, dict)
        allEnums[name] = cls
        return cls

    def __init__(cls, name, bases, init_dict):
        if 'map' in init_dict:
            if not isinstance(cls.map, dict):
                raise TypeError("Enum-derived class attribute 'map' " \
                      "must be of type dict")
            # build list of value strings from map
            cls.vals = list(cls.map.keys())
            cls.vals.sort()
        elif 'vals' in init_dict:
            if not isinstance(cls.vals, list):
                raise TypeError("Enum-derived class attribute 'vals' " \
                      "must be of type list")
            # build string->value map from vals sequence
            cls.map = {}
            for idx,val in enumerate(cls.vals):
                cls.map[val] = idx
        else:
            raise TypeError("Enum-derived class must define "\
                  "attribute 'map' or 'vals'")

        if cls.is_class:
            cls.cxx_type = '%s' % name
        else:
            cls.cxx_type = 'enums::%s' % name

        super().__init__(name, bases, init_dict)

    # Generate C++ class declaration for this enum type.
    # Note that we wrap the enum in a class/struct to act as a namespace,
    # so that the enum strings can be brief w/o worrying about collisions.
    def cxx_decl(cls, code):
        wrapper_name = cls.wrapper_name
        wrapper = 'struct' if cls.wrapper_is_struct else 'namespace'
        name = cls.__name__ if cls.enum_name is None else cls.enum_name
        idem_macro = '__ENUM__%s__%s__' % (wrapper_name, name)

        code('''\
#ifndef $idem_macro
#define $idem_macro

namespace gem5
{
''')
        if cls.is_class:
            code('''\
enum class $name
{
''')
        else:
            code('''\
$wrapper $wrapper_name {
    enum $name
    {
''')
            code.indent(1)
        code.indent(1)
        for val in cls.vals:
            code('$val = ${{cls.map[val]}},')
        code('Num_$name = ${{len(cls.vals)}}')
        code.dedent(1)
        code('};')

        if cls.is_class:
            code('''\
extern const char *${name}Strings[static_cast<int>(${name}::Num_${name})];
''')
        elif cls.wrapper_is_struct:
            code('static const char *${name}Strings[Num_${name}];')
        else:
            code('extern const char *${name}Strings[Num_${name}];')

        if not cls.is_class:
            code.dedent(1)
            code('}; // $wrapper_name')

        code()
        code('} // namespace gem5')

        code()
        code('#endif // $idem_macro')

    def cxx_def(cls, code):
        wrapper_name = cls.wrapper_name
        file_name = cls.__name__
        name = cls.__name__ if cls.enum_name is None else cls.enum_name

        code('#include "base/compiler.hh"')
        code('#include "enums/$file_name.hh"')

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

        if cls.wrapper_is_struct:
            code('const char *${wrapper_name}::${name}Strings'
                '[Num_${name}] =')
        else:
            if cls.is_class:
                code('''\
const char *${name}Strings[static_cast<int>(${name}::Num_${name})] =
''')
            else:
                code('''GEM5_DEPRECATED_NAMESPACE(Enums, enums);
namespace enums
{''')
                code.indent(1)
                code('const char *${name}Strings[Num_${name}] =')

        code('{')
        code.indent(1)
        for val in cls.vals:
            code('"$val",')
        code.dedent(1)
        code('};')

        if not cls.wrapper_is_struct and not cls.is_class:
            code.dedent(1)
            code('} // namespace enums')

        code('} // namespace gem5')


    def pybind_def(cls, code):
        name = cls.__name__
        enum_name = cls.__name__ if cls.enum_name is None else cls.enum_name
        wrapper_name = enum_name if cls.is_class else cls.wrapper_name

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

#include <sim/init.hh>

namespace py = pybind11;

namespace gem5
{

static void
module_init(py::module_ &m_internal)
{
    py::module_ m = m_internal.def_submodule("enum_${name}");

''')
        if cls.is_class:
            code('py::enum_<${enum_name}>(m, "enum_${name}")')
        else:
            code('py::enum_<${wrapper_name}::${enum_name}>(m, "enum_${name}")')

        code.indent()
        code.indent()
        for val in cls.vals:
            code('.value("${val}", ${wrapper_name}::${val})')
        code('.value("Num_${name}", ${wrapper_name}::Num_${enum_name})')
        if not cls.is_class:
            code('.export_values()')
        code(';')
        code.dedent()

        code('}')
        code.dedent()
        code()
        code('static EmbeddedPyBind embed_enum("enum_${name}", module_init);')
        code()
        code('} // namespace gem5')


# Base class for enum types.
class Enum(ParamValue, metaclass=MetaEnum):
    vals = []
    cmd_line_settable = True

    # The name of the wrapping namespace or struct
    wrapper_name = 'enums'

    # If true, the enum is wrapped in a struct rather than a namespace
    wrapper_is_struct = False

    is_class = False

    # If not None, use this as the enum name rather than this class name
    enum_name = None

    def __init__(self, value):
        if value not in self.map:
            raise TypeError("Enum param got bad value '%s' (not in %s)" \
                  % (value, self.vals))
        self.value = value

    def __call__(self, value):
        self.__init__(value)
        return value

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "enums/$0.hh"', cls.__name__)

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code('if (false) {')
        for elem_name in cls.map.keys():
            code('} else if (%s == "%s") {' % (src, elem_name))
            code.indent()
            name = cls.__name__ if cls.enum_name is None else cls.enum_name
            code('%s = %s::%s;' % (dest, name if cls.is_class else 'enums',
                                   elem_name))
            code('%s true;' % ret)
            code.dedent()
        code('} else {')
        code('    %s false;' % ret)
        code('}')

    def getValue(self):
        import m5.internal.params
        e = getattr(m5.internal.params, "enum_%s" % self.__class__.__name__)
        return e(self.map[self.value])

    def __str__(self):
        return self.value

# This param will generate a scoped c++ enum and its python bindings.
class ScopedEnum(Enum):
    vals = []
    cmd_line_settable = True

    # The name of the wrapping namespace or struct
    wrapper_name = None

    # If true, the enum is wrapped in a struct rather than a namespace
    wrapper_is_struct = False

    # If true, the generated enum is a scoped enum
    is_class = True

    # If not None, use this as the enum name rather than this class name
    enum_name = None

class ByteOrder(ScopedEnum):
    """Enum representing component's byte order (endianness)"""

    vals = [
        'big',
        'little',
    ]

# how big does a rounding error need to be before we warn about it?
frequency_tolerance = 0.001  # 0.1%

class TickParamValue(NumericParamValue):
    cxx_type = 'Tick'
    ex_str = "1MHz"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/types.hh"')

    def __call__(self, value):
        self.__init__(value)
        return value

    def getValue(self):
        return int(self.value)

    @classmethod
    def cxx_ini_predecls(cls, code):
        code('#include <sstream>')

    # Ticks are expressed in seconds in JSON files and in plain
    # Ticks in .ini files.  Switch based on a config flag
    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code('${ret} to_number(${src}, ${dest});')

class Latency(TickParamValue):
    ex_str = "100ns"

    def __init__(self, value):
        if isinstance(value, (Latency, Clock)):
            self.ticks = value.ticks
            self.value = value.value
        elif isinstance(value, Frequency):
            self.ticks = value.ticks
            self.value = 1.0 / value.value
        elif value.endswith('t'):
            self.ticks = True
            self.value = int(value[:-1])
        else:
            self.ticks = False
            self.value = convert.toLatency(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def __getattr__(self, attr):
        if attr in ('latency', 'period'):
            return self
        if attr == 'frequency':
            return Frequency(self)
        raise AttributeError("Latency object has no attribute '%s'" % attr)

    def getValue(self):
        if self.ticks or self.value == 0:
            value = self.value
        else:
            value = ticks.fromSeconds(self.value)
        return int(value)

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

    # convert latency to ticks
    def ini_str(self):
        return '%d' % self.getValue()

class Frequency(TickParamValue):
    ex_str = "1GHz"

    def __init__(self, value):
        if isinstance(value, (Latency, Clock)):
            if value.value == 0:
                self.value = 0
            else:
                self.value = 1.0 / value.value
            self.ticks = value.ticks
        elif isinstance(value, Frequency):
            self.value = value.value
            self.ticks = value.ticks
        else:
            self.ticks = False
            self.value = convert.toFrequency(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def __getattr__(self, attr):
        if attr == 'frequency':
            return self
        if attr in ('latency', 'period'):
            return Latency(self)
        raise AttributeError("Frequency object has no attribute '%s'" % attr)

    # convert latency to ticks
    def getValue(self):
        if self.ticks or self.value == 0:
            value = self.value
        else:
            value = ticks.fromSeconds(1.0 / self.value)
        return int(value)

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

    def ini_str(self):
        return '%d' % self.getValue()

# A generic Frequency and/or Latency value. Value is stored as a
# latency, just like Latency and Frequency.
class Clock(TickParamValue):
    def __init__(self, value):
        if isinstance(value, (Latency, Clock)):
            self.ticks = value.ticks
            self.value = value.value
        elif isinstance(value, Frequency):
            self.ticks = value.ticks
            self.value = 1.0 / value.value
        elif value.endswith('t'):
            self.ticks = True
            self.value = int(value[:-1])
        else:
            self.ticks = False
            self.value = convert.anyToLatency(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        return "%s" % Latency(self)

    def __getattr__(self, attr):
        if attr == 'frequency':
            return Frequency(self)
        if attr in ('latency', 'period'):
            return Latency(self)
        raise AttributeError("Frequency object has no attribute '%s'" % attr)

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

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

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

class Voltage(Float):
    ex_str = "1V"

    def __new__(cls, value):
        value = convert.toVoltage(value)
        return super().__new__(cls, value)

    def __init__(self, value):
        value = convert.toVoltage(value)
        super().__init__(value)

class Current(Float):
    ex_str = "1mA"

    def __new__(cls, value):
        value = convert.toCurrent(value)
        return super().__new__(cls, value)

    def __init__(self, value):
        value = convert.toCurrent(value)
        super().__init__(value)

class Energy(Float):
    ex_str = "1pJ"

    def __new__(cls, value):
        value = convert.toEnergy(value)
        return super().__new__(cls, value)

    def __init__(self, value):
        value = convert.toEnergy(value)
        super().__init__(value)

class Temperature(ParamValue):
    cxx_type = 'Temperature'
    cmd_line_settable = True
    ex_str = "1C"

    def __init__(self, value):
        self.value = convert.toTemperature(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        return str(self.value)

    def getValue(self):
        from _m5.core import Temperature
        return Temperature.from_kelvin(self.value)

    def config_value(self):
        return self.value

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/temperature.hh"')

    @classmethod
    def cxx_ini_predecls(cls, code):
        # Assume that base/str.hh will be included anyway
        # code('#include "base/str.hh"')
        pass

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code('double _temp;')
        code('bool _ret = to_number(%s, _temp);' % src)
        code('if (_ret)')
        code('    %s = Temperature(_temp);' % dest)
        code('%s _ret;' % ret)

class NetworkBandwidth(float,ParamValue):
    cxx_type = 'float'
    ex_str = "1Gbps"
    cmd_line_settable = True

    def __new__(cls, value):
        # convert to bits per second
        val = convert.toNetworkBandwidth(value)
        return super().__new__(cls, val)

    def __str__(self):
        return str(self.val)

    def __call__(self, value):
        val = convert.toNetworkBandwidth(value)
        self.__init__(val)
        return value

    def getValue(self):
        # convert to seconds per byte
        value = 8.0 / float(self)
        # convert to ticks per byte
        value = ticks.fromSeconds(value)
        return float(value)

    def ini_str(self):
        return '%f' % self.getValue()

    def config_value(self):
        return '%f' % self.getValue()

    @classmethod
    def cxx_ini_predecls(cls, code):
        code('#include <sstream>')

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code('%s (std::istringstream(%s) >> %s).eof();' % (ret, src, dest))

class MemoryBandwidth(float,ParamValue):
    cxx_type = 'float'
    ex_str = "1GiB/s"
    cmd_line_settable = True

    def __new__(cls, value):
        # convert to bytes per second
        val = convert.toMemoryBandwidth(value)
        return super().__new__(cls, val)

    def __call__(self, value):
        val = convert.toMemoryBandwidth(value)
        self.__init__(val)
        return value

    def getValue(self):
        # convert to seconds per byte
        value = float(self)
        if value:
            value = 1.0 / float(self)
        # convert to ticks per byte
        value = ticks.fromSeconds(value)
        return float(value)

    def ini_str(self):
        return '%f' % self.getValue()

    def config_value(self):
        return '%f' % self.getValue()

    @classmethod
    def cxx_ini_predecls(cls, code):
        code('#include <sstream>')

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code('%s (std::istringstream(%s) >> %s).eof();' % (ret, src, dest))

#
# "Constants"... handy aliases for various values.
#

# Special class for NULL pointers.  Note the special check in
# make_param_value() above that lets these be assigned where a
# SimObject is required.
# only one copy of a particular node
class NullSimObject(object, metaclass=Singleton):
    _name = 'Null'

    def __call__(cls):
        return cls

    def _instantiate(self, parent = None, path = ''):
        pass

    def ini_str(self):
        return 'Null'

    def unproxy(self, base):
        return self

    def set_path(self, parent, name):
        pass

    def set_parent(self, parent, name):
        pass

    def clear_parent(self, old_parent):
        pass

    def descendants(self):
        return
        yield None

    def get_config_as_dict(self):
        return {}

    def __str__(self):
        return self._name

    def config_value(self):
        return None

    def getValue(self):
        return None

# The only instance you'll ever need...
NULL = NullSimObject()

def isNullPointer(value):
    return isinstance(value, NullSimObject)

# Some memory range specifications use this as a default upper bound.
MaxAddr = Addr.max
MaxTick = Tick.max
AllMemory = AddrRange(0, MaxAddr)


#####################################################################
#
# Port objects
#
# Ports are used to interconnect objects in the memory system.
#
#####################################################################

# Port reference: encapsulates a reference to a particular port on a
# particular SimObject.
class PortRef(object):
    def __init__(self, simobj, name, role, is_source):
        assert(isSimObject(simobj) or isSimObjectClass(simobj))
        self.simobj = simobj
        self.name = name
        self.role = role
        self.is_source = is_source
        self.peer = None   # not associated with another port yet
        self.ccConnected = False # C++ port connection done?
        self.index = -1  # always -1 for non-vector ports

    def __str__(self):
        return '%s.%s' % (self.simobj, self.name)

    def __len__(self):
        # Return the number of connected ports, i.e. 0 is we have no
        # peer and 1 if we do.
        return int(self.peer != None)

    # for config.ini, print peer's name (not ours)
    def ini_str(self):
        return str(self.peer)

    # for config.json
    def get_config_as_dict(self):
        return {'role' : self.role, 'peer' : str(self.peer),
                'is_source' : str(self.is_source)}

    def __getattr__(self, attr):
        if attr == 'peerObj':
            # shorthand for proxies
            return self.peer.simobj
        raise AttributeError("'%s' object has no attribute '%s'" % \
              (self.__class__.__name__, attr))

    # Full connection is symmetric (both ways).  Called via
    # SimObject.__setattr__ as a result of a port assignment, e.g.,
    # "obj1.portA = obj2.portB", or via VectorPortElementRef.__setitem__,
    # e.g., "obj1.portA[3] = obj2.portB".
    def connect(self, other):
        if isinstance(other, VectorPortRef):
            # reference to plain VectorPort is implicit append
            other = other._get_next()
        if self.peer and not proxy.isproxy(self.peer):
            fatal("Port %s is already connected to %s, cannot connect %s\n",
                  self, self.peer, other);
        self.peer = other

        if proxy.isproxy(other):
            other.set_param_desc(PortParamDesc())
            return
        elif not isinstance(other, PortRef):
            raise TypeError("assigning non-port reference '%s' to port '%s'" \
                  % (other, self))

        if not Port.is_compat(self, other):
            fatal("Ports %s and %s with roles '%s' and '%s' "
                    "are not compatible", self, other, self.role, other.role)

        if other.peer is not self:
            other.connect(self)

    # Allow a compatible port pair to be spliced between a port and its
    # connected peer. Useful operation for connecting instrumentation
    # structures into a system when it is necessary to connect the
    # instrumentation after the full system has been constructed.
    def splice(self, new_1, new_2):
        if not self.peer or proxy.isproxy(self.peer):
            fatal("Port %s not connected, cannot splice in new peers\n", self)

        if not isinstance(new_1, PortRef) or not isinstance(new_2, PortRef):
            raise TypeError(
                  "Splicing non-port references '%s','%s' to port '%s'" % \
                  (new_1, new_2, self))

        old_peer = self.peer

        if Port.is_compat(old_peer, new_1) and Port.is_compat(self, new_2):
            old_peer.peer = new_1
            new_1.peer = old_peer
            self.peer = new_2
            new_2.peer = self
        elif Port.is_compat(old_peer, new_2) and Port.is_compat(self, new_1):
            old_peer.peer = new_2
            new_2.peer = old_peer
            self.peer = new_1
            new_1.peer = self
        else:
            fatal("Ports %s(%s) and %s(%s) can't be compatibly spliced with "
                    "%s(%s) and %s(%s)", self, self.role,
                    old_peer, old_peer.role, new_1, new_1.role,
                    new_2, new_2.role)

    def clone(self, simobj, memo):
        if self in memo:
            return memo[self]
        newRef = copy.copy(self)
        memo[self] = newRef
        newRef.simobj = simobj
        assert(isSimObject(newRef.simobj))
        if self.peer and not proxy.isproxy(self.peer):
            peerObj = self.peer.simobj(_memo=memo)
            newRef.peer = self.peer.clone(peerObj, memo)
            assert(not isinstance(newRef.peer, VectorPortRef))
        return newRef

    def unproxy(self, simobj):
        assert(simobj is self.simobj)
        if proxy.isproxy(self.peer):
            try:
                realPeer = self.peer.unproxy(self.simobj)
            except:
                print("Error in unproxying port '%s' of %s" %
                      (self.name, self.simobj.path()))
                raise
            self.connect(realPeer)

    # Call C++ to create corresponding port connection between C++ objects
    def ccConnect(self):
        if self.ccConnected: # already done this
            return

        peer = self.peer
        if not self.peer: # nothing to connect to
            return

        port = self.simobj.getPort(self.name, self.index)
        peer_port = peer.simobj.getPort(peer.name, peer.index)
        port.bind(peer_port)

        self.ccConnected = True

# A reference to an individual element of a VectorPort... much like a
# PortRef, but has an index.
class VectorPortElementRef(PortRef):
    def __init__(self, simobj, name, role, is_source, index):
        PortRef.__init__(self, simobj, name, role, is_source)
        self.index = index

    def __str__(self):
        return '%s.%s[%d]' % (self.simobj, self.name, self.index)

# A reference to a complete vector-valued port (not just a single element).
# Can be indexed to retrieve individual VectorPortElementRef instances.
class VectorPortRef(object):
    def __init__(self, simobj, name, role, is_source):
        assert(isSimObject(simobj) or isSimObjectClass(simobj))
        self.simobj = simobj
        self.name = name
        self.role = role
        self.is_source = is_source
        self.elements = []

    def __str__(self):
        return '%s.%s[:]' % (self.simobj, self.name)

    def __len__(self):
        # Return the number of connected peers, corresponding the the
        # length of the elements.
        return len(self.elements)

    # for config.ini, print peer's name (not ours)
    def ini_str(self):
        return ' '.join([el.ini_str() for el in self.elements])

    # for config.json
    def get_config_as_dict(self):
        return {'role' : self.role,
                'peer' : [el.ini_str() for el in self.elements],
                'is_source' : str(self.is_source)}

    def __getitem__(self, key):
        if not isinstance(key, int):
            raise TypeError("VectorPort index must be integer")
        if key >= len(self.elements):
            # need to extend list
            ext = [VectorPortElementRef(
                    self.simobj, self.name, self.role, self.is_source, i)
                   for i in range(len(self.elements), key+1)]
            self.elements.extend(ext)
        return self.elements[key]

    def _get_next(self):
        return self[len(self.elements)]

    def __setitem__(self, key, value):
        if not isinstance(key, int):
            raise TypeError("VectorPort index must be integer")
        self[key].connect(value)

    def connect(self, other):
        if isinstance(other, (list, tuple)):
            # Assign list of port refs to vector port.
            # For now, append them... not sure if that's the right semantics
            # or if it should replace the current vector.
            for ref in other:
                self._get_next().connect(ref)
        else:
            # scalar assignment to plain VectorPort is implicit append
            self._get_next().connect(other)

    def clone(self, simobj, memo):
        if self in memo:
            return memo[self]
        newRef = copy.copy(self)
        memo[self] = newRef
        newRef.simobj = simobj
        assert(isSimObject(newRef.simobj))
        newRef.elements = [el.clone(simobj, memo) for el in self.elements]
        return newRef

    def unproxy(self, simobj):
        [el.unproxy(simobj) for el in self.elements]

    def ccConnect(self):
        [el.ccConnect() for el in self.elements]

# Port description object.  Like a ParamDesc object, this represents a
# logical port in the SimObject class, not a particular port on a
# SimObject instance.  The latter are represented by PortRef objects.
class Port(object):
    # Port("role", "description")

    _compat_dict = { }

    @classmethod
    def compat(cls, role, peer):
        cls._compat_dict.setdefault(role, set()).add(peer)
        cls._compat_dict.setdefault(peer, set()).add(role)

    @classmethod
    def is_compat(cls, one, two):
        for port in one, two:
            if not port.role in Port._compat_dict:
                fatal("Unrecognized role '%s' for port %s\n", port.role, port)
        return one.role in Port._compat_dict[two.role]

    def __init__(self, role, desc, is_source=False):
        self.desc = desc
        self.role = role
        self.is_source = is_source

    # Generate a PortRef for this port on the given SimObject with the
    # given name
    def makeRef(self, simobj):
        return PortRef(simobj, self.name, self.role, self.is_source)

    # Connect an instance of this port (on the given SimObject with
    # the given name) with the port described by the supplied PortRef
    def connect(self, simobj, ref):
        self.makeRef(simobj).connect(ref)

    # No need for any pre-declarations at the moment as we merely rely
    # on an unsigned int.
    def cxx_predecls(self, code):
        pass

    def pybind_predecls(self, code):
        cls.cxx_predecls(self, code)

    # Declare an unsigned int with the same name as the port, that
    # will eventually hold the number of connected ports (and thus the
    # number of elements for a VectorPort).
    def cxx_decl(self, code):
        code('unsigned int port_${{self.name}}_connection_count;')

Port.compat('GEM5 REQUESTOR', 'GEM5 RESPONDER')

class RequestPort(Port):
    # RequestPort("description")
    def __init__(self, desc):
        super().__init__('GEM5 REQUESTOR', desc, is_source=True)

class ResponsePort(Port):
    # ResponsePort("description")
    def __init__(self, desc):
        super().__init__('GEM5 RESPONDER', desc)

# VectorPort description object.  Like Port, but represents a vector
# of connections (e.g., as on a XBar).
class VectorPort(Port):
    def makeRef(self, simobj):
        return VectorPortRef(simobj, self.name, self.role, self.is_source)

class VectorRequestPort(VectorPort):
    # VectorRequestPort("description")
    def __init__(self, desc):
        super().__init__('GEM5 REQUESTOR', desc, is_source=True)

class VectorResponsePort(VectorPort):
    # VectorResponsePort("description")
    def __init__(self, desc):
        super().__init__('GEM5 RESPONDER', desc)

# Old names, maintained for compatibility.
MasterPort = RequestPort
SlavePort = ResponsePort
VectorMasterPort = VectorRequestPort
VectorSlavePort = VectorResponsePort

# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of
# proxy objects (via set_param_desc()) so that proxy error messages
# make sense.
class PortParamDesc(object, metaclass=Singleton):
    ptype_str = 'Port'
    ptype = Port

class DeprecatedParam(object):
    """A special type for deprecated parameter variable names.

    There are times when we need to change the name of parameter, but this
    breaks the external-facing python API used in configuration files. Using
    this "type" for a parameter will warn users that they are using the old
    name, but allow for backwards compatibility.

    Usage example:
    In the following example, the `time` parameter is changed to `delay`.

    ```
    class SomeDevice(SimObject):
        delay = Param.Latency('1ns', 'The time to wait before something')
        time = DeprecatedParam(delay, '`time` is now called `delay`')
    ```
    """

    def __init__(self, new_param, message=''):
        """new_param: the new parameter variable that users should be using
        instead of this parameter variable.
        message: an optional message to print when warning the user
        """
        self.message = message
        self.newParam = new_param
        # Note: We won't know the string variable names until later in the
        # SimObject initialization process. Note: we expect that the setters
        # will be called when the SimObject type (class) is initialized so
        # these variables should be filled in before the instance of the
        # SimObject with this parameter is constructed
        self._oldName = ''
        self._newName = ''

    @property
    def oldName(self):
        assert(self._oldName != '') # should already be set
        return self._oldName

    @oldName.setter
    def oldName(self, name):
        assert(self._oldName == '') # Cannot "re-set" this value
        self._oldName = name

    @property
    def newName(self):
        assert(self._newName != '') # should already be set
        return self._newName

    @newName.setter
    def newName(self, name):
        assert(self._newName == '') # Cannot "re-set" this value
        self._newName = name

    def printWarning(self, instance_name, simobj_name):
        """Issue a warning that this variable name should not be used.

        instance_name: str, the name of the instance used in python
        simobj_name: str, the name of the SimObject type
        """
        if not self.message:
            self.message = "See {} for more information".format(simobj_name)
        warn('{}.{} is deprecated. {}'.format(
            instance_name, self._oldName, self.message))

baseEnums = allEnums.copy()
baseParams = allParams.copy()

def clear():
    global allEnums, allParams

    allEnums = baseEnums.copy()
    allParams = baseParams.copy()

__all__ = ['Param', 'VectorParam',
           'Enum', 'ScopedEnum', 'Bool', 'String', 'Float',
           'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
           'Int32', 'UInt32', 'Int64', 'UInt64',
           'Counter', 'Addr', 'Tick', 'Percent',
           'TcpPort', 'UdpPort', 'EthernetAddr',
           'IpAddress', 'IpNetmask', 'IpWithPort',
           'MemorySize', 'MemorySize32',
           'Latency', 'Frequency', 'Clock', 'Voltage', 'Current', 'Energy',
           'Temperature',
           'NetworkBandwidth', 'MemoryBandwidth',
           'AddrRange',
           'MaxAddr', 'MaxTick', 'AllMemory',
           'Time',
           'NextEthernetAddr', 'NULL',
           'Port', 'RequestPort', 'ResponsePort', 'MasterPort', 'SlavePort',
           'VectorPort', 'VectorRequestPort', 'VectorResponsePort',
           'VectorMasterPort', 'VectorSlavePort',
           'DeprecatedParam',
           ]
