# 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(f"// Unhandled param type: {cls.__name__}")
        code(f"{ret} false;")

    # 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(f"extra unknown kwargs {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(
            f"'{type(self).__name__}' object has no attribute '{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(
            f"Not allowed to set {attr} on '{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(
                f"SimObject {value.get_name()} already has a parent"
                + " 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(f"Cycle detected enumerating params at {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(f"{dest} = {src};")
        code(f"{ret} true;")

    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(f"{ret} to_number({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(
                f"Can't convert object of type {type(value).__name__} to CheckedInt"
            )
        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(f"bool _ret = to_number({src}, _temp);")
        code("if (_ret)")
        code(f"    {dest} = Cycles(_temp);")
        code(f"{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(
                f"Can't convert object of type {type(value).__name__} to Float"
            )

    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(f"{ret} (std::istringstream({src}) >> {dest}).eof();")


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 f"0x{int(val):x}"


class PcCountPair(ParamValue):
    # This parameter stores a Program Counter address and the a count value for
    # the Program Counter address
    cxx_type = "PcCountPair"
    cmd_line_settable = True

    def __init__(self, _pc, _count):
        self.pc = _pc
        self.count = _count

    def get_pc(self):
        return self.pc

    def get_count(self):
        return self.count

    def getValue(self):
        #  convert Python PcCountPair into C++ PcCountPair
        from _m5.pc import PcCountPair

        return PcCountPair(self.pc, self.count)

    def __str__(self):
        return "(%i,%i)" % (self.pc, self.count)

    def __eq__(self, other):
        return self.pc == other.get_pc() and self.count == other.get_count()

    def __hash__(self):
        return hash((int(self.pc), int(self.count)))

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "cpu/probes/pc_count_pair.hh"')

    @classmethod
    def pybind_predecls(cls, code):
        code('#include "cpu/probes/pc_count_pair.hh"')


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(f"Too many keywords: {list(kwargs.keys())}")

    def __str__(self):
        if len(self.masks) == 0:
            return f"{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(f"{ret} to_bool({src}, {dest});")


class HostSocket(ParamValue):
    cxx_type = "ListenSocketConfig"

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

    def __init__(self, value):
        if isinstance(value, HostSocket):
            self.value = value.value
        else:
            self.value = value

    def getValue(self):
        from _m5.socket import listenSocketEmptyConfig
        from _m5.socket import listenSocketInetConfig
        from _m5.socket import listenSocketUnixFileConfig
        from _m5.socket import listenSocketUnixAbstractConfig

        if isinstance(self.value, str):
            if self.value[0] == "@":
                return listenSocketUnixAbstractConfig(self.value[1:])
            else:
                d, f = os.path.split(self.value)
                return listenSocketUnixFileConfig(d, f)
        else:
            if self.value == 0:
                return listenSocketEmptyConfig()
            else:
                return listenSocketInetConfig(self.value)

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

    def __str__(self):
        if isinstance(self.value, str):
            return self.value
        else:
            return "#" + str(self.value)

    def ini_str(self):
        if isinstance(self.value, str):
            if self.value[0] == "@":
                return self.value
            else:
                return "P" + self.value
        else:
            return "#" + str(self.value)

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

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code(f"{ret} ListenSocketConfig::parseIni({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: f"{x:02x}", 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(f"invalid ethernet address {value}")

        for byte in bytes:
            if not 0 <= int(byte, base=16) <= 0xFF:
                raise TypeError(f"invalid ethernet address {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(f"{dest} = networking::EthAddr({src});")
        code(f"{ret} true;")


# 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(f"No value set for {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(f"Too many keywords: {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(f"No value set for {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(f"Too many keywords: {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(f"Could not parse '{value}' as a time")


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 = f"{name}"
        else:
            cls.cxx_type = f"enums::{name}"

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


# 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(
                f"Enum param got bad value '{value}' (not in {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(f"{dest} = {name if cls.is_class else 'enums'}::{elem_name};")
            code(f"{ret} true;")
            code.dedent()
        code("} else {")
        code(f"    {ret} false;")
        code("}")

    def getValue(self):
        import m5.internal.params

        e = getattr(m5.internal.params, f"enum_{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(f"Latency object has no attribute '{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(f"Frequency object has no attribute '{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 f"{Latency(self)}"

    def __getattr__(self, attr):
        if attr == "frequency":
            return Frequency(self)
        if attr in ("latency", "period"):
            return Latency(self)
        raise AttributeError(f"Frequency object has no attribute '{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(f"bool _ret = to_number({src}, _temp);")
        code("if (_ret)")
        code(f"    {dest} = Temperature(_temp);")
        code(f"{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():f}"

    def config_value(self):
        return f"{self.getValue():f}"

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

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code(f"{ret} (std::istringstream({src}) >> {dest}).eof();")


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():f}"

    def config_value(self):
        return f"{self.getValue():f}"

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

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code(f"{ret} (std::istringstream({src}) >> {dest}).eof();")


#
# "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 f"{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(
            f"'{self.__class__.__name__}' object has no attribute '{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(
                f"assigning non-port reference '{other}' to port '{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(
                f"Splicing non-port references '{new_1}','{new_2}' to port '{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(
                    f"Error in unproxying port '{self.name}' of {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 f"{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 = f"See {simobj_name} for more information"
        warn(f"{instance_name}.{self._oldName} is deprecated. {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",
    "PcCountPair",
]
