params.py revision 14059
114049Snikos.nikoleris@arm.com# Copyright (c) 2012-2014, 2017-2019 ARM Limited 28839Sandreas.hansson@arm.com# All rights reserved. 38839Sandreas.hansson@arm.com# 48839Sandreas.hansson@arm.com# The license below extends only to copyright in the software and shall 58839Sandreas.hansson@arm.com# not be construed as granting a license to any other intellectual 68839Sandreas.hansson@arm.com# property including but not limited to intellectual property relating 78839Sandreas.hansson@arm.com# to a hardware implementation of the functionality of the software 88839Sandreas.hansson@arm.com# licensed hereunder. You may use the software subject to the license 98839Sandreas.hansson@arm.com# terms below provided that you ensure that this notice is replicated 108839Sandreas.hansson@arm.com# unmodified and in its entirety in all distributions of the software, 118839Sandreas.hansson@arm.com# modified or unmodified, in source code or in binary form. 128839Sandreas.hansson@arm.com# 133101Sstever@eecs.umich.edu# Copyright (c) 2004-2006 The Regents of The University of Michigan 148579Ssteve.reinhardt@amd.com# Copyright (c) 2010-2011 Advanced Micro Devices, Inc. 153101Sstever@eecs.umich.edu# All rights reserved. 163101Sstever@eecs.umich.edu# 173101Sstever@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 183101Sstever@eecs.umich.edu# modification, are permitted provided that the following conditions are 193101Sstever@eecs.umich.edu# met: redistributions of source code must retain the above copyright 203101Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 213101Sstever@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 223101Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 233101Sstever@eecs.umich.edu# documentation and/or other materials provided with the distribution; 243101Sstever@eecs.umich.edu# neither the name of the copyright holders nor the names of its 253101Sstever@eecs.umich.edu# contributors may be used to endorse or promote products derived from 263101Sstever@eecs.umich.edu# this software without specific prior written permission. 273101Sstever@eecs.umich.edu# 283101Sstever@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 293101Sstever@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 303101Sstever@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 313101Sstever@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 323101Sstever@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 333101Sstever@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 343101Sstever@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 353101Sstever@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 363101Sstever@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 373101Sstever@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 383101Sstever@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 393101Sstever@eecs.umich.edu# 403101Sstever@eecs.umich.edu# Authors: Steve Reinhardt 413101Sstever@eecs.umich.edu# Nathan Binkert 427778Sgblack@eecs.umich.edu# Gabe Black 438839Sandreas.hansson@arm.com# Andreas Hansson 443101Sstever@eecs.umich.edu 453101Sstever@eecs.umich.edu##################################################################### 463101Sstever@eecs.umich.edu# 473101Sstever@eecs.umich.edu# Parameter description classes 483101Sstever@eecs.umich.edu# 493101Sstever@eecs.umich.edu# The _params dictionary in each class maps parameter names to either 503101Sstever@eecs.umich.edu# a Param or a VectorParam object. These objects contain the 513101Sstever@eecs.umich.edu# parameter description string, the parameter type, and the default 523101Sstever@eecs.umich.edu# value (if any). The convert() method on these objects is used to 533101Sstever@eecs.umich.edu# force whatever value is assigned to the parameter to the appropriate 543101Sstever@eecs.umich.edu# type. 553101Sstever@eecs.umich.edu# 563101Sstever@eecs.umich.edu# Note that the default values are loaded into the class's attribute 573101Sstever@eecs.umich.edu# space when the parameter dictionary is initialized (in 583101Sstever@eecs.umich.edu# MetaSimObject._new_param()); after that point they aren't used. 593101Sstever@eecs.umich.edu# 603101Sstever@eecs.umich.edu##################################################################### 613101Sstever@eecs.umich.edu 6212563Sgabeblack@google.comfrom __future__ import print_function 6313719Sandreas.sandberg@arm.comimport six 6413719Sandreas.sandberg@arm.comif six.PY3: 6513719Sandreas.sandberg@arm.com long = int 6612563Sgabeblack@google.com 673885Sbinkertn@umich.eduimport copy 683885Sbinkertn@umich.eduimport datetime 694762Snate@binkert.orgimport re 703885Sbinkertn@umich.eduimport sys 713885Sbinkertn@umich.eduimport time 727528Ssteve.reinhardt@amd.comimport math 733885Sbinkertn@umich.edu 7413714Sandreas.sandberg@arm.comfrom . import proxy 7513714Sandreas.sandberg@arm.comfrom . import ticks 7613714Sandreas.sandberg@arm.comfrom .util import * 773101Sstever@eecs.umich.edu 784762Snate@binkert.orgdef isSimObject(*args, **kwargs): 7913716Sandreas.sandberg@arm.com from . import SimObject 804762Snate@binkert.org return SimObject.isSimObject(*args, **kwargs) 814762Snate@binkert.org 824762Snate@binkert.orgdef isSimObjectSequence(*args, **kwargs): 8313716Sandreas.sandberg@arm.com from . import SimObject 844762Snate@binkert.org return SimObject.isSimObjectSequence(*args, **kwargs) 854762Snate@binkert.org 864762Snate@binkert.orgdef isSimObjectClass(*args, **kwargs): 8713716Sandreas.sandberg@arm.com from . import SimObject 884762Snate@binkert.org return SimObject.isSimObjectClass(*args, **kwargs) 894762Snate@binkert.org 905033Smilesck@eecs.umich.eduallParams = {} 915033Smilesck@eecs.umich.edu 925033Smilesck@eecs.umich.educlass MetaParamValue(type): 935033Smilesck@eecs.umich.edu def __new__(mcls, name, bases, dct): 945033Smilesck@eecs.umich.edu cls = super(MetaParamValue, mcls).__new__(mcls, name, bases, dct) 955033Smilesck@eecs.umich.edu assert name not in allParams 965033Smilesck@eecs.umich.edu allParams[name] = cls 975033Smilesck@eecs.umich.edu return cls 985033Smilesck@eecs.umich.edu 995033Smilesck@eecs.umich.edu 1003101Sstever@eecs.umich.edu# Dummy base class to identify types that are legitimate for SimObject 1013101Sstever@eecs.umich.edu# parameters. 1023101Sstever@eecs.umich.educlass ParamValue(object): 1035033Smilesck@eecs.umich.edu __metaclass__ = MetaParamValue 10410267SGeoffrey.Blake@arm.com cmd_line_settable = False 1058596Ssteve.reinhardt@amd.com 1068596Ssteve.reinhardt@amd.com # Generate the code needed as a prerequisite for declaring a C++ 1078596Ssteve.reinhardt@amd.com # object of this type. Typically generates one or more #include 1088596Ssteve.reinhardt@amd.com # statements. Used when declaring parameters of this type. 1097673Snate@binkert.org @classmethod 1107673Snate@binkert.org def cxx_predecls(cls, code): 1117673Snate@binkert.org pass 1127673Snate@binkert.org 11311988Sandreas.sandberg@arm.com @classmethod 11411988Sandreas.sandberg@arm.com def pybind_predecls(cls, code): 11511988Sandreas.sandberg@arm.com cls.cxx_predecls(code) 11611988Sandreas.sandberg@arm.com 1173101Sstever@eecs.umich.edu # default for printing to .ini file is regular string conversion. 1183101Sstever@eecs.umich.edu # will be overridden in some cases 1193101Sstever@eecs.umich.edu def ini_str(self): 1203101Sstever@eecs.umich.edu return str(self) 1213101Sstever@eecs.umich.edu 12210380SAndrew.Bardsley@arm.com # default for printing to .json file is regular string conversion. 12310380SAndrew.Bardsley@arm.com # will be overridden in some cases, mostly to use native Python 12410380SAndrew.Bardsley@arm.com # types where there are similar JSON types 12510380SAndrew.Bardsley@arm.com def config_value(self): 12610380SAndrew.Bardsley@arm.com return str(self) 12710380SAndrew.Bardsley@arm.com 12810458Sandreas.hansson@arm.com # Prerequisites for .ini parsing with cxx_ini_parse 12910458Sandreas.hansson@arm.com @classmethod 13010458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 13110458Sandreas.hansson@arm.com pass 13210458Sandreas.hansson@arm.com 13310458Sandreas.hansson@arm.com # parse a .ini file entry for this param from string expression 13410458Sandreas.hansson@arm.com # src into lvalue dest (of the param's C++ type) 13510458Sandreas.hansson@arm.com @classmethod 13610458Sandreas.hansson@arm.com def cxx_ini_parse(cls, code, src, dest, ret): 13710458Sandreas.hansson@arm.com code('// Unhandled param type: %s' % cls.__name__) 13810458Sandreas.hansson@arm.com code('%s false;' % ret) 13910458Sandreas.hansson@arm.com 1403101Sstever@eecs.umich.edu # allows us to blithely call unproxy() on things without checking 1413101Sstever@eecs.umich.edu # if they're really proxies or not 1423101Sstever@eecs.umich.edu def unproxy(self, base): 1433101Sstever@eecs.umich.edu return self 1443101Sstever@eecs.umich.edu 14510267SGeoffrey.Blake@arm.com # Produce a human readable version of the stored value 14610267SGeoffrey.Blake@arm.com def pretty_print(self, value): 14710267SGeoffrey.Blake@arm.com return str(value) 14810267SGeoffrey.Blake@arm.com 1493101Sstever@eecs.umich.edu# Regular parameter description. 1503101Sstever@eecs.umich.educlass ParamDesc(object): 1513101Sstever@eecs.umich.edu def __init__(self, ptype_str, ptype, *args, **kwargs): 1523101Sstever@eecs.umich.edu self.ptype_str = ptype_str 1533101Sstever@eecs.umich.edu # remember ptype only if it is provided 1543101Sstever@eecs.umich.edu if ptype != None: 1553101Sstever@eecs.umich.edu self.ptype = ptype 1563101Sstever@eecs.umich.edu 1573101Sstever@eecs.umich.edu if args: 1583101Sstever@eecs.umich.edu if len(args) == 1: 1593101Sstever@eecs.umich.edu self.desc = args[0] 1603101Sstever@eecs.umich.edu elif len(args) == 2: 1613101Sstever@eecs.umich.edu self.default = args[0] 1623101Sstever@eecs.umich.edu self.desc = args[1] 1633101Sstever@eecs.umich.edu else: 16413663Sandreas.sandberg@arm.com raise TypeError('too many arguments') 1653101Sstever@eecs.umich.edu 16613675Sandreas.sandberg@arm.com if 'desc' in kwargs: 1673101Sstever@eecs.umich.edu assert(not hasattr(self, 'desc')) 1683101Sstever@eecs.umich.edu self.desc = kwargs['desc'] 1693101Sstever@eecs.umich.edu del kwargs['desc'] 1703101Sstever@eecs.umich.edu 17113675Sandreas.sandberg@arm.com if 'default' in kwargs: 1723101Sstever@eecs.umich.edu assert(not hasattr(self, 'default')) 1733101Sstever@eecs.umich.edu self.default = kwargs['default'] 1743101Sstever@eecs.umich.edu del kwargs['default'] 1753101Sstever@eecs.umich.edu 1763101Sstever@eecs.umich.edu if kwargs: 17713663Sandreas.sandberg@arm.com raise TypeError('extra unknown kwargs %s' % kwargs) 1783101Sstever@eecs.umich.edu 1793101Sstever@eecs.umich.edu if not hasattr(self, 'desc'): 18013663Sandreas.sandberg@arm.com raise TypeError('desc attribute missing') 1813101Sstever@eecs.umich.edu 1823101Sstever@eecs.umich.edu def __getattr__(self, attr): 1833101Sstever@eecs.umich.edu if attr == 'ptype': 18413716Sandreas.sandberg@arm.com from . import SimObject 1855033Smilesck@eecs.umich.edu ptype = SimObject.allClasses[self.ptype_str] 1866656Snate@binkert.org assert isSimObjectClass(ptype) 1875033Smilesck@eecs.umich.edu self.ptype = ptype 1885033Smilesck@eecs.umich.edu return ptype 1895033Smilesck@eecs.umich.edu 19013663Sandreas.sandberg@arm.com raise AttributeError("'%s' object has no attribute '%s'" % \ 19113663Sandreas.sandberg@arm.com (type(self).__name__, attr)) 1923101Sstever@eecs.umich.edu 19310267SGeoffrey.Blake@arm.com def example_str(self): 19410267SGeoffrey.Blake@arm.com if hasattr(self.ptype, "ex_str"): 19510267SGeoffrey.Blake@arm.com return self.ptype.ex_str 19610267SGeoffrey.Blake@arm.com else: 19710267SGeoffrey.Blake@arm.com return self.ptype_str 19810267SGeoffrey.Blake@arm.com 19910267SGeoffrey.Blake@arm.com # Is the param available to be exposed on the command line 20010267SGeoffrey.Blake@arm.com def isCmdLineSettable(self): 20110267SGeoffrey.Blake@arm.com if hasattr(self.ptype, "cmd_line_settable"): 20210267SGeoffrey.Blake@arm.com return self.ptype.cmd_line_settable 20310267SGeoffrey.Blake@arm.com else: 20410267SGeoffrey.Blake@arm.com return False 20510267SGeoffrey.Blake@arm.com 2063101Sstever@eecs.umich.edu def convert(self, value): 2073101Sstever@eecs.umich.edu if isinstance(value, proxy.BaseProxy): 2083101Sstever@eecs.umich.edu value.set_param_desc(self) 2093101Sstever@eecs.umich.edu return value 21013699Sandreas.sandberg@arm.com if 'ptype' not in self.__dict__ and isNullPointer(value): 2113101Sstever@eecs.umich.edu # deferred evaluation of SimObject; continue to defer if 2123101Sstever@eecs.umich.edu # we're just assigning a null pointer 2133101Sstever@eecs.umich.edu return value 2143101Sstever@eecs.umich.edu if isinstance(value, self.ptype): 2153101Sstever@eecs.umich.edu return value 2163102Sstever@eecs.umich.edu if isNullPointer(value) and isSimObjectClass(self.ptype): 2173101Sstever@eecs.umich.edu return value 2183101Sstever@eecs.umich.edu return self.ptype(value) 2193101Sstever@eecs.umich.edu 22010267SGeoffrey.Blake@arm.com def pretty_print(self, value): 22110267SGeoffrey.Blake@arm.com if isinstance(value, proxy.BaseProxy): 22210267SGeoffrey.Blake@arm.com return str(value) 22310267SGeoffrey.Blake@arm.com if isNullPointer(value): 22410267SGeoffrey.Blake@arm.com return NULL 22510267SGeoffrey.Blake@arm.com return self.ptype(value).pretty_print(value) 22610267SGeoffrey.Blake@arm.com 2277673Snate@binkert.org def cxx_predecls(self, code): 2288607Sgblack@eecs.umich.edu code('#include <cstddef>') 2297673Snate@binkert.org self.ptype.cxx_predecls(code) 2303101Sstever@eecs.umich.edu 23111988Sandreas.sandberg@arm.com def pybind_predecls(self, code): 23211988Sandreas.sandberg@arm.com self.ptype.pybind_predecls(code) 23311988Sandreas.sandberg@arm.com 2347673Snate@binkert.org def cxx_decl(self, code): 2357673Snate@binkert.org code('${{self.ptype.cxx_type}} ${{self.name}};') 2363101Sstever@eecs.umich.edu 2373101Sstever@eecs.umich.edu# Vector-valued parameter description. Just like ParamDesc, except 2383101Sstever@eecs.umich.edu# that the value is a vector (list) of the specified type instead of a 2393101Sstever@eecs.umich.edu# single value. 2403101Sstever@eecs.umich.edu 2413101Sstever@eecs.umich.educlass VectorParamValue(list): 2425033Smilesck@eecs.umich.edu __metaclass__ = MetaParamValue 2435475Snate@binkert.org def __setattr__(self, attr, value): 24413663Sandreas.sandberg@arm.com raise AttributeError("Not allowed to set %s on '%s'" % \ 24513663Sandreas.sandberg@arm.com (attr, type(self).__name__)) 2465475Snate@binkert.org 24710380SAndrew.Bardsley@arm.com def config_value(self): 24810380SAndrew.Bardsley@arm.com return [v.config_value() for v in self] 24910380SAndrew.Bardsley@arm.com 2503101Sstever@eecs.umich.edu def ini_str(self): 2513101Sstever@eecs.umich.edu return ' '.join([v.ini_str() for v in self]) 2523101Sstever@eecs.umich.edu 2534762Snate@binkert.org def getValue(self): 2544762Snate@binkert.org return [ v.getValue() for v in self ] 2554762Snate@binkert.org 2563101Sstever@eecs.umich.edu def unproxy(self, base): 25712050Snikos.nikoleris@arm.com if len(self) == 1 and isinstance(self[0], proxy.BaseProxy): 25812050Snikos.nikoleris@arm.com # The value is a proxy (e.g. Parent.any, Parent.all or 25912050Snikos.nikoleris@arm.com # Parent.x) therefore try resolve it 2608459SAli.Saidi@ARM.com return self[0].unproxy(base) 2618459SAli.Saidi@ARM.com else: 26212050Snikos.nikoleris@arm.com return [v.unproxy(base) for v in self] 2633101Sstever@eecs.umich.edu 2647528Ssteve.reinhardt@amd.comclass SimObjectVector(VectorParamValue): 2657528Ssteve.reinhardt@amd.com # support clone operation 2667528Ssteve.reinhardt@amd.com def __call__(self, **kwargs): 2677528Ssteve.reinhardt@amd.com return SimObjectVector([v(**kwargs) for v in self]) 2687528Ssteve.reinhardt@amd.com 2697528Ssteve.reinhardt@amd.com def clear_parent(self, old_parent): 2703101Sstever@eecs.umich.edu for v in self: 2717528Ssteve.reinhardt@amd.com v.clear_parent(old_parent) 2727528Ssteve.reinhardt@amd.com 2737528Ssteve.reinhardt@amd.com def set_parent(self, parent, name): 2747528Ssteve.reinhardt@amd.com if len(self) == 1: 2757528Ssteve.reinhardt@amd.com self[0].set_parent(parent, name) 2767528Ssteve.reinhardt@amd.com else: 2777528Ssteve.reinhardt@amd.com width = int(math.ceil(math.log(len(self))/math.log(10))) 2787528Ssteve.reinhardt@amd.com for i,v in enumerate(self): 2797528Ssteve.reinhardt@amd.com v.set_parent(parent, "%s%0*d" % (name, width, i)) 2807528Ssteve.reinhardt@amd.com 2818321Ssteve.reinhardt@amd.com def has_parent(self): 28212194Sgabeblack@google.com return any([e.has_parent() for e in self if not isNullPointer(e)]) 2837528Ssteve.reinhardt@amd.com 2847528Ssteve.reinhardt@amd.com # return 'cpu0 cpu1' etc. for print_ini() 2857528Ssteve.reinhardt@amd.com def get_name(self): 2867528Ssteve.reinhardt@amd.com return ' '.join([v._name for v in self]) 2877528Ssteve.reinhardt@amd.com 2887528Ssteve.reinhardt@amd.com # By iterating through the constituent members of the vector here 2897528Ssteve.reinhardt@amd.com # we can nicely handle iterating over all a SimObject's children 2907528Ssteve.reinhardt@amd.com # without having to provide lots of special functions on 2917528Ssteve.reinhardt@amd.com # SimObjectVector directly. 2927528Ssteve.reinhardt@amd.com def descendants(self): 2937528Ssteve.reinhardt@amd.com for v in self: 2947528Ssteve.reinhardt@amd.com for obj in v.descendants(): 2957528Ssteve.reinhardt@amd.com yield obj 2963101Sstever@eecs.umich.edu 2978664SAli.Saidi@ARM.com def get_config_as_dict(self): 2988664SAli.Saidi@ARM.com a = [] 2998664SAli.Saidi@ARM.com for v in self: 3008664SAli.Saidi@ARM.com a.append(v.get_config_as_dict()) 3018664SAli.Saidi@ARM.com return a 3028664SAli.Saidi@ARM.com 3039953Sgeoffrey.blake@arm.com # If we are replacing an item in the vector, make sure to set the 3049953Sgeoffrey.blake@arm.com # parent reference of the new SimObject to be the same as the parent 3059953Sgeoffrey.blake@arm.com # of the SimObject being replaced. Useful to have if we created 3069953Sgeoffrey.blake@arm.com # a SimObjectVector of temporary objects that will be modified later in 3079953Sgeoffrey.blake@arm.com # configuration scripts. 3089953Sgeoffrey.blake@arm.com def __setitem__(self, key, value): 3099953Sgeoffrey.blake@arm.com val = self[key] 3109953Sgeoffrey.blake@arm.com if value.has_parent(): 3119953Sgeoffrey.blake@arm.com warn("SimObject %s already has a parent" % value.get_name() +\ 3129953Sgeoffrey.blake@arm.com " that is being overwritten by a SimObjectVector") 3139953Sgeoffrey.blake@arm.com value.set_parent(val.get_parent(), val._name) 3149953Sgeoffrey.blake@arm.com super(SimObjectVector, self).__setitem__(key, value) 3159953Sgeoffrey.blake@arm.com 31610267SGeoffrey.Blake@arm.com # Enumerate the params of each member of the SimObject vector. Creates 31710267SGeoffrey.Blake@arm.com # strings that will allow indexing into the vector by the python code and 31810267SGeoffrey.Blake@arm.com # allow it to be specified on the command line. 31910267SGeoffrey.Blake@arm.com def enumerateParams(self, flags_dict = {}, 32010267SGeoffrey.Blake@arm.com cmd_line_str = "", 32110267SGeoffrey.Blake@arm.com access_str = ""): 32210267SGeoffrey.Blake@arm.com if hasattr(self, "_paramEnumed"): 32312563Sgabeblack@google.com print("Cycle detected enumerating params at %s?!" % (cmd_line_str)) 32410267SGeoffrey.Blake@arm.com else: 32510267SGeoffrey.Blake@arm.com x = 0 32610267SGeoffrey.Blake@arm.com for vals in self: 32710267SGeoffrey.Blake@arm.com # Each entry in the SimObjectVector should be an 32810267SGeoffrey.Blake@arm.com # instance of a SimObject 32910267SGeoffrey.Blake@arm.com flags_dict = vals.enumerateParams(flags_dict, 33010267SGeoffrey.Blake@arm.com cmd_line_str + "%d." % x, 33110267SGeoffrey.Blake@arm.com access_str + "[%d]." % x) 33210267SGeoffrey.Blake@arm.com x = x + 1 33310267SGeoffrey.Blake@arm.com 33410267SGeoffrey.Blake@arm.com return flags_dict 33510267SGeoffrey.Blake@arm.com 3363101Sstever@eecs.umich.educlass VectorParamDesc(ParamDesc): 3373101Sstever@eecs.umich.edu # Convert assigned value to appropriate type. If the RHS is not a 3383101Sstever@eecs.umich.edu # list or tuple, it generates a single-element list. 3393101Sstever@eecs.umich.edu def convert(self, value): 3403101Sstever@eecs.umich.edu if isinstance(value, (list, tuple)): 3413101Sstever@eecs.umich.edu # list: coerce each element into new list 3423101Sstever@eecs.umich.edu tmp_list = [ ParamDesc.convert(self, v) for v in value ] 34310364SGeoffrey.Blake@arm.com elif isinstance(value, str): 34410364SGeoffrey.Blake@arm.com # If input is a csv string 34510364SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.convert(self, v) \ 34610364SGeoffrey.Blake@arm.com for v in value.strip('[').strip(']').split(',') ] 3473101Sstever@eecs.umich.edu else: 3484762Snate@binkert.org # singleton: coerce to a single-element list 3494762Snate@binkert.org tmp_list = [ ParamDesc.convert(self, value) ] 3504762Snate@binkert.org 3514762Snate@binkert.org if isSimObjectSequence(tmp_list): 3527528Ssteve.reinhardt@amd.com return SimObjectVector(tmp_list) 3534762Snate@binkert.org else: 3544762Snate@binkert.org return VectorParamValue(tmp_list) 3554762Snate@binkert.org 35610267SGeoffrey.Blake@arm.com # Produce a human readable example string that describes 35710267SGeoffrey.Blake@arm.com # how to set this vector parameter in the absence of a default 35810267SGeoffrey.Blake@arm.com # value. 35910267SGeoffrey.Blake@arm.com def example_str(self): 36010267SGeoffrey.Blake@arm.com s = super(VectorParamDesc, self).example_str() 36110267SGeoffrey.Blake@arm.com help_str = "[" + s + "," + s + ", ...]" 36210267SGeoffrey.Blake@arm.com return help_str 36310267SGeoffrey.Blake@arm.com 36410267SGeoffrey.Blake@arm.com # Produce a human readable representation of the value of this vector param. 36510267SGeoffrey.Blake@arm.com def pretty_print(self, value): 36610267SGeoffrey.Blake@arm.com if isinstance(value, (list, tuple)): 36710267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.pretty_print(self, v) for v in value ] 36810267SGeoffrey.Blake@arm.com elif isinstance(value, str): 36910267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.pretty_print(self, v) for v in value.split(',') ] 37010267SGeoffrey.Blake@arm.com else: 37110267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.pretty_print(self, value) ] 37210267SGeoffrey.Blake@arm.com 37310267SGeoffrey.Blake@arm.com return tmp_list 37410267SGeoffrey.Blake@arm.com 37510267SGeoffrey.Blake@arm.com # This is a helper function for the new config system 37610267SGeoffrey.Blake@arm.com def __call__(self, value): 37710267SGeoffrey.Blake@arm.com if isinstance(value, (list, tuple)): 37810267SGeoffrey.Blake@arm.com # list: coerce each element into new list 37910267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.convert(self, v) for v in value ] 38010267SGeoffrey.Blake@arm.com elif isinstance(value, str): 38110267SGeoffrey.Blake@arm.com # If input is a csv string 38210364SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.convert(self, v) \ 38310364SGeoffrey.Blake@arm.com for v in value.strip('[').strip(']').split(',') ] 38410267SGeoffrey.Blake@arm.com else: 38510267SGeoffrey.Blake@arm.com # singleton: coerce to a single-element list 38610267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.convert(self, value) ] 38710267SGeoffrey.Blake@arm.com 38810267SGeoffrey.Blake@arm.com return VectorParamValue(tmp_list) 38910267SGeoffrey.Blake@arm.com 3907673Snate@binkert.org def cxx_predecls(self, code): 3917673Snate@binkert.org code('#include <vector>') 3927673Snate@binkert.org self.ptype.cxx_predecls(code) 3933101Sstever@eecs.umich.edu 39411988Sandreas.sandberg@arm.com def pybind_predecls(self, code): 39511988Sandreas.sandberg@arm.com code('#include <vector>') 39611988Sandreas.sandberg@arm.com self.ptype.pybind_predecls(code) 39711988Sandreas.sandberg@arm.com 3987673Snate@binkert.org def cxx_decl(self, code): 3997673Snate@binkert.org code('std::vector< ${{self.ptype.cxx_type}} > ${{self.name}};') 4003101Sstever@eecs.umich.edu 4013101Sstever@eecs.umich.educlass ParamFactory(object): 4023101Sstever@eecs.umich.edu def __init__(self, param_desc_class, ptype_str = None): 4033101Sstever@eecs.umich.edu self.param_desc_class = param_desc_class 4043101Sstever@eecs.umich.edu self.ptype_str = ptype_str 4053101Sstever@eecs.umich.edu 4063101Sstever@eecs.umich.edu def __getattr__(self, attr): 4073101Sstever@eecs.umich.edu if self.ptype_str: 4083101Sstever@eecs.umich.edu attr = self.ptype_str + '.' + attr 4093101Sstever@eecs.umich.edu return ParamFactory(self.param_desc_class, attr) 4103101Sstever@eecs.umich.edu 4113101Sstever@eecs.umich.edu # E.g., Param.Int(5, "number of widgets") 4123101Sstever@eecs.umich.edu def __call__(self, *args, **kwargs): 4133101Sstever@eecs.umich.edu ptype = None 4143101Sstever@eecs.umich.edu try: 4155033Smilesck@eecs.umich.edu ptype = allParams[self.ptype_str] 4165033Smilesck@eecs.umich.edu except KeyError: 4173101Sstever@eecs.umich.edu # if name isn't defined yet, assume it's a SimObject, and 4183101Sstever@eecs.umich.edu # try to resolve it later 4193101Sstever@eecs.umich.edu pass 4203101Sstever@eecs.umich.edu return self.param_desc_class(self.ptype_str, ptype, *args, **kwargs) 4213101Sstever@eecs.umich.edu 4223101Sstever@eecs.umich.eduParam = ParamFactory(ParamDesc) 4233101Sstever@eecs.umich.eduVectorParam = ParamFactory(VectorParamDesc) 4243101Sstever@eecs.umich.edu 4253101Sstever@eecs.umich.edu##################################################################### 4263101Sstever@eecs.umich.edu# 4273101Sstever@eecs.umich.edu# Parameter Types 4283101Sstever@eecs.umich.edu# 4293101Sstever@eecs.umich.edu# Though native Python types could be used to specify parameter types 4303101Sstever@eecs.umich.edu# (the 'ptype' field of the Param and VectorParam classes), it's more 4313101Sstever@eecs.umich.edu# flexible to define our own set of types. This gives us more control 4323101Sstever@eecs.umich.edu# over how Python expressions are converted to values (via the 4333101Sstever@eecs.umich.edu# __init__() constructor) and how these values are printed out (via 4343101Sstever@eecs.umich.edu# the __str__() conversion method). 4353101Sstever@eecs.umich.edu# 4363101Sstever@eecs.umich.edu##################################################################### 4373101Sstever@eecs.umich.edu 4383101Sstever@eecs.umich.edu# String-valued parameter. Just mixin the ParamValue class with the 4393101Sstever@eecs.umich.edu# built-in str class. 4403101Sstever@eecs.umich.educlass String(ParamValue,str): 4413101Sstever@eecs.umich.edu cxx_type = 'std::string' 44210267SGeoffrey.Blake@arm.com cmd_line_settable = True 4437673Snate@binkert.org 4447673Snate@binkert.org @classmethod 4457673Snate@binkert.org def cxx_predecls(self, code): 4467673Snate@binkert.org code('#include <string>') 4477673Snate@binkert.org 44810267SGeoffrey.Blake@arm.com def __call__(self, value): 44910267SGeoffrey.Blake@arm.com self = value 45010267SGeoffrey.Blake@arm.com return value 45110267SGeoffrey.Blake@arm.com 45210458Sandreas.hansson@arm.com @classmethod 45310458Sandreas.hansson@arm.com def cxx_ini_parse(self, code, src, dest, ret): 45410458Sandreas.hansson@arm.com code('%s = %s;' % (dest, src)) 45510458Sandreas.hansson@arm.com code('%s true;' % ret) 45610458Sandreas.hansson@arm.com 4574762Snate@binkert.org def getValue(self): 4584762Snate@binkert.org return self 4593101Sstever@eecs.umich.edu 4603101Sstever@eecs.umich.edu# superclass for "numeric" parameter values, to emulate math 4613101Sstever@eecs.umich.edu# operations in a type-safe way. e.g., a Latency times an int returns 4623101Sstever@eecs.umich.edu# a new Latency object. 4633101Sstever@eecs.umich.educlass NumericParamValue(ParamValue): 46413708Sandreas.sandberg@arm.com @staticmethod 46513708Sandreas.sandberg@arm.com def unwrap(v): 46613708Sandreas.sandberg@arm.com return v.value if isinstance(v, NumericParamValue) else v 46713708Sandreas.sandberg@arm.com 4683101Sstever@eecs.umich.edu def __str__(self): 4693101Sstever@eecs.umich.edu return str(self.value) 4703101Sstever@eecs.umich.edu 4713101Sstever@eecs.umich.edu def __float__(self): 4723101Sstever@eecs.umich.edu return float(self.value) 4733101Sstever@eecs.umich.edu 4743714Sstever@eecs.umich.edu def __long__(self): 4753714Sstever@eecs.umich.edu return long(self.value) 4763714Sstever@eecs.umich.edu 4773714Sstever@eecs.umich.edu def __int__(self): 4783714Sstever@eecs.umich.edu return int(self.value) 4793714Sstever@eecs.umich.edu 4803101Sstever@eecs.umich.edu # hook for bounds checking 4813101Sstever@eecs.umich.edu def _check(self): 4823101Sstever@eecs.umich.edu return 4833101Sstever@eecs.umich.edu 4843101Sstever@eecs.umich.edu def __mul__(self, other): 4853101Sstever@eecs.umich.edu newobj = self.__class__(self) 48613708Sandreas.sandberg@arm.com newobj.value *= NumericParamValue.unwrap(other) 4873101Sstever@eecs.umich.edu newobj._check() 4883101Sstever@eecs.umich.edu return newobj 4893101Sstever@eecs.umich.edu 4903101Sstever@eecs.umich.edu __rmul__ = __mul__ 4913101Sstever@eecs.umich.edu 49213708Sandreas.sandberg@arm.com def __truediv__(self, other): 4933101Sstever@eecs.umich.edu newobj = self.__class__(self) 49413708Sandreas.sandberg@arm.com newobj.value /= NumericParamValue.unwrap(other) 49513708Sandreas.sandberg@arm.com newobj._check() 49613708Sandreas.sandberg@arm.com return newobj 49713708Sandreas.sandberg@arm.com 49813708Sandreas.sandberg@arm.com def __floordiv__(self, other): 49913708Sandreas.sandberg@arm.com newobj = self.__class__(self) 50013708Sandreas.sandberg@arm.com newobj.value //= NumericParamValue.unwrap(other) 50113708Sandreas.sandberg@arm.com newobj._check() 50213708Sandreas.sandberg@arm.com return newobj 50313708Sandreas.sandberg@arm.com 50413708Sandreas.sandberg@arm.com 50513708Sandreas.sandberg@arm.com def __add__(self, other): 50613708Sandreas.sandberg@arm.com newobj = self.__class__(self) 50713708Sandreas.sandberg@arm.com newobj.value += NumericParamValue.unwrap(other) 5083101Sstever@eecs.umich.edu newobj._check() 5093101Sstever@eecs.umich.edu return newobj 5103101Sstever@eecs.umich.edu 5113101Sstever@eecs.umich.edu def __sub__(self, other): 5123101Sstever@eecs.umich.edu newobj = self.__class__(self) 51313708Sandreas.sandberg@arm.com newobj.value -= NumericParamValue.unwrap(other) 5143101Sstever@eecs.umich.edu newobj._check() 5153101Sstever@eecs.umich.edu return newobj 5163101Sstever@eecs.umich.edu 51713708Sandreas.sandberg@arm.com def __iadd__(self, other): 51813708Sandreas.sandberg@arm.com self.value += NumericParamValue.unwrap(other) 51913708Sandreas.sandberg@arm.com self._check() 52013708Sandreas.sandberg@arm.com return self 52113708Sandreas.sandberg@arm.com 52213708Sandreas.sandberg@arm.com def __isub__(self, other): 52313708Sandreas.sandberg@arm.com self.value -= NumericParamValue.unwrap(other) 52413708Sandreas.sandberg@arm.com self._check() 52513708Sandreas.sandberg@arm.com return self 52613708Sandreas.sandberg@arm.com 52713708Sandreas.sandberg@arm.com def __imul__(self, other): 52813708Sandreas.sandberg@arm.com self.value *= NumericParamValue.unwrap(other) 52913708Sandreas.sandberg@arm.com self._check() 53013708Sandreas.sandberg@arm.com return self 53113708Sandreas.sandberg@arm.com 53213708Sandreas.sandberg@arm.com def __itruediv__(self, other): 53313708Sandreas.sandberg@arm.com self.value /= NumericParamValue.unwrap(other) 53413708Sandreas.sandberg@arm.com self._check() 53513708Sandreas.sandberg@arm.com return self 53613708Sandreas.sandberg@arm.com 53713708Sandreas.sandberg@arm.com def __ifloordiv__(self, other): 53813708Sandreas.sandberg@arm.com self.value //= NumericParamValue.unwrap(other) 53913708Sandreas.sandberg@arm.com self._check() 54013708Sandreas.sandberg@arm.com return self 54113708Sandreas.sandberg@arm.com 54213708Sandreas.sandberg@arm.com def __lt__(self, other): 54313708Sandreas.sandberg@arm.com return self.value < NumericParamValue.unwrap(other) 54413708Sandreas.sandberg@arm.com 54513708Sandreas.sandberg@arm.com # Python 2.7 pre __future__.division operators 54613708Sandreas.sandberg@arm.com # TODO: Remove these when after "import division from __future__" 54713708Sandreas.sandberg@arm.com __div__ = __truediv__ 54813708Sandreas.sandberg@arm.com __idiv__ = __itruediv__ 54913708Sandreas.sandberg@arm.com 55010380SAndrew.Bardsley@arm.com def config_value(self): 55110380SAndrew.Bardsley@arm.com return self.value 55210380SAndrew.Bardsley@arm.com 55310458Sandreas.hansson@arm.com @classmethod 55410458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 55510458Sandreas.hansson@arm.com # Assume that base/str.hh will be included anyway 55610458Sandreas.hansson@arm.com # code('#include "base/str.hh"') 55710458Sandreas.hansson@arm.com pass 55810458Sandreas.hansson@arm.com 55910458Sandreas.hansson@arm.com # The default for parsing PODs from an .ini entry is to extract from an 56010458Sandreas.hansson@arm.com # istringstream and let overloading choose the right type according to 56110458Sandreas.hansson@arm.com # the dest type. 56210458Sandreas.hansson@arm.com @classmethod 56310458Sandreas.hansson@arm.com def cxx_ini_parse(self, code, src, dest, ret): 56410458Sandreas.hansson@arm.com code('%s to_number(%s, %s);' % (ret, src, dest)) 56510458Sandreas.hansson@arm.com 5663101Sstever@eecs.umich.edu# Metaclass for bounds-checked integer parameters. See CheckedInt. 5675033Smilesck@eecs.umich.educlass CheckedIntType(MetaParamValue): 5683101Sstever@eecs.umich.edu def __init__(cls, name, bases, dict): 5693101Sstever@eecs.umich.edu super(CheckedIntType, cls).__init__(name, bases, dict) 5703101Sstever@eecs.umich.edu 5713101Sstever@eecs.umich.edu # CheckedInt is an abstract base class, so we actually don't 5723101Sstever@eecs.umich.edu # want to do any processing on it... the rest of this code is 5733101Sstever@eecs.umich.edu # just for classes that derive from CheckedInt. 5743101Sstever@eecs.umich.edu if name == 'CheckedInt': 5753101Sstever@eecs.umich.edu return 5763101Sstever@eecs.umich.edu 5773101Sstever@eecs.umich.edu if not (hasattr(cls, 'min') and hasattr(cls, 'max')): 5783101Sstever@eecs.umich.edu if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')): 5793101Sstever@eecs.umich.edu panic("CheckedInt subclass %s must define either\n" \ 5805822Ssaidi@eecs.umich.edu " 'min' and 'max' or 'size' and 'unsigned'\n", 5815822Ssaidi@eecs.umich.edu name); 5823101Sstever@eecs.umich.edu if cls.unsigned: 5833101Sstever@eecs.umich.edu cls.min = 0 5843101Sstever@eecs.umich.edu cls.max = 2 ** cls.size - 1 5853101Sstever@eecs.umich.edu else: 5863101Sstever@eecs.umich.edu cls.min = -(2 ** (cls.size - 1)) 5873101Sstever@eecs.umich.edu cls.max = (2 ** (cls.size - 1)) - 1 5883101Sstever@eecs.umich.edu 5893101Sstever@eecs.umich.edu# Abstract superclass for bounds-checked integer parameters. This 5903101Sstever@eecs.umich.edu# class is subclassed to generate parameter classes with specific 5913101Sstever@eecs.umich.edu# bounds. Initialization of the min and max bounds is done in the 5923101Sstever@eecs.umich.edu# metaclass CheckedIntType.__init__. 5933101Sstever@eecs.umich.educlass CheckedInt(NumericParamValue): 5943101Sstever@eecs.umich.edu __metaclass__ = CheckedIntType 59510267SGeoffrey.Blake@arm.com cmd_line_settable = True 5963101Sstever@eecs.umich.edu 5973101Sstever@eecs.umich.edu def _check(self): 5983101Sstever@eecs.umich.edu if not self.min <= self.value <= self.max: 59913663Sandreas.sandberg@arm.com raise TypeError('Integer param out of bounds %d < %d < %d' % \ 60013663Sandreas.sandberg@arm.com (self.min, self.value, self.max)) 6013101Sstever@eecs.umich.edu 6023101Sstever@eecs.umich.edu def __init__(self, value): 6033101Sstever@eecs.umich.edu if isinstance(value, str): 6043102Sstever@eecs.umich.edu self.value = convert.toInteger(value) 6053714Sstever@eecs.umich.edu elif isinstance(value, (int, long, float, NumericParamValue)): 6063101Sstever@eecs.umich.edu self.value = long(value) 6073714Sstever@eecs.umich.edu else: 60813663Sandreas.sandberg@arm.com raise TypeError("Can't convert object of type %s to CheckedInt" \ 60913663Sandreas.sandberg@arm.com % type(value).__name__) 6103101Sstever@eecs.umich.edu self._check() 6113101Sstever@eecs.umich.edu 61210267SGeoffrey.Blake@arm.com def __call__(self, value): 61310267SGeoffrey.Blake@arm.com self.__init__(value) 61410267SGeoffrey.Blake@arm.com return value 61510267SGeoffrey.Blake@arm.com 61613711Sandreas.sandberg@arm.com def __index__(self): 61713711Sandreas.sandberg@arm.com return int(self.value) 61813711Sandreas.sandberg@arm.com 6197673Snate@binkert.org @classmethod 6207673Snate@binkert.org def cxx_predecls(cls, code): 6217673Snate@binkert.org # most derived types require this, so we just do it here once 6227673Snate@binkert.org code('#include "base/types.hh"') 6237673Snate@binkert.org 6244762Snate@binkert.org def getValue(self): 6254762Snate@binkert.org return long(self.value) 6264762Snate@binkert.org 6273101Sstever@eecs.umich.educlass Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False 6283101Sstever@eecs.umich.educlass Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True 6293101Sstever@eecs.umich.edu 6303101Sstever@eecs.umich.educlass Int8(CheckedInt): cxx_type = 'int8_t'; size = 8; unsigned = False 6313101Sstever@eecs.umich.educlass UInt8(CheckedInt): cxx_type = 'uint8_t'; size = 8; unsigned = True 6323101Sstever@eecs.umich.educlass Int16(CheckedInt): cxx_type = 'int16_t'; size = 16; unsigned = False 6333101Sstever@eecs.umich.educlass UInt16(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 6343101Sstever@eecs.umich.educlass Int32(CheckedInt): cxx_type = 'int32_t'; size = 32; unsigned = False 6353101Sstever@eecs.umich.educlass UInt32(CheckedInt): cxx_type = 'uint32_t'; size = 32; unsigned = True 6363101Sstever@eecs.umich.educlass Int64(CheckedInt): cxx_type = 'int64_t'; size = 64; unsigned = False 6373101Sstever@eecs.umich.educlass UInt64(CheckedInt): cxx_type = 'uint64_t'; size = 64; unsigned = True 6383101Sstever@eecs.umich.edu 6393101Sstever@eecs.umich.educlass Counter(CheckedInt): cxx_type = 'Counter'; size = 64; unsigned = True 6403101Sstever@eecs.umich.educlass Tick(CheckedInt): cxx_type = 'Tick'; size = 64; unsigned = True 6413101Sstever@eecs.umich.educlass TcpPort(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 6423101Sstever@eecs.umich.educlass UdpPort(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 6433101Sstever@eecs.umich.edu 6443101Sstever@eecs.umich.educlass Percent(CheckedInt): cxx_type = 'int'; min = 0; max = 100 6453101Sstever@eecs.umich.edu 6469184Sandreas.hansson@arm.comclass Cycles(CheckedInt): 6479184Sandreas.hansson@arm.com cxx_type = 'Cycles' 6489184Sandreas.hansson@arm.com size = 64 6499184Sandreas.hansson@arm.com unsigned = True 6509184Sandreas.hansson@arm.com 6519184Sandreas.hansson@arm.com def getValue(self): 65211802Sandreas.sandberg@arm.com from _m5.core import Cycles 6539184Sandreas.hansson@arm.com return Cycles(self.value) 6549184Sandreas.hansson@arm.com 65510458Sandreas.hansson@arm.com @classmethod 65610458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 65710458Sandreas.hansson@arm.com # Assume that base/str.hh will be included anyway 65810458Sandreas.hansson@arm.com # code('#include "base/str.hh"') 65910458Sandreas.hansson@arm.com pass 66010458Sandreas.hansson@arm.com 66110458Sandreas.hansson@arm.com @classmethod 66210458Sandreas.hansson@arm.com def cxx_ini_parse(cls, code, src, dest, ret): 66310458Sandreas.hansson@arm.com code('uint64_t _temp;') 66410458Sandreas.hansson@arm.com code('bool _ret = to_number(%s, _temp);' % src) 66510458Sandreas.hansson@arm.com code('if (_ret)') 66610458Sandreas.hansson@arm.com code(' %s = Cycles(_temp);' % dest) 66710458Sandreas.hansson@arm.com code('%s _ret;' % ret) 66810458Sandreas.hansson@arm.com 6693101Sstever@eecs.umich.educlass Float(ParamValue, float): 6704446Sbinkertn@umich.edu cxx_type = 'double' 67110668SGeoffrey.Blake@arm.com cmd_line_settable = True 6723101Sstever@eecs.umich.edu 6735468Snate@binkert.org def __init__(self, value): 67410267SGeoffrey.Blake@arm.com if isinstance(value, (int, long, float, NumericParamValue, Float, str)): 6755468Snate@binkert.org self.value = float(value) 6765468Snate@binkert.org else: 67713663Sandreas.sandberg@arm.com raise TypeError("Can't convert object of type %s to Float" \ 67813663Sandreas.sandberg@arm.com % type(value).__name__) 6795468Snate@binkert.org 68010267SGeoffrey.Blake@arm.com def __call__(self, value): 68110267SGeoffrey.Blake@arm.com self.__init__(value) 68210267SGeoffrey.Blake@arm.com return value 68310267SGeoffrey.Blake@arm.com 6844762Snate@binkert.org def getValue(self): 6854762Snate@binkert.org return float(self.value) 6864762Snate@binkert.org 68710380SAndrew.Bardsley@arm.com def config_value(self): 68810380SAndrew.Bardsley@arm.com return self 68910380SAndrew.Bardsley@arm.com 69010458Sandreas.hansson@arm.com @classmethod 69110458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 69210458Sandreas.hansson@arm.com code('#include <sstream>') 69310458Sandreas.hansson@arm.com 69410458Sandreas.hansson@arm.com @classmethod 69510458Sandreas.hansson@arm.com def cxx_ini_parse(self, code, src, dest, ret): 69610458Sandreas.hansson@arm.com code('%s (std::istringstream(%s) >> %s).eof();' % (ret, src, dest)) 69710458Sandreas.hansson@arm.com 6983101Sstever@eecs.umich.educlass MemorySize(CheckedInt): 6993101Sstever@eecs.umich.edu cxx_type = 'uint64_t' 70010267SGeoffrey.Blake@arm.com ex_str = '512MB' 7013101Sstever@eecs.umich.edu size = 64 7023101Sstever@eecs.umich.edu unsigned = True 7033101Sstever@eecs.umich.edu def __init__(self, value): 7043101Sstever@eecs.umich.edu if isinstance(value, MemorySize): 7053101Sstever@eecs.umich.edu self.value = value.value 7063101Sstever@eecs.umich.edu else: 7073102Sstever@eecs.umich.edu self.value = convert.toMemorySize(value) 7083101Sstever@eecs.umich.edu self._check() 7093101Sstever@eecs.umich.edu 7103101Sstever@eecs.umich.educlass MemorySize32(CheckedInt): 7114168Sbinkertn@umich.edu cxx_type = 'uint32_t' 71210267SGeoffrey.Blake@arm.com ex_str = '512MB' 7133101Sstever@eecs.umich.edu size = 32 7143101Sstever@eecs.umich.edu unsigned = True 7153101Sstever@eecs.umich.edu def __init__(self, value): 7163101Sstever@eecs.umich.edu if isinstance(value, MemorySize): 7173101Sstever@eecs.umich.edu self.value = value.value 7183101Sstever@eecs.umich.edu else: 7193102Sstever@eecs.umich.edu self.value = convert.toMemorySize(value) 7203101Sstever@eecs.umich.edu self._check() 7213101Sstever@eecs.umich.edu 7223101Sstever@eecs.umich.educlass Addr(CheckedInt): 7233101Sstever@eecs.umich.edu cxx_type = 'Addr' 7243101Sstever@eecs.umich.edu size = 64 7253101Sstever@eecs.umich.edu unsigned = True 7263101Sstever@eecs.umich.edu def __init__(self, value): 7273101Sstever@eecs.umich.edu if isinstance(value, Addr): 7283101Sstever@eecs.umich.edu self.value = value.value 7293101Sstever@eecs.umich.edu else: 7303101Sstever@eecs.umich.edu try: 73110317Smitch.hayenga@arm.com # Often addresses are referred to with sizes. Ex: A device 73210317Smitch.hayenga@arm.com # base address is at "512MB". Use toMemorySize() to convert 73310317Smitch.hayenga@arm.com # these into addresses. If the address is not specified with a 73410317Smitch.hayenga@arm.com # "size", an exception will occur and numeric translation will 73510317Smitch.hayenga@arm.com # proceed below. 7363102Sstever@eecs.umich.edu self.value = convert.toMemorySize(value) 73710317Smitch.hayenga@arm.com except (TypeError, ValueError): 73810317Smitch.hayenga@arm.com # Convert number to string and use long() to do automatic 73910317Smitch.hayenga@arm.com # base conversion (requires base=0 for auto-conversion) 74010317Smitch.hayenga@arm.com self.value = long(str(value), base=0) 74110317Smitch.hayenga@arm.com 7423101Sstever@eecs.umich.edu self._check() 7433584Ssaidi@eecs.umich.edu def __add__(self, other): 7443584Ssaidi@eecs.umich.edu if isinstance(other, Addr): 7453584Ssaidi@eecs.umich.edu return self.value + other.value 7463584Ssaidi@eecs.umich.edu else: 7473584Ssaidi@eecs.umich.edu return self.value + other 74810267SGeoffrey.Blake@arm.com def pretty_print(self, value): 74910267SGeoffrey.Blake@arm.com try: 75010267SGeoffrey.Blake@arm.com val = convert.toMemorySize(value) 75110267SGeoffrey.Blake@arm.com except TypeError: 75210267SGeoffrey.Blake@arm.com val = long(value) 75310267SGeoffrey.Blake@arm.com return "0x%x" % long(val) 7543101Sstever@eecs.umich.edu 7559232Sandreas.hansson@arm.comclass AddrRange(ParamValue): 7569235Sandreas.hansson@arm.com cxx_type = 'AddrRange' 7573101Sstever@eecs.umich.edu 7583101Sstever@eecs.umich.edu def __init__(self, *args, **kwargs): 75910676Sandreas.hansson@arm.com # Disable interleaving and hashing by default 7609411Sandreas.hansson@arm.com self.intlvBits = 0 7619411Sandreas.hansson@arm.com self.intlvMatch = 0 76214049Snikos.nikoleris@arm.com self.masks = [] 7639411Sandreas.hansson@arm.com 7643101Sstever@eecs.umich.edu def handle_kwargs(self, kwargs): 7659411Sandreas.hansson@arm.com # An address range needs to have an upper limit, specified 7669411Sandreas.hansson@arm.com # either explicitly with an end, or as an offset using the 7679411Sandreas.hansson@arm.com # size keyword. 7683101Sstever@eecs.umich.edu if 'end' in kwargs: 7699232Sandreas.hansson@arm.com self.end = Addr(kwargs.pop('end')) 7703101Sstever@eecs.umich.edu elif 'size' in kwargs: 7719232Sandreas.hansson@arm.com self.end = self.start + Addr(kwargs.pop('size')) - 1 7723101Sstever@eecs.umich.edu else: 77313663Sandreas.sandberg@arm.com raise TypeError("Either end or size must be specified") 7743101Sstever@eecs.umich.edu 7759411Sandreas.hansson@arm.com # Now on to the optional bit 7769411Sandreas.hansson@arm.com if 'intlvMatch' in kwargs: 7779411Sandreas.hansson@arm.com self.intlvMatch = int(kwargs.pop('intlvMatch')) 7789411Sandreas.hansson@arm.com 77914049Snikos.nikoleris@arm.com if 'masks' in kwargs: 78014049Snikos.nikoleris@arm.com self.masks = [ long(x) for x in list(kwargs.pop('masks')) ] 78114049Snikos.nikoleris@arm.com self.intlvBits = len(self.masks) 78214049Snikos.nikoleris@arm.com else: 78314049Snikos.nikoleris@arm.com if 'intlvBits' in kwargs: 78414049Snikos.nikoleris@arm.com self.intlvBits = int(kwargs.pop('intlvBits')) 78514049Snikos.nikoleris@arm.com self.masks = [0] * self.intlvBits 78614059Snikos.nikoleris@arm.com if 'intlvHighBit' not in kwargs: 78714059Snikos.nikoleris@arm.com raise TypeError("No interleave bits specified") 78814059Snikos.nikoleris@arm.com intlv_high_bit = int(kwargs.pop('intlvHighBit')) 78914059Snikos.nikoleris@arm.com xor_high_bit = 0 79014059Snikos.nikoleris@arm.com if 'xorHighBit' in kwargs: 79114059Snikos.nikoleris@arm.com xor_high_bit = int(kwargs.pop('xorHighBit')) 79214059Snikos.nikoleris@arm.com for i in range(0, self.intlvBits): 79314059Snikos.nikoleris@arm.com bit1 = intlv_high_bit - i 79414059Snikos.nikoleris@arm.com mask = 1 << bit1 79514059Snikos.nikoleris@arm.com if xor_high_bit != 0: 79614059Snikos.nikoleris@arm.com bit2 = xor_high_bit - i 79714059Snikos.nikoleris@arm.com mask |= 1 << bit2 79814059Snikos.nikoleris@arm.com self.masks[self.intlvBits - i - 1] = mask 79914049Snikos.nikoleris@arm.com 8003101Sstever@eecs.umich.edu if len(args) == 0: 8019232Sandreas.hansson@arm.com self.start = Addr(kwargs.pop('start')) 8023101Sstever@eecs.umich.edu handle_kwargs(self, kwargs) 8033101Sstever@eecs.umich.edu 8043101Sstever@eecs.umich.edu elif len(args) == 1: 8053101Sstever@eecs.umich.edu if kwargs: 8069232Sandreas.hansson@arm.com self.start = Addr(args[0]) 8073101Sstever@eecs.umich.edu handle_kwargs(self, kwargs) 8085219Ssaidi@eecs.umich.edu elif isinstance(args[0], (list, tuple)): 8099232Sandreas.hansson@arm.com self.start = Addr(args[0][0]) 8109232Sandreas.hansson@arm.com self.end = Addr(args[0][1]) 8113101Sstever@eecs.umich.edu else: 8129232Sandreas.hansson@arm.com self.start = Addr(0) 8139232Sandreas.hansson@arm.com self.end = Addr(args[0]) - 1 8143101Sstever@eecs.umich.edu 8153101Sstever@eecs.umich.edu elif len(args) == 2: 8169232Sandreas.hansson@arm.com self.start = Addr(args[0]) 8179232Sandreas.hansson@arm.com self.end = Addr(args[1]) 8183101Sstever@eecs.umich.edu else: 81913663Sandreas.sandberg@arm.com raise TypeError("Too many arguments specified") 8203101Sstever@eecs.umich.edu 8213101Sstever@eecs.umich.edu if kwargs: 82213663Sandreas.sandberg@arm.com raise TypeError("Too many keywords: %s" % list(kwargs.keys())) 8233101Sstever@eecs.umich.edu 8243101Sstever@eecs.umich.edu def __str__(self): 82514049Snikos.nikoleris@arm.com if len(self.masks) == 0: 82614049Snikos.nikoleris@arm.com return '%s:%s' % (self.start, self.end) 82714049Snikos.nikoleris@arm.com else: 82814049Snikos.nikoleris@arm.com return '%s:%s:%s:%s' % (self.start, self.end, self.intlvMatch, 82914049Snikos.nikoleris@arm.com ':'.join(str(m) for m in self.masks)) 8309232Sandreas.hansson@arm.com 8319232Sandreas.hansson@arm.com def size(self): 8329411Sandreas.hansson@arm.com # Divide the size by the size of the interleaving slice 8339411Sandreas.hansson@arm.com return (long(self.end) - long(self.start) + 1) >> self.intlvBits 8343101Sstever@eecs.umich.edu 8357673Snate@binkert.org @classmethod 8367673Snate@binkert.org def cxx_predecls(cls, code): 8379232Sandreas.hansson@arm.com Addr.cxx_predecls(code) 8389235Sandreas.hansson@arm.com code('#include "base/addr_range.hh"') 8397675Snate@binkert.org 8407675Snate@binkert.org @classmethod 84111988Sandreas.sandberg@arm.com def pybind_predecls(cls, code): 84211988Sandreas.sandberg@arm.com Addr.pybind_predecls(code) 84311988Sandreas.sandberg@arm.com code('#include "base/addr_range.hh"') 84411988Sandreas.sandberg@arm.com 84511988Sandreas.sandberg@arm.com @classmethod 84610458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 84710458Sandreas.hansson@arm.com code('#include <sstream>') 84814049Snikos.nikoleris@arm.com code('#include <vector>') 84914049Snikos.nikoleris@arm.com code('#include "base/types.hh"') 85010458Sandreas.hansson@arm.com 85110458Sandreas.hansson@arm.com @classmethod 85210458Sandreas.hansson@arm.com def cxx_ini_parse(cls, code, src, dest, ret): 85314049Snikos.nikoleris@arm.com code('bool _ret = true;') 85414049Snikos.nikoleris@arm.com code('uint64_t _start, _end, _intlvMatch = 0;') 85514049Snikos.nikoleris@arm.com code('std::vector<Addr> _masks;') 85610458Sandreas.hansson@arm.com code('char _sep;') 85710458Sandreas.hansson@arm.com code('std::istringstream _stream(${src});') 85810458Sandreas.hansson@arm.com code('_stream >> _start;') 85910458Sandreas.hansson@arm.com code('_stream.get(_sep);') 86014049Snikos.nikoleris@arm.com code('_ret = _sep == \':\';') 86110458Sandreas.hansson@arm.com code('_stream >> _end;') 86211620SMatthew.Poremba@amd.com code('if (!_stream.fail() && !_stream.eof()) {') 86311620SMatthew.Poremba@amd.com code(' _stream.get(_sep);') 86414049Snikos.nikoleris@arm.com code(' _ret = ret && _sep == \':\';') 86511620SMatthew.Poremba@amd.com code(' _stream >> _intlvMatch;') 86614049Snikos.nikoleris@arm.com code(' while (!_stream.fail() && !_stream.eof()) {') 86714049Snikos.nikoleris@arm.com code(' _stream.get(_sep);') 86814049Snikos.nikoleris@arm.com code(' _ret = ret && _sep == \':\';') 86914049Snikos.nikoleris@arm.com code(' Addr mask;') 87014049Snikos.nikoleris@arm.com code(' _stream >> mask;') 87114049Snikos.nikoleris@arm.com code(' _masks.push_back(mask);') 87214049Snikos.nikoleris@arm.com code(' }') 87311620SMatthew.Poremba@amd.com code('}') 87414049Snikos.nikoleris@arm.com code('_ret = _ret && !_stream.fail() && _stream.eof();') 87510458Sandreas.hansson@arm.com code('if (_ret)') 87614049Snikos.nikoleris@arm.com code(' ${dest} = AddrRange(_start, _end, _masks, _intlvMatch);') 87710458Sandreas.hansson@arm.com code('${ret} _ret;') 87810458Sandreas.hansson@arm.com 8794762Snate@binkert.org def getValue(self): 88011991Sandreas.sandberg@arm.com # Go from the Python class to the wrapped C++ class 88111802Sandreas.sandberg@arm.com from _m5.range import AddrRange 8824762Snate@binkert.org 8839411Sandreas.hansson@arm.com return AddrRange(long(self.start), long(self.end), 88414049Snikos.nikoleris@arm.com self.masks, int(self.intlvMatch)) 8853101Sstever@eecs.umich.edu 8863101Sstever@eecs.umich.edu# Boolean parameter type. Python doesn't let you subclass bool, since 8873101Sstever@eecs.umich.edu# it doesn't want to let you create multiple instances of True and 8883101Sstever@eecs.umich.edu# False. Thus this is a little more complicated than String. 8893101Sstever@eecs.umich.educlass Bool(ParamValue): 8903101Sstever@eecs.umich.edu cxx_type = 'bool' 89110267SGeoffrey.Blake@arm.com cmd_line_settable = True 89210267SGeoffrey.Blake@arm.com 8933101Sstever@eecs.umich.edu def __init__(self, value): 8943101Sstever@eecs.umich.edu try: 8953102Sstever@eecs.umich.edu self.value = convert.toBool(value) 8963101Sstever@eecs.umich.edu except TypeError: 8973101Sstever@eecs.umich.edu self.value = bool(value) 8983101Sstever@eecs.umich.edu 89910267SGeoffrey.Blake@arm.com def __call__(self, value): 90010267SGeoffrey.Blake@arm.com self.__init__(value) 90110267SGeoffrey.Blake@arm.com return value 90210267SGeoffrey.Blake@arm.com 9034762Snate@binkert.org def getValue(self): 9044762Snate@binkert.org return bool(self.value) 9054762Snate@binkert.org 9063101Sstever@eecs.umich.edu def __str__(self): 9073101Sstever@eecs.umich.edu return str(self.value) 9083101Sstever@eecs.umich.edu 9098934SBrad.Beckmann@amd.com # implement truth value testing for Bool parameters so that these params 9108934SBrad.Beckmann@amd.com # evaluate correctly during the python configuration phase 91113697Sandreas.sandberg@arm.com def __bool__(self): 9128934SBrad.Beckmann@amd.com return bool(self.value) 9138934SBrad.Beckmann@amd.com 91413697Sandreas.sandberg@arm.com # Python 2.7 uses __nonzero__ instead of __bool__ 91513697Sandreas.sandberg@arm.com __nonzero__ = __bool__ 91613697Sandreas.sandberg@arm.com 9173101Sstever@eecs.umich.edu def ini_str(self): 9183101Sstever@eecs.umich.edu if self.value: 9193101Sstever@eecs.umich.edu return 'true' 9203101Sstever@eecs.umich.edu return 'false' 9213101Sstever@eecs.umich.edu 92210380SAndrew.Bardsley@arm.com def config_value(self): 92310380SAndrew.Bardsley@arm.com return self.value 92410380SAndrew.Bardsley@arm.com 92510458Sandreas.hansson@arm.com @classmethod 92610458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 92710458Sandreas.hansson@arm.com # Assume that base/str.hh will be included anyway 92810458Sandreas.hansson@arm.com # code('#include "base/str.hh"') 92910458Sandreas.hansson@arm.com pass 93010458Sandreas.hansson@arm.com 93110458Sandreas.hansson@arm.com @classmethod 93210458Sandreas.hansson@arm.com def cxx_ini_parse(cls, code, src, dest, ret): 93310458Sandreas.hansson@arm.com code('%s to_bool(%s, %s);' % (ret, src, dest)) 93410458Sandreas.hansson@arm.com 9353101Sstever@eecs.umich.edudef IncEthernetAddr(addr, val = 1): 93613709Sandreas.sandberg@arm.com bytes = [ int(x, 16) for x in addr.split(':') ] 9373101Sstever@eecs.umich.edu bytes[5] += val 9383101Sstever@eecs.umich.edu for i in (5, 4, 3, 2, 1): 9393101Sstever@eecs.umich.edu val,rem = divmod(bytes[i], 256) 9403101Sstever@eecs.umich.edu bytes[i] = rem 9413101Sstever@eecs.umich.edu if val == 0: 9423101Sstever@eecs.umich.edu break 9433101Sstever@eecs.umich.edu bytes[i - 1] += val 9443101Sstever@eecs.umich.edu assert(bytes[0] <= 255) 9453101Sstever@eecs.umich.edu return ':'.join(map(lambda x: '%02x' % x, bytes)) 9463101Sstever@eecs.umich.edu 9474380Sbinkertn@umich.edu_NextEthernetAddr = "00:90:00:00:00:01" 9484380Sbinkertn@umich.edudef NextEthernetAddr(): 9494380Sbinkertn@umich.edu global _NextEthernetAddr 9503101Sstever@eecs.umich.edu 9514380Sbinkertn@umich.edu value = _NextEthernetAddr 9524380Sbinkertn@umich.edu _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1) 9534380Sbinkertn@umich.edu return value 9543101Sstever@eecs.umich.edu 9553101Sstever@eecs.umich.educlass EthernetAddr(ParamValue): 9563101Sstever@eecs.umich.edu cxx_type = 'Net::EthAddr' 95710267SGeoffrey.Blake@arm.com ex_str = "00:90:00:00:00:01" 95810267SGeoffrey.Blake@arm.com cmd_line_settable = True 9597673Snate@binkert.org 9607673Snate@binkert.org @classmethod 9617673Snate@binkert.org def cxx_predecls(cls, code): 9627673Snate@binkert.org code('#include "base/inet.hh"') 9637673Snate@binkert.org 9643101Sstever@eecs.umich.edu def __init__(self, value): 9653101Sstever@eecs.umich.edu if value == NextEthernetAddr: 9663101Sstever@eecs.umich.edu self.value = value 9673101Sstever@eecs.umich.edu return 9683101Sstever@eecs.umich.edu 9693101Sstever@eecs.umich.edu if not isinstance(value, str): 97013663Sandreas.sandberg@arm.com raise TypeError("expected an ethernet address and didn't get one") 9713101Sstever@eecs.umich.edu 9723101Sstever@eecs.umich.edu bytes = value.split(':') 9733101Sstever@eecs.umich.edu if len(bytes) != 6: 97413663Sandreas.sandberg@arm.com raise TypeError('invalid ethernet address %s' % value) 9753101Sstever@eecs.umich.edu 9763101Sstever@eecs.umich.edu for byte in bytes: 9779941SGeoffrey.Blake@arm.com if not 0 <= int(byte, base=16) <= 0xff: 97813663Sandreas.sandberg@arm.com raise TypeError('invalid ethernet address %s' % value) 9793101Sstever@eecs.umich.edu 9803101Sstever@eecs.umich.edu self.value = value 9813101Sstever@eecs.umich.edu 98210267SGeoffrey.Blake@arm.com def __call__(self, value): 98310267SGeoffrey.Blake@arm.com self.__init__(value) 98410267SGeoffrey.Blake@arm.com return value 98510267SGeoffrey.Blake@arm.com 9863101Sstever@eecs.umich.edu def unproxy(self, base): 9873101Sstever@eecs.umich.edu if self.value == NextEthernetAddr: 9884380Sbinkertn@umich.edu return EthernetAddr(self.value()) 9893101Sstever@eecs.umich.edu return self 9903101Sstever@eecs.umich.edu 9914762Snate@binkert.org def getValue(self): 99211988Sandreas.sandberg@arm.com from _m5.net import EthAddr 9934762Snate@binkert.org return EthAddr(self.value) 9944762Snate@binkert.org 99511228SAndrew.Bardsley@arm.com def __str__(self): 99611228SAndrew.Bardsley@arm.com return self.value 99711228SAndrew.Bardsley@arm.com 9984380Sbinkertn@umich.edu def ini_str(self): 9994380Sbinkertn@umich.edu return self.value 10003101Sstever@eecs.umich.edu 100110458Sandreas.hansson@arm.com @classmethod 100210458Sandreas.hansson@arm.com def cxx_ini_parse(self, code, src, dest, ret): 100310458Sandreas.hansson@arm.com code('%s = Net::EthAddr(%s);' % (dest, src)) 100410458Sandreas.hansson@arm.com code('%s true;' % ret) 100510458Sandreas.hansson@arm.com 10067777Sgblack@eecs.umich.edu# When initializing an IpAddress, pass in an existing IpAddress, a string of 10077777Sgblack@eecs.umich.edu# the form "a.b.c.d", or an integer representing an IP. 10087777Sgblack@eecs.umich.educlass IpAddress(ParamValue): 10097777Sgblack@eecs.umich.edu cxx_type = 'Net::IpAddress' 101010267SGeoffrey.Blake@arm.com ex_str = "127.0.0.1" 101110267SGeoffrey.Blake@arm.com cmd_line_settable = True 10127777Sgblack@eecs.umich.edu 10137777Sgblack@eecs.umich.edu @classmethod 10147777Sgblack@eecs.umich.edu def cxx_predecls(cls, code): 10157777Sgblack@eecs.umich.edu code('#include "base/inet.hh"') 10167777Sgblack@eecs.umich.edu 10177777Sgblack@eecs.umich.edu def __init__(self, value): 10187777Sgblack@eecs.umich.edu if isinstance(value, IpAddress): 10197777Sgblack@eecs.umich.edu self.ip = value.ip 10207777Sgblack@eecs.umich.edu else: 10217777Sgblack@eecs.umich.edu try: 10227777Sgblack@eecs.umich.edu self.ip = convert.toIpAddress(value) 10237777Sgblack@eecs.umich.edu except TypeError: 10247777Sgblack@eecs.umich.edu self.ip = long(value) 10257777Sgblack@eecs.umich.edu self.verifyIp() 10267777Sgblack@eecs.umich.edu 102710267SGeoffrey.Blake@arm.com def __call__(self, value): 102810267SGeoffrey.Blake@arm.com self.__init__(value) 102910267SGeoffrey.Blake@arm.com return value 103010267SGeoffrey.Blake@arm.com 10318579Ssteve.reinhardt@amd.com def __str__(self): 10328579Ssteve.reinhardt@amd.com tup = [(self.ip >> i) & 0xff for i in (24, 16, 8, 0)] 10338579Ssteve.reinhardt@amd.com return '%d.%d.%d.%d' % tuple(tup) 10348579Ssteve.reinhardt@amd.com 10358579Ssteve.reinhardt@amd.com def __eq__(self, other): 10368579Ssteve.reinhardt@amd.com if isinstance(other, IpAddress): 10378579Ssteve.reinhardt@amd.com return self.ip == other.ip 10388579Ssteve.reinhardt@amd.com elif isinstance(other, str): 10398579Ssteve.reinhardt@amd.com try: 10408579Ssteve.reinhardt@amd.com return self.ip == convert.toIpAddress(other) 10418579Ssteve.reinhardt@amd.com except: 10428579Ssteve.reinhardt@amd.com return False 10438579Ssteve.reinhardt@amd.com else: 10448579Ssteve.reinhardt@amd.com return self.ip == other 10458579Ssteve.reinhardt@amd.com 10468579Ssteve.reinhardt@amd.com def __ne__(self, other): 10478579Ssteve.reinhardt@amd.com return not (self == other) 10488579Ssteve.reinhardt@amd.com 10497777Sgblack@eecs.umich.edu def verifyIp(self): 10507777Sgblack@eecs.umich.edu if self.ip < 0 or self.ip >= (1 << 32): 105113663Sandreas.sandberg@arm.com raise TypeError("invalid ip address %#08x" % self.ip) 10527777Sgblack@eecs.umich.edu 10537777Sgblack@eecs.umich.edu def getValue(self): 105411988Sandreas.sandberg@arm.com from _m5.net import IpAddress 10557777Sgblack@eecs.umich.edu return IpAddress(self.ip) 10567777Sgblack@eecs.umich.edu 10577777Sgblack@eecs.umich.edu# When initializing an IpNetmask, pass in an existing IpNetmask, a string of 10587777Sgblack@eecs.umich.edu# the form "a.b.c.d/n" or "a.b.c.d/e.f.g.h", or an ip and netmask as 10597777Sgblack@eecs.umich.edu# positional or keyword arguments. 10607777Sgblack@eecs.umich.educlass IpNetmask(IpAddress): 10617777Sgblack@eecs.umich.edu cxx_type = 'Net::IpNetmask' 106210267SGeoffrey.Blake@arm.com ex_str = "127.0.0.0/24" 106310267SGeoffrey.Blake@arm.com cmd_line_settable = True 10647777Sgblack@eecs.umich.edu 10657777Sgblack@eecs.umich.edu @classmethod 10667777Sgblack@eecs.umich.edu def cxx_predecls(cls, code): 10677777Sgblack@eecs.umich.edu code('#include "base/inet.hh"') 10687777Sgblack@eecs.umich.edu 10697777Sgblack@eecs.umich.edu def __init__(self, *args, **kwargs): 10707777Sgblack@eecs.umich.edu def handle_kwarg(self, kwargs, key, elseVal = None): 10717777Sgblack@eecs.umich.edu if key in kwargs: 10727777Sgblack@eecs.umich.edu setattr(self, key, kwargs.pop(key)) 10737777Sgblack@eecs.umich.edu elif elseVal: 10747777Sgblack@eecs.umich.edu setattr(self, key, elseVal) 10757777Sgblack@eecs.umich.edu else: 107613663Sandreas.sandberg@arm.com raise TypeError("No value set for %s" % key) 10777777Sgblack@eecs.umich.edu 10787777Sgblack@eecs.umich.edu if len(args) == 0: 10797777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'ip') 10807777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'netmask') 10817777Sgblack@eecs.umich.edu 10827777Sgblack@eecs.umich.edu elif len(args) == 1: 10837777Sgblack@eecs.umich.edu if kwargs: 10847777Sgblack@eecs.umich.edu if not 'ip' in kwargs and not 'netmask' in kwargs: 108513663Sandreas.sandberg@arm.com raise TypeError("Invalid arguments") 10867777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'ip', args[0]) 10877777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'netmask', args[0]) 10887777Sgblack@eecs.umich.edu elif isinstance(args[0], IpNetmask): 10897777Sgblack@eecs.umich.edu self.ip = args[0].ip 10907777Sgblack@eecs.umich.edu self.netmask = args[0].netmask 10917777Sgblack@eecs.umich.edu else: 10927777Sgblack@eecs.umich.edu (self.ip, self.netmask) = convert.toIpNetmask(args[0]) 10937777Sgblack@eecs.umich.edu 10947777Sgblack@eecs.umich.edu elif len(args) == 2: 10957777Sgblack@eecs.umich.edu self.ip = args[0] 10967777Sgblack@eecs.umich.edu self.netmask = args[1] 10977777Sgblack@eecs.umich.edu else: 109813663Sandreas.sandberg@arm.com raise TypeError("Too many arguments specified") 10997777Sgblack@eecs.umich.edu 11007777Sgblack@eecs.umich.edu if kwargs: 110113663Sandreas.sandberg@arm.com raise TypeError("Too many keywords: %s" % list(kwargs.keys())) 11027777Sgblack@eecs.umich.edu 11037777Sgblack@eecs.umich.edu self.verify() 11047777Sgblack@eecs.umich.edu 110510267SGeoffrey.Blake@arm.com def __call__(self, value): 110610267SGeoffrey.Blake@arm.com self.__init__(value) 110710267SGeoffrey.Blake@arm.com return value 110810267SGeoffrey.Blake@arm.com 11098579Ssteve.reinhardt@amd.com def __str__(self): 11108579Ssteve.reinhardt@amd.com return "%s/%d" % (super(IpNetmask, self).__str__(), self.netmask) 11118579Ssteve.reinhardt@amd.com 11128579Ssteve.reinhardt@amd.com def __eq__(self, other): 11138579Ssteve.reinhardt@amd.com if isinstance(other, IpNetmask): 11148579Ssteve.reinhardt@amd.com return self.ip == other.ip and self.netmask == other.netmask 11158579Ssteve.reinhardt@amd.com elif isinstance(other, str): 11168579Ssteve.reinhardt@amd.com try: 11178579Ssteve.reinhardt@amd.com return (self.ip, self.netmask) == convert.toIpNetmask(other) 11188579Ssteve.reinhardt@amd.com except: 11198579Ssteve.reinhardt@amd.com return False 11208579Ssteve.reinhardt@amd.com else: 11218579Ssteve.reinhardt@amd.com return False 11228579Ssteve.reinhardt@amd.com 11237777Sgblack@eecs.umich.edu def verify(self): 11247777Sgblack@eecs.umich.edu self.verifyIp() 11257777Sgblack@eecs.umich.edu if self.netmask < 0 or self.netmask > 32: 112613663Sandreas.sandberg@arm.com raise TypeError("invalid netmask %d" % netmask) 11277777Sgblack@eecs.umich.edu 11287777Sgblack@eecs.umich.edu def getValue(self): 112911988Sandreas.sandberg@arm.com from _m5.net import IpNetmask 11307777Sgblack@eecs.umich.edu return IpNetmask(self.ip, self.netmask) 11317777Sgblack@eecs.umich.edu 11327777Sgblack@eecs.umich.edu# When initializing an IpWithPort, pass in an existing IpWithPort, a string of 11337777Sgblack@eecs.umich.edu# the form "a.b.c.d:p", or an ip and port as positional or keyword arguments. 11347777Sgblack@eecs.umich.educlass IpWithPort(IpAddress): 11357777Sgblack@eecs.umich.edu cxx_type = 'Net::IpWithPort' 113610267SGeoffrey.Blake@arm.com ex_str = "127.0.0.1:80" 113710267SGeoffrey.Blake@arm.com cmd_line_settable = True 11387777Sgblack@eecs.umich.edu 11397777Sgblack@eecs.umich.edu @classmethod 11407777Sgblack@eecs.umich.edu def cxx_predecls(cls, code): 11417777Sgblack@eecs.umich.edu code('#include "base/inet.hh"') 11427777Sgblack@eecs.umich.edu 11437777Sgblack@eecs.umich.edu def __init__(self, *args, **kwargs): 11447777Sgblack@eecs.umich.edu def handle_kwarg(self, kwargs, key, elseVal = None): 11457777Sgblack@eecs.umich.edu if key in kwargs: 11467777Sgblack@eecs.umich.edu setattr(self, key, kwargs.pop(key)) 11477777Sgblack@eecs.umich.edu elif elseVal: 11487777Sgblack@eecs.umich.edu setattr(self, key, elseVal) 11497777Sgblack@eecs.umich.edu else: 115013663Sandreas.sandberg@arm.com raise TypeError("No value set for %s" % key) 11517777Sgblack@eecs.umich.edu 11527777Sgblack@eecs.umich.edu if len(args) == 0: 11537777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'ip') 11547777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'port') 11557777Sgblack@eecs.umich.edu 11567777Sgblack@eecs.umich.edu elif len(args) == 1: 11577777Sgblack@eecs.umich.edu if kwargs: 11587777Sgblack@eecs.umich.edu if not 'ip' in kwargs and not 'port' in kwargs: 115913663Sandreas.sandberg@arm.com raise TypeError("Invalid arguments") 11607777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'ip', args[0]) 11617777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'port', args[0]) 11627777Sgblack@eecs.umich.edu elif isinstance(args[0], IpWithPort): 11637777Sgblack@eecs.umich.edu self.ip = args[0].ip 11647777Sgblack@eecs.umich.edu self.port = args[0].port 11657777Sgblack@eecs.umich.edu else: 11667777Sgblack@eecs.umich.edu (self.ip, self.port) = convert.toIpWithPort(args[0]) 11677777Sgblack@eecs.umich.edu 11687777Sgblack@eecs.umich.edu elif len(args) == 2: 11697777Sgblack@eecs.umich.edu self.ip = args[0] 11707777Sgblack@eecs.umich.edu self.port = args[1] 11717777Sgblack@eecs.umich.edu else: 117213663Sandreas.sandberg@arm.com raise TypeError("Too many arguments specified") 11737777Sgblack@eecs.umich.edu 11747777Sgblack@eecs.umich.edu if kwargs: 117513663Sandreas.sandberg@arm.com raise TypeError("Too many keywords: %s" % list(kwargs.keys())) 11767777Sgblack@eecs.umich.edu 11777777Sgblack@eecs.umich.edu self.verify() 11787777Sgblack@eecs.umich.edu 117910267SGeoffrey.Blake@arm.com def __call__(self, value): 118010267SGeoffrey.Blake@arm.com self.__init__(value) 118110267SGeoffrey.Blake@arm.com return value 118210267SGeoffrey.Blake@arm.com 11838579Ssteve.reinhardt@amd.com def __str__(self): 11848579Ssteve.reinhardt@amd.com return "%s:%d" % (super(IpWithPort, self).__str__(), self.port) 11858579Ssteve.reinhardt@amd.com 11868579Ssteve.reinhardt@amd.com def __eq__(self, other): 11878579Ssteve.reinhardt@amd.com if isinstance(other, IpWithPort): 11888579Ssteve.reinhardt@amd.com return self.ip == other.ip and self.port == other.port 11898579Ssteve.reinhardt@amd.com elif isinstance(other, str): 11908579Ssteve.reinhardt@amd.com try: 11918579Ssteve.reinhardt@amd.com return (self.ip, self.port) == convert.toIpWithPort(other) 11928579Ssteve.reinhardt@amd.com except: 11938579Ssteve.reinhardt@amd.com return False 11948579Ssteve.reinhardt@amd.com else: 11958579Ssteve.reinhardt@amd.com return False 11968579Ssteve.reinhardt@amd.com 11977777Sgblack@eecs.umich.edu def verify(self): 11987777Sgblack@eecs.umich.edu self.verifyIp() 11997777Sgblack@eecs.umich.edu if self.port < 0 or self.port > 0xffff: 120013663Sandreas.sandberg@arm.com raise TypeError("invalid port %d" % self.port) 12017777Sgblack@eecs.umich.edu 12027777Sgblack@eecs.umich.edu def getValue(self): 120311988Sandreas.sandberg@arm.com from _m5.net import IpWithPort 12047777Sgblack@eecs.umich.edu return IpWithPort(self.ip, self.port) 12057777Sgblack@eecs.umich.edu 12063932Sbinkertn@umich.edutime_formats = [ "%a %b %d %H:%M:%S %Z %Y", 120710380SAndrew.Bardsley@arm.com "%a %b %d %H:%M:%S %Y", 12083932Sbinkertn@umich.edu "%Y/%m/%d %H:%M:%S", 12093932Sbinkertn@umich.edu "%Y/%m/%d %H:%M", 12103932Sbinkertn@umich.edu "%Y/%m/%d", 12113932Sbinkertn@umich.edu "%m/%d/%Y %H:%M:%S", 12123932Sbinkertn@umich.edu "%m/%d/%Y %H:%M", 12133932Sbinkertn@umich.edu "%m/%d/%Y", 12143932Sbinkertn@umich.edu "%m/%d/%y %H:%M:%S", 12153932Sbinkertn@umich.edu "%m/%d/%y %H:%M", 12163932Sbinkertn@umich.edu "%m/%d/%y"] 12173932Sbinkertn@umich.edu 12183932Sbinkertn@umich.edu 12193885Sbinkertn@umich.edudef parse_time(value): 12203932Sbinkertn@umich.edu from time import gmtime, strptime, struct_time, time 12213932Sbinkertn@umich.edu from datetime import datetime, date 12223885Sbinkertn@umich.edu 12233932Sbinkertn@umich.edu if isinstance(value, struct_time): 12243932Sbinkertn@umich.edu return value 12253932Sbinkertn@umich.edu 12263932Sbinkertn@umich.edu if isinstance(value, (int, long)): 12273932Sbinkertn@umich.edu return gmtime(value) 12283932Sbinkertn@umich.edu 12293932Sbinkertn@umich.edu if isinstance(value, (datetime, date)): 12303932Sbinkertn@umich.edu return value.timetuple() 12313932Sbinkertn@umich.edu 12323932Sbinkertn@umich.edu if isinstance(value, str): 12333932Sbinkertn@umich.edu if value in ('Now', 'Today'): 12343932Sbinkertn@umich.edu return time.gmtime(time.time()) 12353932Sbinkertn@umich.edu 12363932Sbinkertn@umich.edu for format in time_formats: 12373932Sbinkertn@umich.edu try: 12383932Sbinkertn@umich.edu return strptime(value, format) 12393932Sbinkertn@umich.edu except ValueError: 12403932Sbinkertn@umich.edu pass 12413885Sbinkertn@umich.edu 124213663Sandreas.sandberg@arm.com raise ValueError("Could not parse '%s' as a time" % value) 12433885Sbinkertn@umich.edu 12443885Sbinkertn@umich.educlass Time(ParamValue): 12454762Snate@binkert.org cxx_type = 'tm' 12467673Snate@binkert.org 12477673Snate@binkert.org @classmethod 12487673Snate@binkert.org def cxx_predecls(cls, code): 12497673Snate@binkert.org code('#include <time.h>') 12507673Snate@binkert.org 12513885Sbinkertn@umich.edu def __init__(self, value): 12523932Sbinkertn@umich.edu self.value = parse_time(value) 12533885Sbinkertn@umich.edu 125410267SGeoffrey.Blake@arm.com def __call__(self, value): 125510267SGeoffrey.Blake@arm.com self.__init__(value) 125610267SGeoffrey.Blake@arm.com return value 125710267SGeoffrey.Blake@arm.com 12584762Snate@binkert.org def getValue(self): 125911988Sandreas.sandberg@arm.com from _m5.core import tm 126011988Sandreas.sandberg@arm.com import calendar 12614762Snate@binkert.org 126211988Sandreas.sandberg@arm.com return tm.gmtime(calendar.timegm(self.value)) 12634762Snate@binkert.org 12643885Sbinkertn@umich.edu def __str__(self): 12654762Snate@binkert.org return time.asctime(self.value) 12663885Sbinkertn@umich.edu 12673885Sbinkertn@umich.edu def ini_str(self): 12683932Sbinkertn@umich.edu return str(self) 12693885Sbinkertn@umich.edu 12708664SAli.Saidi@ARM.com def get_config_as_dict(self): 127110380SAndrew.Bardsley@arm.com assert false 12728664SAli.Saidi@ARM.com return str(self) 12738664SAli.Saidi@ARM.com 127410458Sandreas.hansson@arm.com @classmethod 127510458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 127610458Sandreas.hansson@arm.com code('#include <time.h>') 127710458Sandreas.hansson@arm.com 127810458Sandreas.hansson@arm.com @classmethod 127910458Sandreas.hansson@arm.com def cxx_ini_parse(cls, code, src, dest, ret): 128010458Sandreas.hansson@arm.com code('char *_parse_ret = strptime((${src}).c_str(),') 128110458Sandreas.hansson@arm.com code(' "%a %b %d %H:%M:%S %Y", &(${dest}));') 128210458Sandreas.hansson@arm.com code('${ret} _parse_ret && *_parse_ret == \'\\0\';'); 128310458Sandreas.hansson@arm.com 12843101Sstever@eecs.umich.edu# Enumerated types are a little more complex. The user specifies the 12853101Sstever@eecs.umich.edu# type as Enum(foo) where foo is either a list or dictionary of 12863101Sstever@eecs.umich.edu# alternatives (typically strings, but not necessarily so). (In the 12873101Sstever@eecs.umich.edu# long run, the integer value of the parameter will be the list index 12883101Sstever@eecs.umich.edu# or the corresponding dictionary value. For now, since we only check 12893101Sstever@eecs.umich.edu# that the alternative is valid and then spit it into a .ini file, 12903101Sstever@eecs.umich.edu# there's not much point in using the dictionary.) 12913101Sstever@eecs.umich.edu 12923101Sstever@eecs.umich.edu# What Enum() must do is generate a new type encapsulating the 12933101Sstever@eecs.umich.edu# provided list/dictionary so that specific values of the parameter 12943101Sstever@eecs.umich.edu# can be instances of that type. We define two hidden internal 12953101Sstever@eecs.umich.edu# classes (_ListEnum and _DictEnum) to serve as base classes, then 12963101Sstever@eecs.umich.edu# derive the new type from the appropriate base class on the fly. 12973101Sstever@eecs.umich.edu 12984762Snate@binkert.orgallEnums = {} 12993101Sstever@eecs.umich.edu# Metaclass for Enum types 13005033Smilesck@eecs.umich.educlass MetaEnum(MetaParamValue): 13014762Snate@binkert.org def __new__(mcls, name, bases, dict): 13024762Snate@binkert.org assert name not in allEnums 13034762Snate@binkert.org 13044762Snate@binkert.org cls = super(MetaEnum, mcls).__new__(mcls, name, bases, dict) 13054762Snate@binkert.org allEnums[name] = cls 13064762Snate@binkert.org return cls 13074762Snate@binkert.org 13083101Sstever@eecs.umich.edu def __init__(cls, name, bases, init_dict): 130913675Sandreas.sandberg@arm.com if 'map' in init_dict: 13103101Sstever@eecs.umich.edu if not isinstance(cls.map, dict): 131113663Sandreas.sandberg@arm.com raise TypeError("Enum-derived class attribute 'map' " \ 131213663Sandreas.sandberg@arm.com "must be of type dict") 13133101Sstever@eecs.umich.edu # build list of value strings from map 131413709Sandreas.sandberg@arm.com cls.vals = list(cls.map.keys()) 13153101Sstever@eecs.umich.edu cls.vals.sort() 131613675Sandreas.sandberg@arm.com elif 'vals' in init_dict: 13173101Sstever@eecs.umich.edu if not isinstance(cls.vals, list): 131813663Sandreas.sandberg@arm.com raise TypeError("Enum-derived class attribute 'vals' " \ 131913663Sandreas.sandberg@arm.com "must be of type list") 13203101Sstever@eecs.umich.edu # build string->value map from vals sequence 13213101Sstever@eecs.umich.edu cls.map = {} 13223101Sstever@eecs.umich.edu for idx,val in enumerate(cls.vals): 13233101Sstever@eecs.umich.edu cls.map[val] = idx 13243101Sstever@eecs.umich.edu else: 132513663Sandreas.sandberg@arm.com raise TypeError("Enum-derived class must define "\ 132613663Sandreas.sandberg@arm.com "attribute 'map' or 'vals'") 13273101Sstever@eecs.umich.edu 132813558Snikos.nikoleris@arm.com if cls.is_class: 132913558Snikos.nikoleris@arm.com cls.cxx_type = '%s' % name 133013558Snikos.nikoleris@arm.com else: 133113558Snikos.nikoleris@arm.com cls.cxx_type = 'Enums::%s' % name 13323101Sstever@eecs.umich.edu 13333101Sstever@eecs.umich.edu super(MetaEnum, cls).__init__(name, bases, init_dict) 13343101Sstever@eecs.umich.edu 13353101Sstever@eecs.umich.edu # Generate C++ class declaration for this enum type. 13363101Sstever@eecs.umich.edu # Note that we wrap the enum in a class/struct to act as a namespace, 13373101Sstever@eecs.umich.edu # so that the enum strings can be brief w/o worrying about collisions. 13387673Snate@binkert.org def cxx_decl(cls, code): 133910201SAndrew.Bardsley@arm.com wrapper_name = cls.wrapper_name 134010201SAndrew.Bardsley@arm.com wrapper = 'struct' if cls.wrapper_is_struct else 'namespace' 134110201SAndrew.Bardsley@arm.com name = cls.__name__ if cls.enum_name is None else cls.enum_name 134210201SAndrew.Bardsley@arm.com idem_macro = '__ENUM__%s__%s__' % (wrapper_name, name) 134310201SAndrew.Bardsley@arm.com 13447673Snate@binkert.org code('''\ 134510201SAndrew.Bardsley@arm.com#ifndef $idem_macro 134610201SAndrew.Bardsley@arm.com#define $idem_macro 13477673Snate@binkert.org 134813558Snikos.nikoleris@arm.com''') 134913558Snikos.nikoleris@arm.com if cls.is_class: 135013558Snikos.nikoleris@arm.com code('''\ 135113558Snikos.nikoleris@arm.comenum class $name { 135213558Snikos.nikoleris@arm.com''') 135313558Snikos.nikoleris@arm.com else: 135413558Snikos.nikoleris@arm.com code('''\ 135510201SAndrew.Bardsley@arm.com$wrapper $wrapper_name { 13567673Snate@binkert.org enum $name { 13577673Snate@binkert.org''') 135813558Snikos.nikoleris@arm.com code.indent(1) 135913558Snikos.nikoleris@arm.com code.indent(1) 13604762Snate@binkert.org for val in cls.vals: 13617673Snate@binkert.org code('$val = ${{cls.map[val]}},') 13628902Sandreas.hansson@arm.com code('Num_$name = ${{len(cls.vals)}}') 136313558Snikos.nikoleris@arm.com code.dedent(1) 136413558Snikos.nikoleris@arm.com code('};') 13654762Snate@binkert.org 136613558Snikos.nikoleris@arm.com if cls.is_class: 136713558Snikos.nikoleris@arm.com code('''\ 136813558Snikos.nikoleris@arm.comextern const char *${name}Strings[static_cast<int>(${name}::Num_${name})]; 136913558Snikos.nikoleris@arm.com''') 137013558Snikos.nikoleris@arm.com elif cls.wrapper_is_struct: 137113558Snikos.nikoleris@arm.com code('static const char *${name}Strings[Num_${name}];') 137210201SAndrew.Bardsley@arm.com else: 137310201SAndrew.Bardsley@arm.com code('extern const char *${name}Strings[Num_${name}];') 137413558Snikos.nikoleris@arm.com 137513558Snikos.nikoleris@arm.com if not cls.is_class: 137613558Snikos.nikoleris@arm.com code.dedent(1) 137713558Snikos.nikoleris@arm.com code('};') 137810201SAndrew.Bardsley@arm.com 137910201SAndrew.Bardsley@arm.com code() 138010201SAndrew.Bardsley@arm.com code('#endif // $idem_macro') 13817673Snate@binkert.org 13827673Snate@binkert.org def cxx_def(cls, code): 138310201SAndrew.Bardsley@arm.com wrapper_name = cls.wrapper_name 138410201SAndrew.Bardsley@arm.com file_name = cls.__name__ 138510201SAndrew.Bardsley@arm.com name = cls.__name__ if cls.enum_name is None else cls.enum_name 138610201SAndrew.Bardsley@arm.com 138710201SAndrew.Bardsley@arm.com code('#include "enums/$file_name.hh"') 138810201SAndrew.Bardsley@arm.com if cls.wrapper_is_struct: 138910201SAndrew.Bardsley@arm.com code('const char *${wrapper_name}::${name}Strings' 139010201SAndrew.Bardsley@arm.com '[Num_${name}] =') 139110201SAndrew.Bardsley@arm.com else: 139213558Snikos.nikoleris@arm.com if cls.is_class: 139313558Snikos.nikoleris@arm.com code('''\ 139413558Snikos.nikoleris@arm.comconst char *${name}Strings[static_cast<int>(${name}::Num_${name})] = 139513558Snikos.nikoleris@arm.com''') 139613558Snikos.nikoleris@arm.com else: 139713558Snikos.nikoleris@arm.com code('namespace Enums {') 139813558Snikos.nikoleris@arm.com code.indent(1) 139913558Snikos.nikoleris@arm.com code('const char *${name}Strings[Num_${name}] =') 140010201SAndrew.Bardsley@arm.com 140110201SAndrew.Bardsley@arm.com code('{') 140210201SAndrew.Bardsley@arm.com code.indent(1) 14034762Snate@binkert.org for val in cls.vals: 14047673Snate@binkert.org code('"$val",') 140510201SAndrew.Bardsley@arm.com code.dedent(1) 140610201SAndrew.Bardsley@arm.com code('};') 140710201SAndrew.Bardsley@arm.com 140813558Snikos.nikoleris@arm.com if not cls.wrapper_is_struct and not cls.is_class: 140913558Snikos.nikoleris@arm.com code.dedent(1) 141010201SAndrew.Bardsley@arm.com code('} // namespace $wrapper_name') 141113558Snikos.nikoleris@arm.com 14123101Sstever@eecs.umich.edu 141311988Sandreas.sandberg@arm.com def pybind_def(cls, code): 141411988Sandreas.sandberg@arm.com name = cls.__name__ 141511988Sandreas.sandberg@arm.com enum_name = cls.__name__ if cls.enum_name is None else cls.enum_name 141613558Snikos.nikoleris@arm.com wrapper_name = enum_name if cls.is_class else cls.wrapper_name 141711988Sandreas.sandberg@arm.com 141811988Sandreas.sandberg@arm.com code('''#include "pybind11/pybind11.h" 141911988Sandreas.sandberg@arm.com#include "pybind11/stl.h" 142011988Sandreas.sandberg@arm.com 142111988Sandreas.sandberg@arm.com#include <sim/init.hh> 142211988Sandreas.sandberg@arm.com 142311988Sandreas.sandberg@arm.comnamespace py = pybind11; 142411988Sandreas.sandberg@arm.com 142511988Sandreas.sandberg@arm.comstatic void 142611988Sandreas.sandberg@arm.commodule_init(py::module &m_internal) 142711988Sandreas.sandberg@arm.com{ 142811988Sandreas.sandberg@arm.com py::module m = m_internal.def_submodule("enum_${name}"); 142911988Sandreas.sandberg@arm.com 143011988Sandreas.sandberg@arm.com''') 143113558Snikos.nikoleris@arm.com if cls.is_class: 143213558Snikos.nikoleris@arm.com code('py::enum_<${enum_name}>(m, "enum_${name}")') 143313558Snikos.nikoleris@arm.com else: 143413558Snikos.nikoleris@arm.com code('py::enum_<${wrapper_name}::${enum_name}>(m, "enum_${name}")') 143511988Sandreas.sandberg@arm.com 143611988Sandreas.sandberg@arm.com code.indent() 143711988Sandreas.sandberg@arm.com code.indent() 143811988Sandreas.sandberg@arm.com for val in cls.vals: 143911988Sandreas.sandberg@arm.com code('.value("${val}", ${wrapper_name}::${val})') 144011988Sandreas.sandberg@arm.com code('.value("Num_${name}", ${wrapper_name}::Num_${enum_name})') 144111988Sandreas.sandberg@arm.com code('.export_values()') 144211988Sandreas.sandberg@arm.com code(';') 144311988Sandreas.sandberg@arm.com code.dedent() 144411988Sandreas.sandberg@arm.com 144511988Sandreas.sandberg@arm.com code('}') 144611988Sandreas.sandberg@arm.com code.dedent() 144711988Sandreas.sandberg@arm.com code() 144811988Sandreas.sandberg@arm.com code('static EmbeddedPyBind embed_enum("enum_${name}", module_init);') 144911988Sandreas.sandberg@arm.com 14508596Ssteve.reinhardt@amd.com 14513101Sstever@eecs.umich.edu# Base class for enum types. 14523101Sstever@eecs.umich.educlass Enum(ParamValue): 14533101Sstever@eecs.umich.edu __metaclass__ = MetaEnum 14543101Sstever@eecs.umich.edu vals = [] 145510267SGeoffrey.Blake@arm.com cmd_line_settable = True 14563101Sstever@eecs.umich.edu 145710201SAndrew.Bardsley@arm.com # The name of the wrapping namespace or struct 145810201SAndrew.Bardsley@arm.com wrapper_name = 'Enums' 145910201SAndrew.Bardsley@arm.com 146010201SAndrew.Bardsley@arm.com # If true, the enum is wrapped in a struct rather than a namespace 146110201SAndrew.Bardsley@arm.com wrapper_is_struct = False 146210201SAndrew.Bardsley@arm.com 146313558Snikos.nikoleris@arm.com is_class = False 146413558Snikos.nikoleris@arm.com 146510201SAndrew.Bardsley@arm.com # If not None, use this as the enum name rather than this class name 146610201SAndrew.Bardsley@arm.com enum_name = None 146710201SAndrew.Bardsley@arm.com 14683101Sstever@eecs.umich.edu def __init__(self, value): 14693101Sstever@eecs.umich.edu if value not in self.map: 147013663Sandreas.sandberg@arm.com raise TypeError("Enum param got bad value '%s' (not in %s)" \ 147113663Sandreas.sandberg@arm.com % (value, self.vals)) 14723101Sstever@eecs.umich.edu self.value = value 14733101Sstever@eecs.umich.edu 147410267SGeoffrey.Blake@arm.com def __call__(self, value): 147510267SGeoffrey.Blake@arm.com self.__init__(value) 147610267SGeoffrey.Blake@arm.com return value 147710267SGeoffrey.Blake@arm.com 14787675Snate@binkert.org @classmethod 14797675Snate@binkert.org def cxx_predecls(cls, code): 14807675Snate@binkert.org code('#include "enums/$0.hh"', cls.__name__) 14817675Snate@binkert.org 14827675Snate@binkert.org @classmethod 148310458Sandreas.hansson@arm.com def cxx_ini_parse(cls, code, src, dest, ret): 148410458Sandreas.hansson@arm.com code('if (false) {') 148513709Sandreas.sandberg@arm.com for elem_name in cls.map.keys(): 148610458Sandreas.hansson@arm.com code('} else if (%s == "%s") {' % (src, elem_name)) 148710458Sandreas.hansson@arm.com code.indent() 148814052Snikos.nikoleris@arm.com name = cls.__name__ if cls.enum_name is None else cls.enum_name 148914052Snikos.nikoleris@arm.com code('%s = %s::%s;' % (dest, name if cls.is_class else 'Enums', 149014052Snikos.nikoleris@arm.com elem_name)) 149110458Sandreas.hansson@arm.com code('%s true;' % ret) 149210458Sandreas.hansson@arm.com code.dedent() 149310458Sandreas.hansson@arm.com code('} else {') 149410458Sandreas.hansson@arm.com code(' %s false;' % ret) 149510458Sandreas.hansson@arm.com code('}') 149610458Sandreas.hansson@arm.com 14974762Snate@binkert.org def getValue(self): 149811988Sandreas.sandberg@arm.com import m5.internal.params 149911988Sandreas.sandberg@arm.com e = getattr(m5.internal.params, "enum_%s" % self.__class__.__name__) 150011988Sandreas.sandberg@arm.com return e(self.map[self.value]) 15014762Snate@binkert.org 15023101Sstever@eecs.umich.edu def __str__(self): 15033101Sstever@eecs.umich.edu return self.value 15043101Sstever@eecs.umich.edu 150513558Snikos.nikoleris@arm.com# This param will generate a scoped c++ enum and its python bindings. 150613558Snikos.nikoleris@arm.comclass ScopedEnum(Enum): 150713558Snikos.nikoleris@arm.com __metaclass__ = MetaEnum 150813558Snikos.nikoleris@arm.com vals = [] 150913558Snikos.nikoleris@arm.com cmd_line_settable = True 151013558Snikos.nikoleris@arm.com 151113558Snikos.nikoleris@arm.com # The name of the wrapping namespace or struct 151213558Snikos.nikoleris@arm.com wrapper_name = None 151313558Snikos.nikoleris@arm.com 151413558Snikos.nikoleris@arm.com # If true, the enum is wrapped in a struct rather than a namespace 151513558Snikos.nikoleris@arm.com wrapper_is_struct = False 151613558Snikos.nikoleris@arm.com 151713558Snikos.nikoleris@arm.com # If true, the generated enum is a scoped enum 151813558Snikos.nikoleris@arm.com is_class = True 151913558Snikos.nikoleris@arm.com 152013558Snikos.nikoleris@arm.com # If not None, use this as the enum name rather than this class name 152113558Snikos.nikoleris@arm.com enum_name = None 152213558Snikos.nikoleris@arm.com 15233101Sstever@eecs.umich.edu# how big does a rounding error need to be before we warn about it? 15243101Sstever@eecs.umich.edufrequency_tolerance = 0.001 # 0.1% 15253101Sstever@eecs.umich.edu 15264167Sbinkertn@umich.educlass TickParamValue(NumericParamValue): 15273101Sstever@eecs.umich.edu cxx_type = 'Tick' 152810267SGeoffrey.Blake@arm.com ex_str = "1MHz" 152910267SGeoffrey.Blake@arm.com cmd_line_settable = True 15307673Snate@binkert.org 15317673Snate@binkert.org @classmethod 15327673Snate@binkert.org def cxx_predecls(cls, code): 15337673Snate@binkert.org code('#include "base/types.hh"') 15347673Snate@binkert.org 153510267SGeoffrey.Blake@arm.com def __call__(self, value): 153610267SGeoffrey.Blake@arm.com self.__init__(value) 153710267SGeoffrey.Blake@arm.com return value 153810267SGeoffrey.Blake@arm.com 15394762Snate@binkert.org def getValue(self): 15404762Snate@binkert.org return long(self.value) 15414762Snate@binkert.org 154210458Sandreas.hansson@arm.com @classmethod 154310458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 154410458Sandreas.hansson@arm.com code('#include <sstream>') 154510458Sandreas.hansson@arm.com 154610458Sandreas.hansson@arm.com # Ticks are expressed in seconds in JSON files and in plain 154710458Sandreas.hansson@arm.com # Ticks in .ini files. Switch based on a config flag 154810458Sandreas.hansson@arm.com @classmethod 154910458Sandreas.hansson@arm.com def cxx_ini_parse(self, code, src, dest, ret): 155010458Sandreas.hansson@arm.com code('${ret} to_number(${src}, ${dest});') 155110458Sandreas.hansson@arm.com 15524167Sbinkertn@umich.educlass Latency(TickParamValue): 155310267SGeoffrey.Blake@arm.com ex_str = "100ns" 155410267SGeoffrey.Blake@arm.com 15553101Sstever@eecs.umich.edu def __init__(self, value): 15564167Sbinkertn@umich.edu if isinstance(value, (Latency, Clock)): 15574167Sbinkertn@umich.edu self.ticks = value.ticks 15584167Sbinkertn@umich.edu self.value = value.value 15594167Sbinkertn@umich.edu elif isinstance(value, Frequency): 15604167Sbinkertn@umich.edu self.ticks = value.ticks 15614167Sbinkertn@umich.edu self.value = 1.0 / value.value 15624167Sbinkertn@umich.edu elif value.endswith('t'): 15634167Sbinkertn@umich.edu self.ticks = True 15644167Sbinkertn@umich.edu self.value = int(value[:-1]) 15654167Sbinkertn@umich.edu else: 15664167Sbinkertn@umich.edu self.ticks = False 15674167Sbinkertn@umich.edu self.value = convert.toLatency(value) 15683101Sstever@eecs.umich.edu 156910267SGeoffrey.Blake@arm.com def __call__(self, value): 157010267SGeoffrey.Blake@arm.com self.__init__(value) 157110267SGeoffrey.Blake@arm.com return value 157210267SGeoffrey.Blake@arm.com 15733101Sstever@eecs.umich.edu def __getattr__(self, attr): 15743101Sstever@eecs.umich.edu if attr in ('latency', 'period'): 15753101Sstever@eecs.umich.edu return self 15763101Sstever@eecs.umich.edu if attr == 'frequency': 15773101Sstever@eecs.umich.edu return Frequency(self) 157813663Sandreas.sandberg@arm.com raise AttributeError("Latency object has no attribute '%s'" % attr) 15793101Sstever@eecs.umich.edu 15804762Snate@binkert.org def getValue(self): 15814762Snate@binkert.org if self.ticks or self.value == 0: 15824762Snate@binkert.org value = self.value 15834762Snate@binkert.org else: 15844762Snate@binkert.org value = ticks.fromSeconds(self.value) 15854762Snate@binkert.org return long(value) 15864762Snate@binkert.org 158710380SAndrew.Bardsley@arm.com def config_value(self): 158810380SAndrew.Bardsley@arm.com return self.getValue() 158910380SAndrew.Bardsley@arm.com 15903101Sstever@eecs.umich.edu # convert latency to ticks 15913101Sstever@eecs.umich.edu def ini_str(self): 15924762Snate@binkert.org return '%d' % self.getValue() 15933101Sstever@eecs.umich.edu 15944167Sbinkertn@umich.educlass Frequency(TickParamValue): 159510267SGeoffrey.Blake@arm.com ex_str = "1GHz" 159610267SGeoffrey.Blake@arm.com 15973101Sstever@eecs.umich.edu def __init__(self, value): 15984167Sbinkertn@umich.edu if isinstance(value, (Latency, Clock)): 15994167Sbinkertn@umich.edu if value.value == 0: 16004167Sbinkertn@umich.edu self.value = 0 16014167Sbinkertn@umich.edu else: 16024167Sbinkertn@umich.edu self.value = 1.0 / value.value 16034167Sbinkertn@umich.edu self.ticks = value.ticks 16044167Sbinkertn@umich.edu elif isinstance(value, Frequency): 16054167Sbinkertn@umich.edu self.value = value.value 16064167Sbinkertn@umich.edu self.ticks = value.ticks 16074167Sbinkertn@umich.edu else: 16084167Sbinkertn@umich.edu self.ticks = False 16094167Sbinkertn@umich.edu self.value = convert.toFrequency(value) 16103101Sstever@eecs.umich.edu 161110267SGeoffrey.Blake@arm.com def __call__(self, value): 161210267SGeoffrey.Blake@arm.com self.__init__(value) 161310267SGeoffrey.Blake@arm.com return value 161410267SGeoffrey.Blake@arm.com 16153101Sstever@eecs.umich.edu def __getattr__(self, attr): 16163101Sstever@eecs.umich.edu if attr == 'frequency': 16173101Sstever@eecs.umich.edu return self 16183101Sstever@eecs.umich.edu if attr in ('latency', 'period'): 16193101Sstever@eecs.umich.edu return Latency(self) 162013663Sandreas.sandberg@arm.com raise AttributeError("Frequency object has no attribute '%s'" % attr) 16213101Sstever@eecs.umich.edu 16224167Sbinkertn@umich.edu # convert latency to ticks 16234762Snate@binkert.org def getValue(self): 16244762Snate@binkert.org if self.ticks or self.value == 0: 16254762Snate@binkert.org value = self.value 16264762Snate@binkert.org else: 16274762Snate@binkert.org value = ticks.fromSeconds(1.0 / self.value) 16284762Snate@binkert.org return long(value) 16294762Snate@binkert.org 163010380SAndrew.Bardsley@arm.com def config_value(self): 163110380SAndrew.Bardsley@arm.com return self.getValue() 163210380SAndrew.Bardsley@arm.com 16333101Sstever@eecs.umich.edu def ini_str(self): 16344762Snate@binkert.org return '%d' % self.getValue() 16353101Sstever@eecs.umich.edu 163610019Sandreas.hansson@arm.com# A generic Frequency and/or Latency value. Value is stored as a 163710019Sandreas.hansson@arm.com# latency, just like Latency and Frequency. 163810019Sandreas.hansson@arm.comclass Clock(TickParamValue): 16393101Sstever@eecs.umich.edu def __init__(self, value): 16404167Sbinkertn@umich.edu if isinstance(value, (Latency, Clock)): 16414167Sbinkertn@umich.edu self.ticks = value.ticks 16424167Sbinkertn@umich.edu self.value = value.value 16434167Sbinkertn@umich.edu elif isinstance(value, Frequency): 16444167Sbinkertn@umich.edu self.ticks = value.ticks 16454167Sbinkertn@umich.edu self.value = 1.0 / value.value 16464167Sbinkertn@umich.edu elif value.endswith('t'): 16474167Sbinkertn@umich.edu self.ticks = True 16484167Sbinkertn@umich.edu self.value = int(value[:-1]) 16494167Sbinkertn@umich.edu else: 16504167Sbinkertn@umich.edu self.ticks = False 16514167Sbinkertn@umich.edu self.value = convert.anyToLatency(value) 16523101Sstever@eecs.umich.edu 165310267SGeoffrey.Blake@arm.com def __call__(self, value): 165410267SGeoffrey.Blake@arm.com self.__init__(value) 165510267SGeoffrey.Blake@arm.com return value 165610267SGeoffrey.Blake@arm.com 165710267SGeoffrey.Blake@arm.com def __str__(self): 165810267SGeoffrey.Blake@arm.com return "%s" % Latency(self) 165910267SGeoffrey.Blake@arm.com 16603101Sstever@eecs.umich.edu def __getattr__(self, attr): 16613101Sstever@eecs.umich.edu if attr == 'frequency': 16623101Sstever@eecs.umich.edu return Frequency(self) 16633101Sstever@eecs.umich.edu if attr in ('latency', 'period'): 16643101Sstever@eecs.umich.edu return Latency(self) 166513663Sandreas.sandberg@arm.com raise AttributeError("Frequency object has no attribute '%s'" % attr) 16663101Sstever@eecs.umich.edu 16674762Snate@binkert.org def getValue(self): 16684762Snate@binkert.org return self.period.getValue() 16694762Snate@binkert.org 167010380SAndrew.Bardsley@arm.com def config_value(self): 167110380SAndrew.Bardsley@arm.com return self.period.config_value() 167210380SAndrew.Bardsley@arm.com 16733101Sstever@eecs.umich.edu def ini_str(self): 16743101Sstever@eecs.umich.edu return self.period.ini_str() 16753101Sstever@eecs.umich.edu 167612250Sgabeblack@google.comclass Voltage(Float): 167710267SGeoffrey.Blake@arm.com ex_str = "1V" 167810267SGeoffrey.Blake@arm.com 16799827Sakash.bagdia@arm.com def __new__(cls, value): 168012250Sgabeblack@google.com value = convert.toVoltage(value) 168112250Sgabeblack@google.com return super(cls, Voltage).__new__(cls, value) 16829827Sakash.bagdia@arm.com 168312250Sgabeblack@google.com def __init__(self, value): 168412250Sgabeblack@google.com value = convert.toVoltage(value) 168512250Sgabeblack@google.com super(Voltage, self).__init__(value) 168610267SGeoffrey.Blake@arm.com 168712250Sgabeblack@google.comclass Current(Float): 168810427Sandreas.hansson@arm.com ex_str = "1mA" 168910427Sandreas.hansson@arm.com 169010427Sandreas.hansson@arm.com def __new__(cls, value): 169112250Sgabeblack@google.com value = convert.toCurrent(value) 169212250Sgabeblack@google.com return super(cls, Current).__new__(cls, value) 169310427Sandreas.hansson@arm.com 169412250Sgabeblack@google.com def __init__(self, value): 169512250Sgabeblack@google.com value = convert.toCurrent(value) 169612250Sgabeblack@google.com super(Current, self).__init__(value) 169710458Sandreas.hansson@arm.com 169812253Sgabeblack@google.comclass Energy(Float): 169912253Sgabeblack@google.com ex_str = "1pJ" 170012253Sgabeblack@google.com 170112253Sgabeblack@google.com def __new__(cls, value): 170212253Sgabeblack@google.com value = convert.toEnergy(value) 170312253Sgabeblack@google.com return super(cls, Energy).__new__(cls, value) 170412253Sgabeblack@google.com 170512253Sgabeblack@google.com def __init__(self, value): 170612253Sgabeblack@google.com value = convert.toEnergy(value) 170712253Sgabeblack@google.com super(Energy, self).__init__(value) 170812253Sgabeblack@google.com 17093101Sstever@eecs.umich.educlass NetworkBandwidth(float,ParamValue): 17103101Sstever@eecs.umich.edu cxx_type = 'float' 171110267SGeoffrey.Blake@arm.com ex_str = "1Gbps" 171210267SGeoffrey.Blake@arm.com cmd_line_settable = True 171310267SGeoffrey.Blake@arm.com 17143101Sstever@eecs.umich.edu def __new__(cls, value): 17154167Sbinkertn@umich.edu # convert to bits per second 17164167Sbinkertn@umich.edu val = convert.toNetworkBandwidth(value) 17173101Sstever@eecs.umich.edu return super(cls, NetworkBandwidth).__new__(cls, val) 17183101Sstever@eecs.umich.edu 17193101Sstever@eecs.umich.edu def __str__(self): 17203101Sstever@eecs.umich.edu return str(self.val) 17213101Sstever@eecs.umich.edu 172210267SGeoffrey.Blake@arm.com def __call__(self, value): 172310267SGeoffrey.Blake@arm.com val = convert.toNetworkBandwidth(value) 172410267SGeoffrey.Blake@arm.com self.__init__(val) 172510267SGeoffrey.Blake@arm.com return value 172610267SGeoffrey.Blake@arm.com 17274762Snate@binkert.org def getValue(self): 17284167Sbinkertn@umich.edu # convert to seconds per byte 17294167Sbinkertn@umich.edu value = 8.0 / float(self) 17304167Sbinkertn@umich.edu # convert to ticks per byte 17314762Snate@binkert.org value = ticks.fromSeconds(value) 17324762Snate@binkert.org return float(value) 17334762Snate@binkert.org 17344762Snate@binkert.org def ini_str(self): 17354762Snate@binkert.org return '%f' % self.getValue() 17363101Sstever@eecs.umich.edu 173710380SAndrew.Bardsley@arm.com def config_value(self): 173810380SAndrew.Bardsley@arm.com return '%f' % self.getValue() 173910380SAndrew.Bardsley@arm.com 174010458Sandreas.hansson@arm.com @classmethod 174110458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 174210458Sandreas.hansson@arm.com code('#include <sstream>') 174310458Sandreas.hansson@arm.com 174410458Sandreas.hansson@arm.com @classmethod 174510458Sandreas.hansson@arm.com def cxx_ini_parse(self, code, src, dest, ret): 174610458Sandreas.hansson@arm.com code('%s (std::istringstream(%s) >> %s).eof();' % (ret, src, dest)) 174710458Sandreas.hansson@arm.com 17483101Sstever@eecs.umich.educlass MemoryBandwidth(float,ParamValue): 17493101Sstever@eecs.umich.edu cxx_type = 'float' 175010267SGeoffrey.Blake@arm.com ex_str = "1GB/s" 175110267SGeoffrey.Blake@arm.com cmd_line_settable = True 175210267SGeoffrey.Blake@arm.com 17535469Snate@binkert.org def __new__(cls, value): 17547743Sgblack@eecs.umich.edu # convert to bytes per second 17553102Sstever@eecs.umich.edu val = convert.toMemoryBandwidth(value) 17563101Sstever@eecs.umich.edu return super(cls, MemoryBandwidth).__new__(cls, val) 17573101Sstever@eecs.umich.edu 175810267SGeoffrey.Blake@arm.com def __call__(self, value): 175910267SGeoffrey.Blake@arm.com val = convert.toMemoryBandwidth(value) 176010267SGeoffrey.Blake@arm.com self.__init__(val) 176110267SGeoffrey.Blake@arm.com return value 17623101Sstever@eecs.umich.edu 17634762Snate@binkert.org def getValue(self): 17644167Sbinkertn@umich.edu # convert to seconds per byte 17655468Snate@binkert.org value = float(self) 17665468Snate@binkert.org if value: 17675468Snate@binkert.org value = 1.0 / float(self) 17684167Sbinkertn@umich.edu # convert to ticks per byte 17694762Snate@binkert.org value = ticks.fromSeconds(value) 17704762Snate@binkert.org return float(value) 17714762Snate@binkert.org 17724762Snate@binkert.org def ini_str(self): 17734762Snate@binkert.org return '%f' % self.getValue() 17743101Sstever@eecs.umich.edu 177510380SAndrew.Bardsley@arm.com def config_value(self): 177610380SAndrew.Bardsley@arm.com return '%f' % self.getValue() 177710380SAndrew.Bardsley@arm.com 177810458Sandreas.hansson@arm.com @classmethod 177910458Sandreas.hansson@arm.com def cxx_ini_predecls(cls, code): 178010458Sandreas.hansson@arm.com code('#include <sstream>') 178110458Sandreas.hansson@arm.com 178210458Sandreas.hansson@arm.com @classmethod 178310458Sandreas.hansson@arm.com def cxx_ini_parse(self, code, src, dest, ret): 178410458Sandreas.hansson@arm.com code('%s (std::istringstream(%s) >> %s).eof();' % (ret, src, dest)) 178510458Sandreas.hansson@arm.com 17863101Sstever@eecs.umich.edu# 17873101Sstever@eecs.umich.edu# "Constants"... handy aliases for various values. 17883101Sstever@eecs.umich.edu# 17893101Sstever@eecs.umich.edu 17903102Sstever@eecs.umich.edu# Special class for NULL pointers. Note the special check in 17913102Sstever@eecs.umich.edu# make_param_value() above that lets these be assigned where a 17923102Sstever@eecs.umich.edu# SimObject is required. 17933102Sstever@eecs.umich.edu# only one copy of a particular node 17943102Sstever@eecs.umich.educlass NullSimObject(object): 17953102Sstever@eecs.umich.edu __metaclass__ = Singleton 179612197Sgabeblack@google.com _name = 'Null' 17973102Sstever@eecs.umich.edu 17983102Sstever@eecs.umich.edu def __call__(cls): 17993102Sstever@eecs.umich.edu return cls 18003102Sstever@eecs.umich.edu 18013102Sstever@eecs.umich.edu def _instantiate(self, parent = None, path = ''): 18023102Sstever@eecs.umich.edu pass 18033102Sstever@eecs.umich.edu 18043102Sstever@eecs.umich.edu def ini_str(self): 18053102Sstever@eecs.umich.edu return 'Null' 18063102Sstever@eecs.umich.edu 18073102Sstever@eecs.umich.edu def unproxy(self, base): 18083102Sstever@eecs.umich.edu return self 18093102Sstever@eecs.umich.edu 18103102Sstever@eecs.umich.edu def set_path(self, parent, name): 18113102Sstever@eecs.umich.edu pass 18124762Snate@binkert.org 181312192Sgabeblack@google.com def set_parent(self, parent, name): 181412192Sgabeblack@google.com pass 181512192Sgabeblack@google.com 181612195Sgabeblack@google.com def clear_parent(self, old_parent): 181712195Sgabeblack@google.com pass 181812195Sgabeblack@google.com 181912196Sgabeblack@google.com def descendants(self): 182012196Sgabeblack@google.com return 182112196Sgabeblack@google.com yield None 182212196Sgabeblack@google.com 182312200Sgabeblack@google.com def get_config_as_dict(self): 182412200Sgabeblack@google.com return {} 182512200Sgabeblack@google.com 18263102Sstever@eecs.umich.edu def __str__(self): 182712197Sgabeblack@google.com return self._name 18283102Sstever@eecs.umich.edu 182910380SAndrew.Bardsley@arm.com def config_value(self): 183010380SAndrew.Bardsley@arm.com return None 183110380SAndrew.Bardsley@arm.com 18324762Snate@binkert.org def getValue(self): 18334762Snate@binkert.org return None 18344762Snate@binkert.org 18353102Sstever@eecs.umich.edu# The only instance you'll ever need... 18363102Sstever@eecs.umich.eduNULL = NullSimObject() 18373102Sstever@eecs.umich.edu 18383102Sstever@eecs.umich.edudef isNullPointer(value): 18393102Sstever@eecs.umich.edu return isinstance(value, NullSimObject) 18403102Sstever@eecs.umich.edu 18413101Sstever@eecs.umich.edu# Some memory range specifications use this as a default upper bound. 18423101Sstever@eecs.umich.eduMaxAddr = Addr.max 18433101Sstever@eecs.umich.eduMaxTick = Tick.max 18443101Sstever@eecs.umich.eduAllMemory = AddrRange(0, MaxAddr) 18453101Sstever@eecs.umich.edu 18463101Sstever@eecs.umich.edu 18473101Sstever@eecs.umich.edu##################################################################### 18483101Sstever@eecs.umich.edu# 18493101Sstever@eecs.umich.edu# Port objects 18503101Sstever@eecs.umich.edu# 18513101Sstever@eecs.umich.edu# Ports are used to interconnect objects in the memory system. 18523101Sstever@eecs.umich.edu# 18533101Sstever@eecs.umich.edu##################################################################### 18543101Sstever@eecs.umich.edu 18553101Sstever@eecs.umich.edu# Port reference: encapsulates a reference to a particular port on a 18563101Sstever@eecs.umich.edu# particular SimObject. 18573101Sstever@eecs.umich.educlass PortRef(object): 185813869Sgabeblack@google.com def __init__(self, simobj, name, role, is_source): 18593105Sstever@eecs.umich.edu assert(isSimObject(simobj) or isSimObjectClass(simobj)) 18603101Sstever@eecs.umich.edu self.simobj = simobj 18613101Sstever@eecs.umich.edu self.name = name 18628839Sandreas.hansson@arm.com self.role = role 186313869Sgabeblack@google.com self.is_source = is_source 18643101Sstever@eecs.umich.edu self.peer = None # not associated with another port yet 18653101Sstever@eecs.umich.edu self.ccConnected = False # C++ port connection done? 18663105Sstever@eecs.umich.edu self.index = -1 # always -1 for non-vector ports 18673101Sstever@eecs.umich.edu 18683103Sstever@eecs.umich.edu def __str__(self): 18693105Sstever@eecs.umich.edu return '%s.%s' % (self.simobj, self.name) 18703103Sstever@eecs.umich.edu 18718840Sandreas.hansson@arm.com def __len__(self): 18728840Sandreas.hansson@arm.com # Return the number of connected ports, i.e. 0 is we have no 18738840Sandreas.hansson@arm.com # peer and 1 if we do. 18748840Sandreas.hansson@arm.com return int(self.peer != None) 18758840Sandreas.hansson@arm.com 18763105Sstever@eecs.umich.edu # for config.ini, print peer's name (not ours) 18773105Sstever@eecs.umich.edu def ini_str(self): 18783105Sstever@eecs.umich.edu return str(self.peer) 18793105Sstever@eecs.umich.edu 18809017Sandreas.hansson@arm.com # for config.json 18819017Sandreas.hansson@arm.com def get_config_as_dict(self): 188213869Sgabeblack@google.com return {'role' : self.role, 'peer' : str(self.peer), 188313869Sgabeblack@google.com 'is_source' : str(self.is_source)} 18849017Sandreas.hansson@arm.com 18853105Sstever@eecs.umich.edu def __getattr__(self, attr): 18863105Sstever@eecs.umich.edu if attr == 'peerObj': 18873105Sstever@eecs.umich.edu # shorthand for proxies 18883105Sstever@eecs.umich.edu return self.peer.simobj 188913663Sandreas.sandberg@arm.com raise AttributeError("'%s' object has no attribute '%s'" % \ 189013663Sandreas.sandberg@arm.com (self.__class__.__name__, attr)) 18913105Sstever@eecs.umich.edu 18923105Sstever@eecs.umich.edu # Full connection is symmetric (both ways). Called via 18933105Sstever@eecs.umich.edu # SimObject.__setattr__ as a result of a port assignment, e.g., 18943109Sstever@eecs.umich.edu # "obj1.portA = obj2.portB", or via VectorPortElementRef.__setitem__, 18953105Sstever@eecs.umich.edu # e.g., "obj1.portA[3] = obj2.portB". 18963105Sstever@eecs.umich.edu def connect(self, other): 18973105Sstever@eecs.umich.edu if isinstance(other, VectorPortRef): 18983105Sstever@eecs.umich.edu # reference to plain VectorPort is implicit append 18993105Sstever@eecs.umich.edu other = other._get_next() 19003105Sstever@eecs.umich.edu if self.peer and not proxy.isproxy(self.peer): 19019014Sandreas.hansson@arm.com fatal("Port %s is already connected to %s, cannot connect %s\n", 19029014Sandreas.hansson@arm.com self, self.peer, other); 19033101Sstever@eecs.umich.edu self.peer = other 190413869Sgabeblack@google.com 19053109Sstever@eecs.umich.edu if proxy.isproxy(other): 19063109Sstever@eecs.umich.edu other.set_param_desc(PortParamDesc()) 190713869Sgabeblack@google.com return 190813869Sgabeblack@google.com elif not isinstance(other, PortRef): 190913663Sandreas.sandberg@arm.com raise TypeError("assigning non-port reference '%s' to port '%s'" \ 191013663Sandreas.sandberg@arm.com % (other, self)) 19113101Sstever@eecs.umich.edu 191213869Sgabeblack@google.com if not Port.is_compat(self, other): 191313869Sgabeblack@google.com fatal("Ports %s and %s with roles '%s' and '%s' " 191413869Sgabeblack@google.com "are not compatible", self, other, self.role, other.role) 191513869Sgabeblack@google.com 191613869Sgabeblack@google.com if other.peer is not self: 191713869Sgabeblack@google.com other.connect(self) 191813869Sgabeblack@google.com 191913871Sgabeblack@google.com # Allow a compatible port pair to be spliced between a port and its 192013871Sgabeblack@google.com # connected peer. Useful operation for connecting instrumentation 192113871Sgabeblack@google.com # structures into a system when it is necessary to connect the 192213871Sgabeblack@google.com # instrumentation after the full system has been constructed. 192313871Sgabeblack@google.com def splice(self, new_1, new_2): 192413543Sgabeblack@google.com if not self.peer or proxy.isproxy(self.peer): 192513543Sgabeblack@google.com fatal("Port %s not connected, cannot splice in new peers\n", self) 192613543Sgabeblack@google.com 192713871Sgabeblack@google.com if not isinstance(new_1, PortRef) or not isinstance(new_2, PortRef): 192813663Sandreas.sandberg@arm.com raise TypeError( 192913543Sgabeblack@google.com "Splicing non-port references '%s','%s' to port '%s'" % \ 193013871Sgabeblack@google.com (new_1, new_2, self)) 193113543Sgabeblack@google.com 193213543Sgabeblack@google.com old_peer = self.peer 193313871Sgabeblack@google.com 193413871Sgabeblack@google.com if Port.is_compat(old_peer, new_1) and Port.is_compat(self, new_2): 193513871Sgabeblack@google.com old_peer.peer = new_1 193613871Sgabeblack@google.com new_1.peer = old_peer 193713871Sgabeblack@google.com self.peer = new_2 193813871Sgabeblack@google.com new_2.peer = self 193913871Sgabeblack@google.com elif Port.is_compat(old_peer, new_2) and Port.is_compat(self, new_1): 194013871Sgabeblack@google.com old_peer.peer = new_2 194113871Sgabeblack@google.com new_2.peer = old_peer 194213871Sgabeblack@google.com self.peer = new_1 194313871Sgabeblack@google.com new_1.peer = self 194410355SGeoffrey.Blake@arm.com else: 194513871Sgabeblack@google.com fatal("Ports %s(%s) and %s(%s) can't be compatibly spliced with " 194613871Sgabeblack@google.com "%s(%s) and %s(%s)", self, self.role, 194713871Sgabeblack@google.com old_peer, old_peer.role, new_1, new_1.role, 194813871Sgabeblack@google.com new_2, new_2.role) 194910355SGeoffrey.Blake@arm.com 19503105Sstever@eecs.umich.edu def clone(self, simobj, memo): 195113675Sandreas.sandberg@arm.com if self in memo: 19523105Sstever@eecs.umich.edu return memo[self] 19533101Sstever@eecs.umich.edu newRef = copy.copy(self) 19543105Sstever@eecs.umich.edu memo[self] = newRef 19553105Sstever@eecs.umich.edu newRef.simobj = simobj 19563101Sstever@eecs.umich.edu assert(isSimObject(newRef.simobj)) 19573105Sstever@eecs.umich.edu if self.peer and not proxy.isproxy(self.peer): 19583179Sstever@eecs.umich.edu peerObj = self.peer.simobj(_memo=memo) 19593105Sstever@eecs.umich.edu newRef.peer = self.peer.clone(peerObj, memo) 19603105Sstever@eecs.umich.edu assert(not isinstance(newRef.peer, VectorPortRef)) 19613101Sstever@eecs.umich.edu return newRef 19623101Sstever@eecs.umich.edu 19633105Sstever@eecs.umich.edu def unproxy(self, simobj): 19643105Sstever@eecs.umich.edu assert(simobj is self.simobj) 19653105Sstever@eecs.umich.edu if proxy.isproxy(self.peer): 19663105Sstever@eecs.umich.edu try: 19673105Sstever@eecs.umich.edu realPeer = self.peer.unproxy(self.simobj) 19683105Sstever@eecs.umich.edu except: 196912563Sgabeblack@google.com print("Error in unproxying port '%s' of %s" % 197012563Sgabeblack@google.com (self.name, self.simobj.path())) 19713105Sstever@eecs.umich.edu raise 19723105Sstever@eecs.umich.edu self.connect(realPeer) 19733105Sstever@eecs.umich.edu 19743101Sstever@eecs.umich.edu # Call C++ to create corresponding port connection between C++ objects 19753101Sstever@eecs.umich.edu def ccConnect(self): 197613594Snicholas.lindsay@arm.com if self.ccConnected: # already done this 19778839Sandreas.hansson@arm.com return 19788839Sandreas.hansson@arm.com 19793101Sstever@eecs.umich.edu peer = self.peer 19805578SSteve.Reinhardt@amd.com if not self.peer: # nothing to connect to 19815578SSteve.Reinhardt@amd.com return 19828839Sandreas.hansson@arm.com 198313783Sgabeblack@google.com port = self.simobj.getPort(self.name, self.index) 198413783Sgabeblack@google.com peer_port = peer.simobj.getPort(peer.name, peer.index) 198513783Sgabeblack@google.com port.bind(peer_port) 19868839Sandreas.hansson@arm.com 19873101Sstever@eecs.umich.edu self.ccConnected = True 19883101Sstever@eecs.umich.edu 19893105Sstever@eecs.umich.edu# A reference to an individual element of a VectorPort... much like a 19903105Sstever@eecs.umich.edu# PortRef, but has an index. 19913105Sstever@eecs.umich.educlass VectorPortElementRef(PortRef): 199213869Sgabeblack@google.com def __init__(self, simobj, name, role, is_source, index): 199313869Sgabeblack@google.com PortRef.__init__(self, simobj, name, role, is_source) 19943105Sstever@eecs.umich.edu self.index = index 19953105Sstever@eecs.umich.edu 19963105Sstever@eecs.umich.edu def __str__(self): 19973105Sstever@eecs.umich.edu return '%s.%s[%d]' % (self.simobj, self.name, self.index) 19983105Sstever@eecs.umich.edu 19993105Sstever@eecs.umich.edu# A reference to a complete vector-valued port (not just a single element). 20003105Sstever@eecs.umich.edu# Can be indexed to retrieve individual VectorPortElementRef instances. 20013105Sstever@eecs.umich.educlass VectorPortRef(object): 200213869Sgabeblack@google.com def __init__(self, simobj, name, role, is_source): 20033105Sstever@eecs.umich.edu assert(isSimObject(simobj) or isSimObjectClass(simobj)) 20043105Sstever@eecs.umich.edu self.simobj = simobj 20053105Sstever@eecs.umich.edu self.name = name 20068839Sandreas.hansson@arm.com self.role = role 200713869Sgabeblack@google.com self.is_source = is_source 20083105Sstever@eecs.umich.edu self.elements = [] 20093105Sstever@eecs.umich.edu 20103109Sstever@eecs.umich.edu def __str__(self): 20113109Sstever@eecs.umich.edu return '%s.%s[:]' % (self.simobj, self.name) 20123109Sstever@eecs.umich.edu 20138840Sandreas.hansson@arm.com def __len__(self): 20148840Sandreas.hansson@arm.com # Return the number of connected peers, corresponding the the 20158840Sandreas.hansson@arm.com # length of the elements. 20168840Sandreas.hansson@arm.com return len(self.elements) 20178840Sandreas.hansson@arm.com 20183105Sstever@eecs.umich.edu # for config.ini, print peer's name (not ours) 20193105Sstever@eecs.umich.edu def ini_str(self): 20203105Sstever@eecs.umich.edu return ' '.join([el.ini_str() for el in self.elements]) 20213105Sstever@eecs.umich.edu 20229017Sandreas.hansson@arm.com # for config.json 20239017Sandreas.hansson@arm.com def get_config_as_dict(self): 20249017Sandreas.hansson@arm.com return {'role' : self.role, 202513869Sgabeblack@google.com 'peer' : [el.ini_str() for el in self.elements], 202613869Sgabeblack@google.com 'is_source' : str(self.is_source)} 20279017Sandreas.hansson@arm.com 20283105Sstever@eecs.umich.edu def __getitem__(self, key): 20293105Sstever@eecs.umich.edu if not isinstance(key, int): 203013663Sandreas.sandberg@arm.com raise TypeError("VectorPort index must be integer") 20313105Sstever@eecs.umich.edu if key >= len(self.elements): 20323105Sstever@eecs.umich.edu # need to extend list 203313869Sgabeblack@google.com ext = [VectorPortElementRef( 203413869Sgabeblack@google.com self.simobj, self.name, self.role, self.is_source, i) 20353105Sstever@eecs.umich.edu for i in range(len(self.elements), key+1)] 20363105Sstever@eecs.umich.edu self.elements.extend(ext) 20373105Sstever@eecs.umich.edu return self.elements[key] 20383105Sstever@eecs.umich.edu 20393105Sstever@eecs.umich.edu def _get_next(self): 20403105Sstever@eecs.umich.edu return self[len(self.elements)] 20413105Sstever@eecs.umich.edu 20423105Sstever@eecs.umich.edu def __setitem__(self, key, value): 20433105Sstever@eecs.umich.edu if not isinstance(key, int): 204413663Sandreas.sandberg@arm.com raise TypeError("VectorPort index must be integer") 20453105Sstever@eecs.umich.edu self[key].connect(value) 20463105Sstever@eecs.umich.edu 20473105Sstever@eecs.umich.edu def connect(self, other): 20483109Sstever@eecs.umich.edu if isinstance(other, (list, tuple)): 20493109Sstever@eecs.umich.edu # Assign list of port refs to vector port. 20503109Sstever@eecs.umich.edu # For now, append them... not sure if that's the right semantics 20513109Sstever@eecs.umich.edu # or if it should replace the current vector. 20523109Sstever@eecs.umich.edu for ref in other: 20533109Sstever@eecs.umich.edu self._get_next().connect(ref) 20543109Sstever@eecs.umich.edu else: 20553109Sstever@eecs.umich.edu # scalar assignment to plain VectorPort is implicit append 20563109Sstever@eecs.umich.edu self._get_next().connect(other) 20573109Sstever@eecs.umich.edu 20583109Sstever@eecs.umich.edu def clone(self, simobj, memo): 205913675Sandreas.sandberg@arm.com if self in memo: 20603109Sstever@eecs.umich.edu return memo[self] 20613109Sstever@eecs.umich.edu newRef = copy.copy(self) 20623109Sstever@eecs.umich.edu memo[self] = newRef 20633109Sstever@eecs.umich.edu newRef.simobj = simobj 20643109Sstever@eecs.umich.edu assert(isSimObject(newRef.simobj)) 20653109Sstever@eecs.umich.edu newRef.elements = [el.clone(simobj, memo) for el in self.elements] 20663109Sstever@eecs.umich.edu return newRef 20673105Sstever@eecs.umich.edu 20683105Sstever@eecs.umich.edu def unproxy(self, simobj): 20693105Sstever@eecs.umich.edu [el.unproxy(simobj) for el in self.elements] 20703105Sstever@eecs.umich.edu 20713105Sstever@eecs.umich.edu def ccConnect(self): 20723105Sstever@eecs.umich.edu [el.ccConnect() for el in self.elements] 20733105Sstever@eecs.umich.edu 20743101Sstever@eecs.umich.edu# Port description object. Like a ParamDesc object, this represents a 20753101Sstever@eecs.umich.edu# logical port in the SimObject class, not a particular port on a 20763101Sstever@eecs.umich.edu# SimObject instance. The latter are represented by PortRef objects. 20773101Sstever@eecs.umich.educlass Port(object): 207813869Sgabeblack@google.com # Port("role", "description") 207913869Sgabeblack@google.com 208013869Sgabeblack@google.com _compat_dict = { } 208113869Sgabeblack@google.com 208213869Sgabeblack@google.com @classmethod 208313869Sgabeblack@google.com def compat(cls, role, peer): 208413869Sgabeblack@google.com cls._compat_dict.setdefault(role, set()).add(peer) 208513869Sgabeblack@google.com cls._compat_dict.setdefault(peer, set()).add(role) 208613869Sgabeblack@google.com 208713869Sgabeblack@google.com @classmethod 208813869Sgabeblack@google.com def is_compat(cls, one, two): 208913869Sgabeblack@google.com for port in one, two: 209013869Sgabeblack@google.com if not port.role in Port._compat_dict: 209113869Sgabeblack@google.com fatal("Unrecognized role '%s' for port %s\n", port.role, port) 209213869Sgabeblack@google.com return one.role in Port._compat_dict[two.role] 209313869Sgabeblack@google.com 209413869Sgabeblack@google.com def __init__(self, role, desc, is_source=False): 209513869Sgabeblack@google.com self.desc = desc 209613869Sgabeblack@google.com self.role = role 209713869Sgabeblack@google.com self.is_source = is_source 209813869Sgabeblack@google.com 20993101Sstever@eecs.umich.edu # Generate a PortRef for this port on the given SimObject with the 21003101Sstever@eecs.umich.edu # given name 21013105Sstever@eecs.umich.edu def makeRef(self, simobj): 210213869Sgabeblack@google.com return PortRef(simobj, self.name, self.role, self.is_source) 21033101Sstever@eecs.umich.edu 21043101Sstever@eecs.umich.edu # Connect an instance of this port (on the given SimObject with 21053101Sstever@eecs.umich.edu # the given name) with the port described by the supplied PortRef 21063105Sstever@eecs.umich.edu def connect(self, simobj, ref): 21073105Sstever@eecs.umich.edu self.makeRef(simobj).connect(ref) 21083101Sstever@eecs.umich.edu 21098840Sandreas.hansson@arm.com # No need for any pre-declarations at the moment as we merely rely 21108840Sandreas.hansson@arm.com # on an unsigned int. 21118840Sandreas.hansson@arm.com def cxx_predecls(self, code): 21128840Sandreas.hansson@arm.com pass 21138840Sandreas.hansson@arm.com 211411988Sandreas.sandberg@arm.com def pybind_predecls(self, code): 211511988Sandreas.sandberg@arm.com cls.cxx_predecls(self, code) 211611988Sandreas.sandberg@arm.com 21178840Sandreas.hansson@arm.com # Declare an unsigned int with the same name as the port, that 21188840Sandreas.hansson@arm.com # will eventually hold the number of connected ports (and thus the 21198840Sandreas.hansson@arm.com # number of elements for a VectorPort). 21208840Sandreas.hansson@arm.com def cxx_decl(self, code): 21218840Sandreas.hansson@arm.com code('unsigned int port_${{self.name}}_connection_count;') 21228840Sandreas.hansson@arm.com 212313890Sgabeblack@google.comPort.compat('GEM5 REQUESTER', 'GEM5 RESPONDER') 212413869Sgabeblack@google.com 212513890Sgabeblack@google.comclass RequestPort(Port): 212613890Sgabeblack@google.com # RequestPort("description") 212713869Sgabeblack@google.com def __init__(self, desc): 212813890Sgabeblack@google.com super(RequestPort, self).__init__( 212913890Sgabeblack@google.com 'GEM5 REQUESTER', desc, is_source=True) 21308839Sandreas.hansson@arm.com 213113890Sgabeblack@google.comclass ResponsePort(Port): 213213890Sgabeblack@google.com # ResponsePort("description") 213313869Sgabeblack@google.com def __init__(self, desc): 213413890Sgabeblack@google.com super(ResponsePort, self).__init__('GEM5 RESPONDER', desc) 21358839Sandreas.hansson@arm.com 21363101Sstever@eecs.umich.edu# VectorPort description object. Like Port, but represents a vector 213710405Sandreas.hansson@arm.com# of connections (e.g., as on a XBar). 21383101Sstever@eecs.umich.educlass VectorPort(Port): 21393105Sstever@eecs.umich.edu def makeRef(self, simobj): 214013869Sgabeblack@google.com return VectorPortRef(simobj, self.name, self.role, self.is_source) 21418839Sandreas.hansson@arm.com 214213890Sgabeblack@google.comclass VectorRequestPort(VectorPort): 214313890Sgabeblack@google.com # VectorRequestPort("description") 214413869Sgabeblack@google.com def __init__(self, desc): 214513890Sgabeblack@google.com super(VectorRequestPort, self).__init__( 214613890Sgabeblack@google.com 'GEM5 REQUESTER', desc, is_source=True) 21478839Sandreas.hansson@arm.com 214813890Sgabeblack@google.comclass VectorResponsePort(VectorPort): 214913890Sgabeblack@google.com # VectorResponsePort("description") 215013869Sgabeblack@google.com def __init__(self, desc): 215113890Sgabeblack@google.com super(VectorResponsePort, self).__init__('GEM5 RESPONDER', desc) 215213890Sgabeblack@google.com 215313890Sgabeblack@google.com# Old names, maintained for compatibility. 215413890Sgabeblack@google.comMasterPort = RequestPort 215513890Sgabeblack@google.comSlavePort = ResponsePort 215613890Sgabeblack@google.comVectorMasterPort = VectorRequestPort 215713890Sgabeblack@google.comVectorSlavePort = VectorResponsePort 21583105Sstever@eecs.umich.edu 21593109Sstever@eecs.umich.edu# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of 21603109Sstever@eecs.umich.edu# proxy objects (via set_param_desc()) so that proxy error messages 21613109Sstever@eecs.umich.edu# make sense. 21623109Sstever@eecs.umich.educlass PortParamDesc(object): 21633109Sstever@eecs.umich.edu __metaclass__ = Singleton 21643109Sstever@eecs.umich.edu 21653109Sstever@eecs.umich.edu ptype_str = 'Port' 21663109Sstever@eecs.umich.edu ptype = Port 21673105Sstever@eecs.umich.edu 21686654Snate@binkert.orgbaseEnums = allEnums.copy() 21696654Snate@binkert.orgbaseParams = allParams.copy() 21706654Snate@binkert.org 21716654Snate@binkert.orgdef clear(): 21726654Snate@binkert.org global allEnums, allParams 21736654Snate@binkert.org 21746654Snate@binkert.org allEnums = baseEnums.copy() 21756654Snate@binkert.org allParams = baseParams.copy() 21766654Snate@binkert.org 21773101Sstever@eecs.umich.edu__all__ = ['Param', 'VectorParam', 217813558Snikos.nikoleris@arm.com 'Enum', 'ScopedEnum', 'Bool', 'String', 'Float', 21793101Sstever@eecs.umich.edu 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 21803101Sstever@eecs.umich.edu 'Int32', 'UInt32', 'Int64', 'UInt64', 21813101Sstever@eecs.umich.edu 'Counter', 'Addr', 'Tick', 'Percent', 21823101Sstever@eecs.umich.edu 'TcpPort', 'UdpPort', 'EthernetAddr', 21837777Sgblack@eecs.umich.edu 'IpAddress', 'IpNetmask', 'IpWithPort', 21843101Sstever@eecs.umich.edu 'MemorySize', 'MemorySize32', 218512253Sgabeblack@google.com 'Latency', 'Frequency', 'Clock', 'Voltage', 'Current', 'Energy', 21863101Sstever@eecs.umich.edu 'NetworkBandwidth', 'MemoryBandwidth', 21879232Sandreas.hansson@arm.com 'AddrRange', 21883101Sstever@eecs.umich.edu 'MaxAddr', 'MaxTick', 'AllMemory', 21893885Sbinkertn@umich.edu 'Time', 21903102Sstever@eecs.umich.edu 'NextEthernetAddr', 'NULL', 219113890Sgabeblack@google.com 'Port', 'RequestPort', 'ResponsePort', 'MasterPort', 'SlavePort', 219213890Sgabeblack@google.com 'VectorPort', 'VectorRequestPort', 'VectorResponsePort', 219313890Sgabeblack@google.com 'VectorMasterPort', 'VectorSlavePort'] 2194