params.py revision 8664
113558Snikos.nikoleris@arm.com# Copyright (c) 2004-2006 The Regents of The University of Michigan 28839Sandreas.hansson@arm.com# Copyright (c) 2010-2011 Advanced Micro Devices, Inc. 38839Sandreas.hansson@arm.com# All rights reserved. 48839Sandreas.hansson@arm.com# 58839Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without 68839Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are 78839Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright 88839Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer; 98839Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright 108839Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the 118839Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution; 128839Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its 133101Sstever@eecs.umich.edu# contributors may be used to endorse or promote products derived from 148579Ssteve.reinhardt@amd.com# this software without specific prior written permission. 153101Sstever@eecs.umich.edu# 163101Sstever@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173101Sstever@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183101Sstever@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193101Sstever@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203101Sstever@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213101Sstever@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223101Sstever@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233101Sstever@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243101Sstever@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253101Sstever@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263101Sstever@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273101Sstever@eecs.umich.edu# 283101Sstever@eecs.umich.edu# Authors: Steve Reinhardt 293101Sstever@eecs.umich.edu# Nathan Binkert 303101Sstever@eecs.umich.edu# Gabe Black 313101Sstever@eecs.umich.edu 323101Sstever@eecs.umich.edu##################################################################### 333101Sstever@eecs.umich.edu# 343101Sstever@eecs.umich.edu# Parameter description classes 353101Sstever@eecs.umich.edu# 363101Sstever@eecs.umich.edu# The _params dictionary in each class maps parameter names to either 373101Sstever@eecs.umich.edu# a Param or a VectorParam object. These objects contain the 383101Sstever@eecs.umich.edu# parameter description string, the parameter type, and the default 393101Sstever@eecs.umich.edu# value (if any). The convert() method on these objects is used to 403101Sstever@eecs.umich.edu# force whatever value is assigned to the parameter to the appropriate 413101Sstever@eecs.umich.edu# type. 427778Sgblack@eecs.umich.edu# 438839Sandreas.hansson@arm.com# Note that the default values are loaded into the class's attribute 443101Sstever@eecs.umich.edu# space when the parameter dictionary is initialized (in 453101Sstever@eecs.umich.edu# MetaSimObject._new_param()); after that point they aren't used. 463101Sstever@eecs.umich.edu# 473101Sstever@eecs.umich.edu##################################################################### 483101Sstever@eecs.umich.edu 493101Sstever@eecs.umich.eduimport copy 503101Sstever@eecs.umich.eduimport datetime 513101Sstever@eecs.umich.eduimport re 523101Sstever@eecs.umich.eduimport sys 533101Sstever@eecs.umich.eduimport time 543101Sstever@eecs.umich.eduimport math 553101Sstever@eecs.umich.edu 563101Sstever@eecs.umich.eduimport proxy 573101Sstever@eecs.umich.eduimport ticks 583101Sstever@eecs.umich.edufrom util import * 593101Sstever@eecs.umich.edu 603101Sstever@eecs.umich.edudef isSimObject(*args, **kwargs): 613101Sstever@eecs.umich.edu return SimObject.isSimObject(*args, **kwargs) 6212563Sgabeblack@google.com 6312563Sgabeblack@google.comdef isSimObjectSequence(*args, **kwargs): 643885Sbinkertn@umich.edu return SimObject.isSimObjectSequence(*args, **kwargs) 653885Sbinkertn@umich.edu 664762Snate@binkert.orgdef isSimObjectClass(*args, **kwargs): 673885Sbinkertn@umich.edu return SimObject.isSimObjectClass(*args, **kwargs) 683885Sbinkertn@umich.edu 697528Ssteve.reinhardt@amd.comallParams = {} 703885Sbinkertn@umich.edu 714380Sbinkertn@umich.educlass MetaParamValue(type): 724167Sbinkertn@umich.edu def __new__(mcls, name, bases, dct): 733102Sstever@eecs.umich.edu cls = super(MetaParamValue, mcls).__new__(mcls, name, bases, dct) 743101Sstever@eecs.umich.edu assert name not in allParams 754762Snate@binkert.org allParams[name] = cls 764762Snate@binkert.org return cls 774762Snate@binkert.org 784762Snate@binkert.org 794762Snate@binkert.org# Dummy base class to identify types that are legitimate for SimObject 804762Snate@binkert.org# parameters. 814762Snate@binkert.orgclass ParamValue(object): 824762Snate@binkert.org __metaclass__ = MetaParamValue 834762Snate@binkert.org 845033Smilesck@eecs.umich.edu 855033Smilesck@eecs.umich.edu # Generate the code needed as a prerequisite for declaring a C++ 865033Smilesck@eecs.umich.edu # object of this type. Typically generates one or more #include 875033Smilesck@eecs.umich.edu # statements. Used when declaring parameters of this type. 885033Smilesck@eecs.umich.edu @classmethod 895033Smilesck@eecs.umich.edu def cxx_predecls(cls, code): 905033Smilesck@eecs.umich.edu pass 915033Smilesck@eecs.umich.edu 925033Smilesck@eecs.umich.edu # Generate the code needed as a prerequisite for including a 935033Smilesck@eecs.umich.edu # reference to a C++ object of this type in a SWIG .i file. 943101Sstever@eecs.umich.edu # Typically generates one or more %import or %include statements. 953101Sstever@eecs.umich.edu @classmethod 963101Sstever@eecs.umich.edu def swig_predecls(cls, code): 975033Smilesck@eecs.umich.edu pass 9810267SGeoffrey.Blake@arm.com 998596Ssteve.reinhardt@amd.com # default for printing to .ini file is regular string conversion. 1008596Ssteve.reinhardt@amd.com # will be overridden in some cases 1018596Ssteve.reinhardt@amd.com def ini_str(self): 1028596Ssteve.reinhardt@amd.com return str(self) 1037673Snate@binkert.org 1047673Snate@binkert.org # allows us to blithely call unproxy() on things without checking 1057673Snate@binkert.org # if they're really proxies or not 1067673Snate@binkert.org def unproxy(self, base): 10711988Sandreas.sandberg@arm.com return self 10811988Sandreas.sandberg@arm.com 10911988Sandreas.sandberg@arm.com# Regular parameter description. 11011988Sandreas.sandberg@arm.comclass ParamDesc(object): 1113101Sstever@eecs.umich.edu def __init__(self, ptype_str, ptype, *args, **kwargs): 1123101Sstever@eecs.umich.edu self.ptype_str = ptype_str 1133101Sstever@eecs.umich.edu # remember ptype only if it is provided 1143101Sstever@eecs.umich.edu if ptype != None: 1153101Sstever@eecs.umich.edu self.ptype = ptype 11610380SAndrew.Bardsley@arm.com 11710380SAndrew.Bardsley@arm.com if args: 11810380SAndrew.Bardsley@arm.com if len(args) == 1: 11910380SAndrew.Bardsley@arm.com self.desc = args[0] 12010380SAndrew.Bardsley@arm.com elif len(args) == 2: 12110380SAndrew.Bardsley@arm.com self.default = args[0] 12210458Sandreas.hansson@arm.com self.desc = args[1] 12310458Sandreas.hansson@arm.com else: 12410458Sandreas.hansson@arm.com raise TypeError, 'too many arguments' 12510458Sandreas.hansson@arm.com 12610458Sandreas.hansson@arm.com if kwargs.has_key('desc'): 12710458Sandreas.hansson@arm.com assert(not hasattr(self, 'desc')) 12810458Sandreas.hansson@arm.com self.desc = kwargs['desc'] 12910458Sandreas.hansson@arm.com del kwargs['desc'] 13010458Sandreas.hansson@arm.com 13110458Sandreas.hansson@arm.com if kwargs.has_key('default'): 13210458Sandreas.hansson@arm.com assert(not hasattr(self, 'default')) 13310458Sandreas.hansson@arm.com self.default = kwargs['default'] 1343101Sstever@eecs.umich.edu del kwargs['default'] 1353101Sstever@eecs.umich.edu 1363101Sstever@eecs.umich.edu if kwargs: 1373101Sstever@eecs.umich.edu raise TypeError, 'extra unknown kwargs %s' % kwargs 1383101Sstever@eecs.umich.edu 13910267SGeoffrey.Blake@arm.com if not hasattr(self, 'desc'): 14010267SGeoffrey.Blake@arm.com raise TypeError, 'desc attribute missing' 14110267SGeoffrey.Blake@arm.com 14210267SGeoffrey.Blake@arm.com def __getattr__(self, attr): 1433101Sstever@eecs.umich.edu if attr == 'ptype': 1443101Sstever@eecs.umich.edu ptype = SimObject.allClasses[self.ptype_str] 1453101Sstever@eecs.umich.edu assert isSimObjectClass(ptype) 1463101Sstever@eecs.umich.edu self.ptype = ptype 1473101Sstever@eecs.umich.edu return ptype 1483101Sstever@eecs.umich.edu 1493101Sstever@eecs.umich.edu raise AttributeError, "'%s' object has no attribute '%s'" % \ 1503101Sstever@eecs.umich.edu (type(self).__name__, attr) 1513101Sstever@eecs.umich.edu 1523101Sstever@eecs.umich.edu def convert(self, value): 1533101Sstever@eecs.umich.edu if isinstance(value, proxy.BaseProxy): 1543101Sstever@eecs.umich.edu value.set_param_desc(self) 1553101Sstever@eecs.umich.edu return value 1563101Sstever@eecs.umich.edu if not hasattr(self, 'ptype') and isNullPointer(value): 1573101Sstever@eecs.umich.edu # deferred evaluation of SimObject; continue to defer if 15813663Sandreas.sandberg@arm.com # we're just assigning a null pointer 1593101Sstever@eecs.umich.edu return value 16013675Sandreas.sandberg@arm.com if isinstance(value, self.ptype): 1613101Sstever@eecs.umich.edu return value 1623101Sstever@eecs.umich.edu if isNullPointer(value) and isSimObjectClass(self.ptype): 1633101Sstever@eecs.umich.edu return value 1643101Sstever@eecs.umich.edu return self.ptype(value) 16513675Sandreas.sandberg@arm.com 1663101Sstever@eecs.umich.edu def cxx_predecls(self, code): 1673101Sstever@eecs.umich.edu code('#include <cstddef>') 1683101Sstever@eecs.umich.edu self.ptype.cxx_predecls(code) 1693101Sstever@eecs.umich.edu 1703101Sstever@eecs.umich.edu def swig_predecls(self, code): 17113663Sandreas.sandberg@arm.com self.ptype.swig_predecls(code) 1723101Sstever@eecs.umich.edu 1733101Sstever@eecs.umich.edu def cxx_decl(self, code): 17413663Sandreas.sandberg@arm.com code('${{self.ptype.cxx_type}} ${{self.name}};') 1753101Sstever@eecs.umich.edu 1763101Sstever@eecs.umich.edu# Vector-valued parameter description. Just like ParamDesc, except 1773101Sstever@eecs.umich.edu# that the value is a vector (list) of the specified type instead of a 1785033Smilesck@eecs.umich.edu# single value. 1796656Snate@binkert.org 1805033Smilesck@eecs.umich.educlass VectorParamValue(list): 1815033Smilesck@eecs.umich.edu __metaclass__ = MetaParamValue 1825033Smilesck@eecs.umich.edu def __setattr__(self, attr, value): 18313663Sandreas.sandberg@arm.com raise AttributeError, \ 18413663Sandreas.sandberg@arm.com "Not allowed to set %s on '%s'" % (attr, type(self).__name__) 1853101Sstever@eecs.umich.edu 18610267SGeoffrey.Blake@arm.com def ini_str(self): 18710267SGeoffrey.Blake@arm.com return ' '.join([v.ini_str() for v in self]) 18810267SGeoffrey.Blake@arm.com 18910267SGeoffrey.Blake@arm.com def getValue(self): 19010267SGeoffrey.Blake@arm.com return [ v.getValue() for v in self ] 19110267SGeoffrey.Blake@arm.com 19210267SGeoffrey.Blake@arm.com def unproxy(self, base): 19310267SGeoffrey.Blake@arm.com if len(self) == 1 and isinstance(self[0], proxy.AllProxy): 19410267SGeoffrey.Blake@arm.com return self[0].unproxy(base) 19510267SGeoffrey.Blake@arm.com else: 19610267SGeoffrey.Blake@arm.com return [v.unproxy(base) for v in self] 19710267SGeoffrey.Blake@arm.com 19810267SGeoffrey.Blake@arm.comclass SimObjectVector(VectorParamValue): 1993101Sstever@eecs.umich.edu # support clone operation 2003101Sstever@eecs.umich.edu def __call__(self, **kwargs): 2013101Sstever@eecs.umich.edu return SimObjectVector([v(**kwargs) for v in self]) 2023101Sstever@eecs.umich.edu 2033101Sstever@eecs.umich.edu def clear_parent(self, old_parent): 2043101Sstever@eecs.umich.edu for v in self: 2053101Sstever@eecs.umich.edu v.clear_parent(old_parent) 2063101Sstever@eecs.umich.edu 2073101Sstever@eecs.umich.edu def set_parent(self, parent, name): 2083101Sstever@eecs.umich.edu if len(self) == 1: 2093102Sstever@eecs.umich.edu self[0].set_parent(parent, name) 2103101Sstever@eecs.umich.edu else: 2113101Sstever@eecs.umich.edu width = int(math.ceil(math.log(len(self))/math.log(10))) 2123101Sstever@eecs.umich.edu for i,v in enumerate(self): 21310267SGeoffrey.Blake@arm.com v.set_parent(parent, "%s%0*d" % (name, width, i)) 21410267SGeoffrey.Blake@arm.com 21510267SGeoffrey.Blake@arm.com def has_parent(self): 21610267SGeoffrey.Blake@arm.com return reduce(lambda x,y: x and y, [v.has_parent() for v in self]) 21710267SGeoffrey.Blake@arm.com 21810267SGeoffrey.Blake@arm.com # return 'cpu0 cpu1' etc. for print_ini() 21910267SGeoffrey.Blake@arm.com def get_name(self): 2207673Snate@binkert.org return ' '.join([v._name for v in self]) 2218607Sgblack@eecs.umich.edu 2227673Snate@binkert.org # By iterating through the constituent members of the vector here 2233101Sstever@eecs.umich.edu # we can nicely handle iterating over all a SimObject's children 22411988Sandreas.sandberg@arm.com # without having to provide lots of special functions on 22511988Sandreas.sandberg@arm.com # SimObjectVector directly. 22611988Sandreas.sandberg@arm.com def descendants(self): 2277673Snate@binkert.org for v in self: 2287673Snate@binkert.org for obj in v.descendants(): 2293101Sstever@eecs.umich.edu yield obj 2303101Sstever@eecs.umich.edu 2313101Sstever@eecs.umich.edu def get_config_as_dict(self): 2323101Sstever@eecs.umich.edu a = [] 2333101Sstever@eecs.umich.edu for v in self: 2343101Sstever@eecs.umich.edu a.append(v.get_config_as_dict()) 2355033Smilesck@eecs.umich.edu return a 2365475Snate@binkert.org 23713663Sandreas.sandberg@arm.comclass VectorParamDesc(ParamDesc): 23813663Sandreas.sandberg@arm.com # Convert assigned value to appropriate type. If the RHS is not a 2395475Snate@binkert.org # list or tuple, it generates a single-element list. 24010380SAndrew.Bardsley@arm.com def convert(self, value): 24110380SAndrew.Bardsley@arm.com if isinstance(value, (list, tuple)): 24210380SAndrew.Bardsley@arm.com # list: coerce each element into new list 2433101Sstever@eecs.umich.edu tmp_list = [ ParamDesc.convert(self, v) for v in value ] 2443101Sstever@eecs.umich.edu else: 2453101Sstever@eecs.umich.edu # singleton: coerce to a single-element list 2464762Snate@binkert.org tmp_list = [ ParamDesc.convert(self, value) ] 2474762Snate@binkert.org 2484762Snate@binkert.org if isSimObjectSequence(tmp_list): 2493101Sstever@eecs.umich.edu return SimObjectVector(tmp_list) 25012050Snikos.nikoleris@arm.com else: 25112050Snikos.nikoleris@arm.com return VectorParamValue(tmp_list) 25212050Snikos.nikoleris@arm.com 2538459SAli.Saidi@ARM.com def swig_module_name(self): 2548459SAli.Saidi@ARM.com return "%s_vector" % self.ptype_str 25512050Snikos.nikoleris@arm.com 2563101Sstever@eecs.umich.edu def swig_predecls(self, code): 2577528Ssteve.reinhardt@amd.com code('%import "${{self.swig_module_name()}}.i"') 2587528Ssteve.reinhardt@amd.com 2597528Ssteve.reinhardt@amd.com def swig_decl(self, code): 2607528Ssteve.reinhardt@amd.com code('%module(package="m5.internal") ${{self.swig_module_name()}}') 2617528Ssteve.reinhardt@amd.com code('%{') 2627528Ssteve.reinhardt@amd.com self.ptype.cxx_predecls(code) 2633101Sstever@eecs.umich.edu code('%}') 2647528Ssteve.reinhardt@amd.com code() 2657528Ssteve.reinhardt@amd.com # Make sure the SWIGPY_SLICE_ARG is defined through this inclusion 2667528Ssteve.reinhardt@amd.com code('%include "std_container.i"') 2677528Ssteve.reinhardt@amd.com code() 2687528Ssteve.reinhardt@amd.com self.ptype.swig_predecls(code) 2697528Ssteve.reinhardt@amd.com code() 2707528Ssteve.reinhardt@amd.com code('%include "std_vector.i"') 2717528Ssteve.reinhardt@amd.com code() 2727528Ssteve.reinhardt@amd.com 2737528Ssteve.reinhardt@amd.com ptype = self.ptype_str 2748321Ssteve.reinhardt@amd.com cxx_type = self.ptype.cxx_type 27512194Sgabeblack@google.com 2767528Ssteve.reinhardt@amd.com code('''\ 2777528Ssteve.reinhardt@amd.com%typemap(in) std::vector< $cxx_type >::value_type { 2787528Ssteve.reinhardt@amd.com if (SWIG_ConvertPtr($$input, (void **)&$$1, $$1_descriptor, 0) == -1) { 2797528Ssteve.reinhardt@amd.com if (SWIG_ConvertPtr($$input, (void **)&$$1, 2807528Ssteve.reinhardt@amd.com $$descriptor($cxx_type), 0) == -1) { 2817528Ssteve.reinhardt@amd.com return NULL; 2827528Ssteve.reinhardt@amd.com } 2837528Ssteve.reinhardt@amd.com } 2847528Ssteve.reinhardt@amd.com} 2857528Ssteve.reinhardt@amd.com 2867528Ssteve.reinhardt@amd.com%typemap(in) std::vector< $cxx_type >::value_type * { 2877528Ssteve.reinhardt@amd.com if (SWIG_ConvertPtr($$input, (void **)&$$1, $$1_descriptor, 0) == -1) { 2887528Ssteve.reinhardt@amd.com if (SWIG_ConvertPtr($$input, (void **)&$$1, 2893101Sstever@eecs.umich.edu $$descriptor($cxx_type *), 0) == -1) { 2908664SAli.Saidi@ARM.com return NULL; 2918664SAli.Saidi@ARM.com } 2928664SAli.Saidi@ARM.com } 2938664SAli.Saidi@ARM.com} 2948664SAli.Saidi@ARM.com''') 2958664SAli.Saidi@ARM.com 2969953Sgeoffrey.blake@arm.com code('%template(vector_$ptype) std::vector< $cxx_type >;') 2979953Sgeoffrey.blake@arm.com 2989953Sgeoffrey.blake@arm.com def cxx_predecls(self, code): 2999953Sgeoffrey.blake@arm.com code('#include <vector>') 3009953Sgeoffrey.blake@arm.com self.ptype.cxx_predecls(code) 3019953Sgeoffrey.blake@arm.com 3029953Sgeoffrey.blake@arm.com def cxx_decl(self, code): 3039953Sgeoffrey.blake@arm.com code('std::vector< ${{self.ptype.cxx_type}} > ${{self.name}};') 3049953Sgeoffrey.blake@arm.com 3059953Sgeoffrey.blake@arm.comclass ParamFactory(object): 3069953Sgeoffrey.blake@arm.com def __init__(self, param_desc_class, ptype_str = None): 3079953Sgeoffrey.blake@arm.com self.param_desc_class = param_desc_class 3089953Sgeoffrey.blake@arm.com self.ptype_str = ptype_str 30910267SGeoffrey.Blake@arm.com 31010267SGeoffrey.Blake@arm.com def __getattr__(self, attr): 31110267SGeoffrey.Blake@arm.com if self.ptype_str: 31210267SGeoffrey.Blake@arm.com attr = self.ptype_str + '.' + attr 31310267SGeoffrey.Blake@arm.com return ParamFactory(self.param_desc_class, attr) 31410267SGeoffrey.Blake@arm.com 31510267SGeoffrey.Blake@arm.com # E.g., Param.Int(5, "number of widgets") 31612563Sgabeblack@google.com def __call__(self, *args, **kwargs): 31710267SGeoffrey.Blake@arm.com ptype = None 31810267SGeoffrey.Blake@arm.com try: 31910267SGeoffrey.Blake@arm.com ptype = allParams[self.ptype_str] 32010267SGeoffrey.Blake@arm.com except KeyError: 32110267SGeoffrey.Blake@arm.com # if name isn't defined yet, assume it's a SimObject, and 32210267SGeoffrey.Blake@arm.com # try to resolve it later 32310267SGeoffrey.Blake@arm.com pass 32410267SGeoffrey.Blake@arm.com return self.param_desc_class(self.ptype_str, ptype, *args, **kwargs) 32510267SGeoffrey.Blake@arm.com 32610267SGeoffrey.Blake@arm.comParam = ParamFactory(ParamDesc) 32710267SGeoffrey.Blake@arm.comVectorParam = ParamFactory(VectorParamDesc) 32810267SGeoffrey.Blake@arm.com 3293101Sstever@eecs.umich.edu##################################################################### 3303101Sstever@eecs.umich.edu# 3313101Sstever@eecs.umich.edu# Parameter Types 3323101Sstever@eecs.umich.edu# 3333101Sstever@eecs.umich.edu# Though native Python types could be used to specify parameter types 3343101Sstever@eecs.umich.edu# (the 'ptype' field of the Param and VectorParam classes), it's more 3353101Sstever@eecs.umich.edu# flexible to define our own set of types. This gives us more control 33610364SGeoffrey.Blake@arm.com# over how Python expressions are converted to values (via the 33710364SGeoffrey.Blake@arm.com# __init__() constructor) and how these values are printed out (via 33810364SGeoffrey.Blake@arm.com# the __str__() conversion method). 33910364SGeoffrey.Blake@arm.com# 3403101Sstever@eecs.umich.edu##################################################################### 3414762Snate@binkert.org 3424762Snate@binkert.org# String-valued parameter. Just mixin the ParamValue class with the 3434762Snate@binkert.org# built-in str class. 3444762Snate@binkert.orgclass String(ParamValue,str): 3457528Ssteve.reinhardt@amd.com cxx_type = 'std::string' 3464762Snate@binkert.org 3474762Snate@binkert.org @classmethod 3484762Snate@binkert.org def cxx_predecls(self, code): 34910267SGeoffrey.Blake@arm.com code('#include <string>') 35010267SGeoffrey.Blake@arm.com 35110267SGeoffrey.Blake@arm.com @classmethod 35210267SGeoffrey.Blake@arm.com def swig_predecls(cls, code): 35310267SGeoffrey.Blake@arm.com code('%include "std_string.i"') 35410267SGeoffrey.Blake@arm.com 35510267SGeoffrey.Blake@arm.com def getValue(self): 35610267SGeoffrey.Blake@arm.com return self 35710267SGeoffrey.Blake@arm.com 35810267SGeoffrey.Blake@arm.com# superclass for "numeric" parameter values, to emulate math 35910267SGeoffrey.Blake@arm.com# operations in a type-safe way. e.g., a Latency times an int returns 36010267SGeoffrey.Blake@arm.com# a new Latency object. 36110267SGeoffrey.Blake@arm.comclass NumericParamValue(ParamValue): 36210267SGeoffrey.Blake@arm.com def __str__(self): 36310267SGeoffrey.Blake@arm.com return str(self.value) 36410267SGeoffrey.Blake@arm.com 36510267SGeoffrey.Blake@arm.com def __float__(self): 36610267SGeoffrey.Blake@arm.com return float(self.value) 36710267SGeoffrey.Blake@arm.com 36810267SGeoffrey.Blake@arm.com def __long__(self): 36910267SGeoffrey.Blake@arm.com return long(self.value) 37010267SGeoffrey.Blake@arm.com 37110267SGeoffrey.Blake@arm.com def __int__(self): 37210267SGeoffrey.Blake@arm.com return int(self.value) 37310267SGeoffrey.Blake@arm.com 37410267SGeoffrey.Blake@arm.com # hook for bounds checking 37510364SGeoffrey.Blake@arm.com def _check(self): 37610364SGeoffrey.Blake@arm.com return 37710267SGeoffrey.Blake@arm.com 37810267SGeoffrey.Blake@arm.com def __mul__(self, other): 37910267SGeoffrey.Blake@arm.com newobj = self.__class__(self) 38010267SGeoffrey.Blake@arm.com newobj.value *= other 38110267SGeoffrey.Blake@arm.com newobj._check() 38210267SGeoffrey.Blake@arm.com return newobj 3837673Snate@binkert.org 3847673Snate@binkert.org __rmul__ = __mul__ 3857673Snate@binkert.org 3863101Sstever@eecs.umich.edu def __div__(self, other): 38711988Sandreas.sandberg@arm.com newobj = self.__class__(self) 38811988Sandreas.sandberg@arm.com newobj.value /= other 38911988Sandreas.sandberg@arm.com newobj._check() 39011988Sandreas.sandberg@arm.com return newobj 3917673Snate@binkert.org 3927673Snate@binkert.org def __sub__(self, other): 3933101Sstever@eecs.umich.edu newobj = self.__class__(self) 3943101Sstever@eecs.umich.edu newobj.value -= other 3953101Sstever@eecs.umich.edu newobj._check() 3963101Sstever@eecs.umich.edu return newobj 3973101Sstever@eecs.umich.edu 3983101Sstever@eecs.umich.edu# Metaclass for bounds-checked integer parameters. See CheckedInt. 3993101Sstever@eecs.umich.educlass CheckedIntType(MetaParamValue): 4003101Sstever@eecs.umich.edu def __init__(cls, name, bases, dict): 4013101Sstever@eecs.umich.edu super(CheckedIntType, cls).__init__(name, bases, dict) 4023101Sstever@eecs.umich.edu 4033101Sstever@eecs.umich.edu # CheckedInt is an abstract base class, so we actually don't 4043101Sstever@eecs.umich.edu # want to do any processing on it... the rest of this code is 4053101Sstever@eecs.umich.edu # just for classes that derive from CheckedInt. 4063101Sstever@eecs.umich.edu if name == 'CheckedInt': 4073101Sstever@eecs.umich.edu return 4085033Smilesck@eecs.umich.edu 4095033Smilesck@eecs.umich.edu if not (hasattr(cls, 'min') and hasattr(cls, 'max')): 4103101Sstever@eecs.umich.edu if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')): 4113101Sstever@eecs.umich.edu panic("CheckedInt subclass %s must define either\n" \ 4123101Sstever@eecs.umich.edu " 'min' and 'max' or 'size' and 'unsigned'\n", 4133101Sstever@eecs.umich.edu name); 4143101Sstever@eecs.umich.edu if cls.unsigned: 4153101Sstever@eecs.umich.edu cls.min = 0 4163101Sstever@eecs.umich.edu cls.max = 2 ** cls.size - 1 4173101Sstever@eecs.umich.edu else: 4183101Sstever@eecs.umich.edu cls.min = -(2 ** (cls.size - 1)) 4193101Sstever@eecs.umich.edu cls.max = (2 ** (cls.size - 1)) - 1 4203101Sstever@eecs.umich.edu 4213101Sstever@eecs.umich.edu# Abstract superclass for bounds-checked integer parameters. This 4223101Sstever@eecs.umich.edu# class is subclassed to generate parameter classes with specific 4233101Sstever@eecs.umich.edu# bounds. Initialization of the min and max bounds is done in the 4243101Sstever@eecs.umich.edu# metaclass CheckedIntType.__init__. 4253101Sstever@eecs.umich.educlass CheckedInt(NumericParamValue): 4263101Sstever@eecs.umich.edu __metaclass__ = CheckedIntType 4273101Sstever@eecs.umich.edu 4283101Sstever@eecs.umich.edu def _check(self): 4293101Sstever@eecs.umich.edu if not self.min <= self.value <= self.max: 4303101Sstever@eecs.umich.edu raise TypeError, 'Integer param out of bounds %d < %d < %d' % \ 4313101Sstever@eecs.umich.edu (self.min, self.value, self.max) 4323101Sstever@eecs.umich.edu 4333101Sstever@eecs.umich.edu def __init__(self, value): 4343101Sstever@eecs.umich.edu if isinstance(value, str): 43510267SGeoffrey.Blake@arm.com self.value = convert.toInteger(value) 4367673Snate@binkert.org elif isinstance(value, (int, long, float, NumericParamValue)): 4377673Snate@binkert.org self.value = long(value) 4387673Snate@binkert.org else: 4397673Snate@binkert.org raise TypeError, "Can't convert object of type %s to CheckedInt" \ 4407673Snate@binkert.org % type(value).__name__ 44110267SGeoffrey.Blake@arm.com self._check() 44210267SGeoffrey.Blake@arm.com 44310267SGeoffrey.Blake@arm.com @classmethod 44410267SGeoffrey.Blake@arm.com def cxx_predecls(cls, code): 44510458Sandreas.hansson@arm.com # most derived types require this, so we just do it here once 44610458Sandreas.hansson@arm.com code('#include "base/types.hh"') 44710458Sandreas.hansson@arm.com 44810458Sandreas.hansson@arm.com @classmethod 44910458Sandreas.hansson@arm.com def swig_predecls(cls, code): 4504762Snate@binkert.org # most derived types require this, so we just do it here once 4514762Snate@binkert.org code('%import "stdint.i"') 4523101Sstever@eecs.umich.edu code('%import "base/types.hh"') 4533101Sstever@eecs.umich.edu 4543101Sstever@eecs.umich.edu def getValue(self): 4553101Sstever@eecs.umich.edu return long(self.value) 4563101Sstever@eecs.umich.edu 4573101Sstever@eecs.umich.educlass Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False 4583101Sstever@eecs.umich.educlass Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True 4593101Sstever@eecs.umich.edu 4603101Sstever@eecs.umich.educlass Int8(CheckedInt): cxx_type = 'int8_t'; size = 8; unsigned = False 4613101Sstever@eecs.umich.educlass UInt8(CheckedInt): cxx_type = 'uint8_t'; size = 8; unsigned = True 4623101Sstever@eecs.umich.educlass Int16(CheckedInt): cxx_type = 'int16_t'; size = 16; unsigned = False 4633714Sstever@eecs.umich.educlass UInt16(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 4643714Sstever@eecs.umich.educlass Int32(CheckedInt): cxx_type = 'int32_t'; size = 32; unsigned = False 4653714Sstever@eecs.umich.educlass UInt32(CheckedInt): cxx_type = 'uint32_t'; size = 32; unsigned = True 4663714Sstever@eecs.umich.educlass Int64(CheckedInt): cxx_type = 'int64_t'; size = 64; unsigned = False 4673714Sstever@eecs.umich.educlass UInt64(CheckedInt): cxx_type = 'uint64_t'; size = 64; unsigned = True 4683714Sstever@eecs.umich.edu 4693101Sstever@eecs.umich.educlass Counter(CheckedInt): cxx_type = 'Counter'; size = 64; unsigned = True 4703101Sstever@eecs.umich.educlass Tick(CheckedInt): cxx_type = 'Tick'; size = 64; unsigned = True 4713101Sstever@eecs.umich.educlass TcpPort(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 4723101Sstever@eecs.umich.educlass UdpPort(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 4733101Sstever@eecs.umich.edu 4743101Sstever@eecs.umich.educlass Percent(CheckedInt): cxx_type = 'int'; min = 0; max = 100 4753101Sstever@eecs.umich.edu 4763101Sstever@eecs.umich.educlass Float(ParamValue, float): 4773101Sstever@eecs.umich.edu cxx_type = 'double' 4783101Sstever@eecs.umich.edu 4793101Sstever@eecs.umich.edu def __init__(self, value): 4803101Sstever@eecs.umich.edu if isinstance(value, (int, long, float, NumericParamValue, Float)): 4813101Sstever@eecs.umich.edu self.value = float(value) 4823101Sstever@eecs.umich.edu else: 4833101Sstever@eecs.umich.edu raise TypeError, "Can't convert object of type %s to Float" \ 4843101Sstever@eecs.umich.edu % type(value).__name__ 4853101Sstever@eecs.umich.edu 4863101Sstever@eecs.umich.edu def getValue(self): 4873101Sstever@eecs.umich.edu return float(self.value) 4883101Sstever@eecs.umich.edu 4893101Sstever@eecs.umich.educlass MemorySize(CheckedInt): 4903101Sstever@eecs.umich.edu cxx_type = 'uint64_t' 4913101Sstever@eecs.umich.edu size = 64 4923101Sstever@eecs.umich.edu unsigned = True 49310380SAndrew.Bardsley@arm.com def __init__(self, value): 49410380SAndrew.Bardsley@arm.com if isinstance(value, MemorySize): 49510380SAndrew.Bardsley@arm.com self.value = value.value 49610458Sandreas.hansson@arm.com else: 49710458Sandreas.hansson@arm.com self.value = convert.toMemorySize(value) 49810458Sandreas.hansson@arm.com self._check() 49910458Sandreas.hansson@arm.com 50010458Sandreas.hansson@arm.comclass MemorySize32(CheckedInt): 50110458Sandreas.hansson@arm.com cxx_type = 'uint32_t' 50210458Sandreas.hansson@arm.com size = 32 50310458Sandreas.hansson@arm.com unsigned = True 50410458Sandreas.hansson@arm.com def __init__(self, value): 50510458Sandreas.hansson@arm.com if isinstance(value, MemorySize): 50610458Sandreas.hansson@arm.com self.value = value.value 50710458Sandreas.hansson@arm.com else: 50810458Sandreas.hansson@arm.com self.value = convert.toMemorySize(value) 5093101Sstever@eecs.umich.edu self._check() 5105033Smilesck@eecs.umich.edu 5113101Sstever@eecs.umich.educlass Addr(CheckedInt): 5123101Sstever@eecs.umich.edu cxx_type = 'Addr' 5133101Sstever@eecs.umich.edu size = 64 5143101Sstever@eecs.umich.edu unsigned = True 5153101Sstever@eecs.umich.edu def __init__(self, value): 5163101Sstever@eecs.umich.edu if isinstance(value, Addr): 5173101Sstever@eecs.umich.edu self.value = value.value 5183101Sstever@eecs.umich.edu else: 5193101Sstever@eecs.umich.edu try: 5203101Sstever@eecs.umich.edu self.value = convert.toMemorySize(value) 5213101Sstever@eecs.umich.edu except TypeError: 5223101Sstever@eecs.umich.edu self.value = long(value) 5235822Ssaidi@eecs.umich.edu self._check() 5245822Ssaidi@eecs.umich.edu def __add__(self, other): 5253101Sstever@eecs.umich.edu if isinstance(other, Addr): 5263101Sstever@eecs.umich.edu return self.value + other.value 5273101Sstever@eecs.umich.edu else: 5283101Sstever@eecs.umich.edu return self.value + other 5293101Sstever@eecs.umich.edu 5303101Sstever@eecs.umich.edu 5313101Sstever@eecs.umich.educlass MetaRange(MetaParamValue): 5323101Sstever@eecs.umich.edu def __init__(cls, name, bases, dict): 5333101Sstever@eecs.umich.edu super(MetaRange, cls).__init__(name, bases, dict) 5343101Sstever@eecs.umich.edu if name == 'Range': 5353101Sstever@eecs.umich.edu return 5363101Sstever@eecs.umich.edu cls.cxx_type = 'Range< %s >' % cls.type.cxx_type 5373101Sstever@eecs.umich.edu 53810267SGeoffrey.Blake@arm.comclass Range(ParamValue): 5393101Sstever@eecs.umich.edu __metaclass__ = MetaRange 5403101Sstever@eecs.umich.edu type = Int # default; can be overridden in subclasses 5413101Sstever@eecs.umich.edu def __init__(self, *args, **kwargs): 54213663Sandreas.sandberg@arm.com def handle_kwargs(self, kwargs): 54313663Sandreas.sandberg@arm.com if 'end' in kwargs: 5443101Sstever@eecs.umich.edu self.second = self.type(kwargs.pop('end')) 5453101Sstever@eecs.umich.edu elif 'size' in kwargs: 5463101Sstever@eecs.umich.edu self.second = self.first + self.type(kwargs.pop('size')) - 1 5473102Sstever@eecs.umich.edu else: 5483714Sstever@eecs.umich.edu raise TypeError, "Either end or size must be specified" 5493101Sstever@eecs.umich.edu 5503714Sstever@eecs.umich.edu if len(args) == 0: 55113663Sandreas.sandberg@arm.com self.first = self.type(kwargs.pop('start')) 55213663Sandreas.sandberg@arm.com handle_kwargs(self, kwargs) 5533101Sstever@eecs.umich.edu 5543101Sstever@eecs.umich.edu elif len(args) == 1: 55510267SGeoffrey.Blake@arm.com if kwargs: 55610267SGeoffrey.Blake@arm.com self.first = self.type(args[0]) 55710267SGeoffrey.Blake@arm.com handle_kwargs(self, kwargs) 55810267SGeoffrey.Blake@arm.com elif isinstance(args[0], Range): 5597673Snate@binkert.org self.first = self.type(args[0].first) 5607673Snate@binkert.org self.second = self.type(args[0].second) 5617673Snate@binkert.org elif isinstance(args[0], (list, tuple)): 5627673Snate@binkert.org self.first = self.type(args[0][0]) 5637673Snate@binkert.org self.second = self.type(args[0][1]) 5644762Snate@binkert.org else: 5654762Snate@binkert.org self.first = self.type(0) 5664762Snate@binkert.org self.second = self.type(args[0]) - 1 5673101Sstever@eecs.umich.edu 5683101Sstever@eecs.umich.edu elif len(args) == 2: 5693101Sstever@eecs.umich.edu self.first = self.type(args[0]) 5703101Sstever@eecs.umich.edu self.second = self.type(args[1]) 5713101Sstever@eecs.umich.edu else: 5723101Sstever@eecs.umich.edu raise TypeError, "Too many arguments specified" 5733101Sstever@eecs.umich.edu 5743101Sstever@eecs.umich.edu if kwargs: 5753101Sstever@eecs.umich.edu raise TypeError, "too many keywords: %s" % kwargs.keys() 5763101Sstever@eecs.umich.edu 5773101Sstever@eecs.umich.edu def __str__(self): 5783101Sstever@eecs.umich.edu return '%s:%s' % (self.first, self.second) 5793101Sstever@eecs.umich.edu 5803101Sstever@eecs.umich.edu @classmethod 5813101Sstever@eecs.umich.edu def cxx_predecls(cls, code): 5823101Sstever@eecs.umich.edu cls.type.cxx_predecls(code) 5833101Sstever@eecs.umich.edu code('#include "base/range.hh"') 5843101Sstever@eecs.umich.edu 5853101Sstever@eecs.umich.edu @classmethod 5869184Sandreas.hansson@arm.com def swig_predecls(cls, code): 5879184Sandreas.hansson@arm.com cls.type.swig_predecls(code) 5889184Sandreas.hansson@arm.com code('%import "python/swig/range.i"') 5899184Sandreas.hansson@arm.com 5909184Sandreas.hansson@arm.comclass AddrRange(Range): 5919184Sandreas.hansson@arm.com type = Addr 59211802Sandreas.sandberg@arm.com 5939184Sandreas.hansson@arm.com def getValue(self): 5949184Sandreas.hansson@arm.com from m5.internal.range import AddrRange 59510458Sandreas.hansson@arm.com 59610458Sandreas.hansson@arm.com value = AddrRange() 59710458Sandreas.hansson@arm.com value.start = long(self.first) 59810458Sandreas.hansson@arm.com value.end = long(self.second) 59910458Sandreas.hansson@arm.com return value 60010458Sandreas.hansson@arm.com 60110458Sandreas.hansson@arm.comclass TickRange(Range): 60210458Sandreas.hansson@arm.com type = Tick 60310458Sandreas.hansson@arm.com 60410458Sandreas.hansson@arm.com def getValue(self): 60510458Sandreas.hansson@arm.com from m5.internal.range import TickRange 60610458Sandreas.hansson@arm.com 60710458Sandreas.hansson@arm.com value = TickRange() 60810458Sandreas.hansson@arm.com value.start = long(self.first) 6093101Sstever@eecs.umich.edu value.end = long(self.second) 6104446Sbinkertn@umich.edu return value 61110668SGeoffrey.Blake@arm.com 6123101Sstever@eecs.umich.edu# Boolean parameter type. Python doesn't let you subclass bool, since 6135468Snate@binkert.org# it doesn't want to let you create multiple instances of True and 61410267SGeoffrey.Blake@arm.com# False. Thus this is a little more complicated than String. 6155468Snate@binkert.orgclass Bool(ParamValue): 6165468Snate@binkert.org cxx_type = 'bool' 61713663Sandreas.sandberg@arm.com def __init__(self, value): 61813663Sandreas.sandberg@arm.com try: 6195468Snate@binkert.org self.value = convert.toBool(value) 62010267SGeoffrey.Blake@arm.com except TypeError: 62110267SGeoffrey.Blake@arm.com self.value = bool(value) 62210267SGeoffrey.Blake@arm.com 62310267SGeoffrey.Blake@arm.com def getValue(self): 6244762Snate@binkert.org return bool(self.value) 6254762Snate@binkert.org 6264762Snate@binkert.org def __str__(self): 62710380SAndrew.Bardsley@arm.com return str(self.value) 62810380SAndrew.Bardsley@arm.com 62910380SAndrew.Bardsley@arm.com def ini_str(self): 63010458Sandreas.hansson@arm.com if self.value: 63110458Sandreas.hansson@arm.com return 'true' 63210458Sandreas.hansson@arm.com return 'false' 63310458Sandreas.hansson@arm.com 63410458Sandreas.hansson@arm.comdef IncEthernetAddr(addr, val = 1): 63510458Sandreas.hansson@arm.com bytes = map(lambda x: int(x, 16), addr.split(':')) 63610458Sandreas.hansson@arm.com bytes[5] += val 63710458Sandreas.hansson@arm.com for i in (5, 4, 3, 2, 1): 6383101Sstever@eecs.umich.edu val,rem = divmod(bytes[i], 256) 6393101Sstever@eecs.umich.edu bytes[i] = rem 64010267SGeoffrey.Blake@arm.com if val == 0: 6413101Sstever@eecs.umich.edu break 6423101Sstever@eecs.umich.edu bytes[i - 1] += val 6433101Sstever@eecs.umich.edu assert(bytes[0] <= 255) 6443101Sstever@eecs.umich.edu return ':'.join(map(lambda x: '%02x' % x, bytes)) 6453101Sstever@eecs.umich.edu 6463101Sstever@eecs.umich.edu_NextEthernetAddr = "00:90:00:00:00:01" 6473102Sstever@eecs.umich.edudef NextEthernetAddr(): 6483101Sstever@eecs.umich.edu global _NextEthernetAddr 6493101Sstever@eecs.umich.edu 6503101Sstever@eecs.umich.edu value = _NextEthernetAddr 6514168Sbinkertn@umich.edu _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1) 65210267SGeoffrey.Blake@arm.com return value 6533101Sstever@eecs.umich.edu 6543101Sstever@eecs.umich.educlass EthernetAddr(ParamValue): 6553101Sstever@eecs.umich.edu cxx_type = 'Net::EthAddr' 6563101Sstever@eecs.umich.edu 6573101Sstever@eecs.umich.edu @classmethod 6583101Sstever@eecs.umich.edu def cxx_predecls(cls, code): 6593102Sstever@eecs.umich.edu code('#include "base/inet.hh"') 6603101Sstever@eecs.umich.edu 6613101Sstever@eecs.umich.edu @classmethod 6623101Sstever@eecs.umich.edu def swig_predecls(cls, code): 6633101Sstever@eecs.umich.edu code('%include "python/swig/inet.i"') 6643101Sstever@eecs.umich.edu 6653101Sstever@eecs.umich.edu def __init__(self, value): 6663101Sstever@eecs.umich.edu if value == NextEthernetAddr: 6673101Sstever@eecs.umich.edu self.value = value 6683101Sstever@eecs.umich.edu return 6693101Sstever@eecs.umich.edu 6703101Sstever@eecs.umich.edu if not isinstance(value, str): 67110317Smitch.hayenga@arm.com raise TypeError, "expected an ethernet address and didn't get one" 67210317Smitch.hayenga@arm.com 67310317Smitch.hayenga@arm.com bytes = value.split(':') 67410317Smitch.hayenga@arm.com if len(bytes) != 6: 67510317Smitch.hayenga@arm.com raise TypeError, 'invalid ethernet address %s' % value 6763102Sstever@eecs.umich.edu 67710317Smitch.hayenga@arm.com for byte in bytes: 67810317Smitch.hayenga@arm.com if not 0 <= int(byte) <= 0xff: 67910317Smitch.hayenga@arm.com raise TypeError, 'invalid ethernet address %s' % value 68010317Smitch.hayenga@arm.com 68110317Smitch.hayenga@arm.com self.value = value 6823101Sstever@eecs.umich.edu 6833584Ssaidi@eecs.umich.edu def unproxy(self, base): 6843584Ssaidi@eecs.umich.edu if self.value == NextEthernetAddr: 6853584Ssaidi@eecs.umich.edu return EthernetAddr(self.value()) 6863584Ssaidi@eecs.umich.edu return self 6873584Ssaidi@eecs.umich.edu 68810267SGeoffrey.Blake@arm.com def getValue(self): 68910267SGeoffrey.Blake@arm.com from m5.internal.params import EthAddr 69010267SGeoffrey.Blake@arm.com return EthAddr(self.value) 69110267SGeoffrey.Blake@arm.com 69210267SGeoffrey.Blake@arm.com def ini_str(self): 69310267SGeoffrey.Blake@arm.com return self.value 6943101Sstever@eecs.umich.edu 6959232Sandreas.hansson@arm.com# When initializing an IpAddress, pass in an existing IpAddress, a string of 6969235Sandreas.hansson@arm.com# the form "a.b.c.d", or an integer representing an IP. 6973101Sstever@eecs.umich.educlass IpAddress(ParamValue): 6983101Sstever@eecs.umich.edu cxx_type = 'Net::IpAddress' 69910676Sandreas.hansson@arm.com 7009411Sandreas.hansson@arm.com @classmethod 70110676Sandreas.hansson@arm.com def cxx_predecls(cls, code): 7029411Sandreas.hansson@arm.com code('#include "base/inet.hh"') 7039411Sandreas.hansson@arm.com 7049411Sandreas.hansson@arm.com @classmethod 7053101Sstever@eecs.umich.edu def swig_predecls(cls, code): 7069411Sandreas.hansson@arm.com code('%include "python/swig/inet.i"') 7079411Sandreas.hansson@arm.com 7089411Sandreas.hansson@arm.com def __init__(self, value): 7093101Sstever@eecs.umich.edu if isinstance(value, IpAddress): 7109232Sandreas.hansson@arm.com self.ip = value.ip 7113101Sstever@eecs.umich.edu else: 7129232Sandreas.hansson@arm.com try: 7133101Sstever@eecs.umich.edu self.ip = convert.toIpAddress(value) 71413663Sandreas.sandberg@arm.com except TypeError: 7153101Sstever@eecs.umich.edu self.ip = long(value) 7169411Sandreas.hansson@arm.com self.verifyIp() 7179411Sandreas.hansson@arm.com 7189411Sandreas.hansson@arm.com def __str__(self): 71910676Sandreas.hansson@arm.com tup = [(self.ip >> i) & 0xff for i in (24, 16, 8, 0)] 72010676Sandreas.hansson@arm.com return '%d.%d.%d.%d' % tuple(tup) 7219411Sandreas.hansson@arm.com 7229411Sandreas.hansson@arm.com def __eq__(self, other): 7239411Sandreas.hansson@arm.com if isinstance(other, IpAddress): 7249411Sandreas.hansson@arm.com return self.ip == other.ip 7259411Sandreas.hansson@arm.com elif isinstance(other, str): 7263101Sstever@eecs.umich.edu try: 7279232Sandreas.hansson@arm.com return self.ip == convert.toIpAddress(other) 7283101Sstever@eecs.umich.edu except: 7293101Sstever@eecs.umich.edu return False 7303101Sstever@eecs.umich.edu else: 7313101Sstever@eecs.umich.edu return self.ip == other 7329232Sandreas.hansson@arm.com 7333101Sstever@eecs.umich.edu def __ne__(self, other): 7345219Ssaidi@eecs.umich.edu return not (self == other) 7359232Sandreas.hansson@arm.com 7369232Sandreas.hansson@arm.com def verifyIp(self): 7373101Sstever@eecs.umich.edu if self.ip < 0 or self.ip >= (1 << 32): 7389232Sandreas.hansson@arm.com raise TypeError, "invalid ip address %#08x" % self.ip 7399232Sandreas.hansson@arm.com 7403101Sstever@eecs.umich.edu def getValue(self): 7413101Sstever@eecs.umich.edu from m5.internal.params import IpAddress 7429232Sandreas.hansson@arm.com return IpAddress(self.ip) 7439232Sandreas.hansson@arm.com 7443101Sstever@eecs.umich.edu# When initializing an IpNetmask, pass in an existing IpNetmask, a string of 74513663Sandreas.sandberg@arm.com# the form "a.b.c.d/n" or "a.b.c.d/e.f.g.h", or an ip and netmask as 7463101Sstever@eecs.umich.edu# positional or keyword arguments. 7473101Sstever@eecs.umich.educlass IpNetmask(IpAddress): 74813663Sandreas.sandberg@arm.com cxx_type = 'Net::IpNetmask' 7493101Sstever@eecs.umich.edu 7503101Sstever@eecs.umich.edu @classmethod 75111620SMatthew.Poremba@amd.com def cxx_predecls(cls, code): 75211620SMatthew.Poremba@amd.com code('#include "base/inet.hh"') 75311620SMatthew.Poremba@amd.com 7549232Sandreas.hansson@arm.com @classmethod 7559232Sandreas.hansson@arm.com def swig_predecls(cls, code): 7569411Sandreas.hansson@arm.com code('%include "python/swig/inet.i"') 7579411Sandreas.hansson@arm.com 7583101Sstever@eecs.umich.edu def __init__(self, *args, **kwargs): 7597673Snate@binkert.org def handle_kwarg(self, kwargs, key, elseVal = None): 7607673Snate@binkert.org if key in kwargs: 7619232Sandreas.hansson@arm.com setattr(self, key, kwargs.pop(key)) 7629235Sandreas.hansson@arm.com elif elseVal: 7637675Snate@binkert.org setattr(self, key, elseVal) 7647675Snate@binkert.org else: 76511988Sandreas.sandberg@arm.com raise TypeError, "No value set for %s" % key 76611988Sandreas.sandberg@arm.com 76711988Sandreas.sandberg@arm.com if len(args) == 0: 76811988Sandreas.sandberg@arm.com handle_kwarg(self, kwargs, 'ip') 76911988Sandreas.sandberg@arm.com handle_kwarg(self, kwargs, 'netmask') 77010458Sandreas.hansson@arm.com 77110458Sandreas.hansson@arm.com elif len(args) == 1: 77210458Sandreas.hansson@arm.com if kwargs: 77310458Sandreas.hansson@arm.com if not 'ip' in kwargs and not 'netmask' in kwargs: 77410458Sandreas.hansson@arm.com raise TypeError, "Invalid arguments" 77511620SMatthew.Poremba@amd.com handle_kwarg(self, kwargs, 'ip', args[0]) 77611620SMatthew.Poremba@amd.com handle_kwarg(self, kwargs, 'netmask', args[0]) 77710458Sandreas.hansson@arm.com elif isinstance(args[0], IpNetmask): 77810458Sandreas.hansson@arm.com self.ip = args[0].ip 77910458Sandreas.hansson@arm.com self.netmask = args[0].netmask 78010458Sandreas.hansson@arm.com else: 78110458Sandreas.hansson@arm.com (self.ip, self.netmask) = convert.toIpNetmask(args[0]) 78211620SMatthew.Poremba@amd.com 78311620SMatthew.Poremba@amd.com elif len(args) == 2: 78411620SMatthew.Poremba@amd.com self.ip = args[0] 78511620SMatthew.Poremba@amd.com self.netmask = args[1] 78611620SMatthew.Poremba@amd.com else: 78711620SMatthew.Poremba@amd.com raise TypeError, "Too many arguments specified" 78811620SMatthew.Poremba@amd.com 78911620SMatthew.Poremba@amd.com if kwargs: 79011620SMatthew.Poremba@amd.com raise TypeError, "Too many keywords: %s" % kwargs.keys() 79111620SMatthew.Poremba@amd.com 79210458Sandreas.hansson@arm.com self.verify() 79310458Sandreas.hansson@arm.com 79410458Sandreas.hansson@arm.com def __str__(self): 79511620SMatthew.Poremba@amd.com return "%s/%d" % (super(IpNetmask, self).__str__(), self.netmask) 79611620SMatthew.Poremba@amd.com 79710458Sandreas.hansson@arm.com def __eq__(self, other): 79810458Sandreas.hansson@arm.com if isinstance(other, IpNetmask): 7994762Snate@binkert.org return self.ip == other.ip and self.netmask == other.netmask 80011991Sandreas.sandberg@arm.com elif isinstance(other, str): 80111802Sandreas.sandberg@arm.com try: 8024762Snate@binkert.org return (self.ip, self.netmask) == convert.toIpNetmask(other) 8039411Sandreas.hansson@arm.com except: 80410676Sandreas.hansson@arm.com return False 80510676Sandreas.hansson@arm.com else: 8063101Sstever@eecs.umich.edu return False 8073101Sstever@eecs.umich.edu 8083101Sstever@eecs.umich.edu def verify(self): 8093101Sstever@eecs.umich.edu self.verifyIp() 8103101Sstever@eecs.umich.edu if self.netmask < 0 or self.netmask > 32: 8113101Sstever@eecs.umich.edu raise TypeError, "invalid netmask %d" % netmask 81210267SGeoffrey.Blake@arm.com 81310267SGeoffrey.Blake@arm.com def getValue(self): 8143101Sstever@eecs.umich.edu from m5.internal.params import IpNetmask 8153101Sstever@eecs.umich.edu return IpNetmask(self.ip, self.netmask) 8163102Sstever@eecs.umich.edu 8173101Sstever@eecs.umich.edu# When initializing an IpWithPort, pass in an existing IpWithPort, a string of 8183101Sstever@eecs.umich.edu# the form "a.b.c.d:p", or an ip and port as positional or keyword arguments. 8193101Sstever@eecs.umich.educlass IpWithPort(IpAddress): 82010267SGeoffrey.Blake@arm.com cxx_type = 'Net::IpWithPort' 82110267SGeoffrey.Blake@arm.com 82210267SGeoffrey.Blake@arm.com @classmethod 82310267SGeoffrey.Blake@arm.com def cxx_predecls(cls, code): 8244762Snate@binkert.org code('#include "base/inet.hh"') 8254762Snate@binkert.org 8264762Snate@binkert.org @classmethod 8273101Sstever@eecs.umich.edu def swig_predecls(cls, code): 8283101Sstever@eecs.umich.edu code('%include "python/swig/inet.i"') 8293101Sstever@eecs.umich.edu 8308934SBrad.Beckmann@amd.com def __init__(self, *args, **kwargs): 8318934SBrad.Beckmann@amd.com def handle_kwarg(self, kwargs, key, elseVal = None): 83213697Sandreas.sandberg@arm.com if key in kwargs: 8338934SBrad.Beckmann@amd.com setattr(self, key, kwargs.pop(key)) 8348934SBrad.Beckmann@amd.com elif elseVal: 83513697Sandreas.sandberg@arm.com setattr(self, key, elseVal) 83613697Sandreas.sandberg@arm.com else: 83713697Sandreas.sandberg@arm.com raise TypeError, "No value set for %s" % key 8383101Sstever@eecs.umich.edu 8393101Sstever@eecs.umich.edu if len(args) == 0: 8403101Sstever@eecs.umich.edu handle_kwarg(self, kwargs, 'ip') 8413101Sstever@eecs.umich.edu handle_kwarg(self, kwargs, 'port') 8423101Sstever@eecs.umich.edu 84310380SAndrew.Bardsley@arm.com elif len(args) == 1: 84410380SAndrew.Bardsley@arm.com if kwargs: 84510380SAndrew.Bardsley@arm.com if not 'ip' in kwargs and not 'port' in kwargs: 84610458Sandreas.hansson@arm.com raise TypeError, "Invalid arguments" 84710458Sandreas.hansson@arm.com handle_kwarg(self, kwargs, 'ip', args[0]) 84810458Sandreas.hansson@arm.com handle_kwarg(self, kwargs, 'port', args[0]) 84910458Sandreas.hansson@arm.com elif isinstance(args[0], IpWithPort): 85010458Sandreas.hansson@arm.com self.ip = args[0].ip 85110458Sandreas.hansson@arm.com self.port = args[0].port 85210458Sandreas.hansson@arm.com else: 85310458Sandreas.hansson@arm.com (self.ip, self.port) = convert.toIpWithPort(args[0]) 85410458Sandreas.hansson@arm.com 85510458Sandreas.hansson@arm.com elif len(args) == 2: 8563101Sstever@eecs.umich.edu self.ip = args[0] 8573101Sstever@eecs.umich.edu self.port = args[1] 8583101Sstever@eecs.umich.edu else: 8593101Sstever@eecs.umich.edu raise TypeError, "Too many arguments specified" 8603101Sstever@eecs.umich.edu 8613101Sstever@eecs.umich.edu if kwargs: 8623101Sstever@eecs.umich.edu raise TypeError, "Too many keywords: %s" % kwargs.keys() 8633101Sstever@eecs.umich.edu 8643101Sstever@eecs.umich.edu self.verify() 8653101Sstever@eecs.umich.edu 8663101Sstever@eecs.umich.edu def __str__(self): 8673101Sstever@eecs.umich.edu return "%s:%d" % (super(IpWithPort, self).__str__(), self.port) 8684380Sbinkertn@umich.edu 8694380Sbinkertn@umich.edu def __eq__(self, other): 8704380Sbinkertn@umich.edu if isinstance(other, IpWithPort): 8713101Sstever@eecs.umich.edu return self.ip == other.ip and self.port == other.port 8724380Sbinkertn@umich.edu elif isinstance(other, str): 8734380Sbinkertn@umich.edu try: 8744380Sbinkertn@umich.edu return (self.ip, self.port) == convert.toIpWithPort(other) 8753101Sstever@eecs.umich.edu except: 8763101Sstever@eecs.umich.edu return False 8773101Sstever@eecs.umich.edu else: 87810267SGeoffrey.Blake@arm.com return False 87910267SGeoffrey.Blake@arm.com 8807673Snate@binkert.org def verify(self): 8817673Snate@binkert.org self.verifyIp() 8827673Snate@binkert.org if self.port < 0 or self.port > 0xffff: 8837673Snate@binkert.org raise TypeError, "invalid port %d" % self.port 8847673Snate@binkert.org 8853101Sstever@eecs.umich.edu def getValue(self): 8863101Sstever@eecs.umich.edu from m5.internal.params import IpWithPort 8873101Sstever@eecs.umich.edu return IpWithPort(self.ip, self.port) 8883101Sstever@eecs.umich.edu 8893101Sstever@eecs.umich.edutime_formats = [ "%a %b %d %H:%M:%S %Z %Y", 8903101Sstever@eecs.umich.edu "%a %b %d %H:%M:%S %Z %Y", 89113663Sandreas.sandberg@arm.com "%Y/%m/%d %H:%M:%S", 8923101Sstever@eecs.umich.edu "%Y/%m/%d %H:%M", 8933101Sstever@eecs.umich.edu "%Y/%m/%d", 8943101Sstever@eecs.umich.edu "%m/%d/%Y %H:%M:%S", 89513663Sandreas.sandberg@arm.com "%m/%d/%Y %H:%M", 8963101Sstever@eecs.umich.edu "%m/%d/%Y", 8973101Sstever@eecs.umich.edu "%m/%d/%y %H:%M:%S", 8989941SGeoffrey.Blake@arm.com "%m/%d/%y %H:%M", 89913663Sandreas.sandberg@arm.com "%m/%d/%y"] 9003101Sstever@eecs.umich.edu 9013101Sstever@eecs.umich.edu 9023101Sstever@eecs.umich.edudef parse_time(value): 90310267SGeoffrey.Blake@arm.com from time import gmtime, strptime, struct_time, time 90410267SGeoffrey.Blake@arm.com from datetime import datetime, date 90510267SGeoffrey.Blake@arm.com 90610267SGeoffrey.Blake@arm.com if isinstance(value, struct_time): 9073101Sstever@eecs.umich.edu return value 9083101Sstever@eecs.umich.edu 9094380Sbinkertn@umich.edu if isinstance(value, (int, long)): 9103101Sstever@eecs.umich.edu return gmtime(value) 9113101Sstever@eecs.umich.edu 9124762Snate@binkert.org if isinstance(value, (datetime, date)): 91311988Sandreas.sandberg@arm.com return value.timetuple() 9144762Snate@binkert.org 9154762Snate@binkert.org if isinstance(value, str): 91611228SAndrew.Bardsley@arm.com if value in ('Now', 'Today'): 91711228SAndrew.Bardsley@arm.com return time.gmtime(time.time()) 91811228SAndrew.Bardsley@arm.com 9194380Sbinkertn@umich.edu for format in time_formats: 9204380Sbinkertn@umich.edu try: 9213101Sstever@eecs.umich.edu return strptime(value, format) 92210458Sandreas.hansson@arm.com except ValueError: 92310458Sandreas.hansson@arm.com pass 92410458Sandreas.hansson@arm.com 92510458Sandreas.hansson@arm.com raise ValueError, "Could not parse '%s' as a time" % value 92610458Sandreas.hansson@arm.com 9277777Sgblack@eecs.umich.educlass Time(ParamValue): 9287777Sgblack@eecs.umich.edu cxx_type = 'tm' 9297777Sgblack@eecs.umich.edu 9307777Sgblack@eecs.umich.edu @classmethod 93110267SGeoffrey.Blake@arm.com def cxx_predecls(cls, code): 93210267SGeoffrey.Blake@arm.com code('#include <time.h>') 9337777Sgblack@eecs.umich.edu 9347777Sgblack@eecs.umich.edu @classmethod 9357777Sgblack@eecs.umich.edu def swig_predecls(cls, code): 9367777Sgblack@eecs.umich.edu code('%include "python/swig/time.i"') 9377777Sgblack@eecs.umich.edu 9387777Sgblack@eecs.umich.edu def __init__(self, value): 9397777Sgblack@eecs.umich.edu self.value = parse_time(value) 9407777Sgblack@eecs.umich.edu 9417777Sgblack@eecs.umich.edu def getValue(self): 9427777Sgblack@eecs.umich.edu from m5.internal.params import tm 9437777Sgblack@eecs.umich.edu 9447777Sgblack@eecs.umich.edu c_time = tm() 9457777Sgblack@eecs.umich.edu py_time = self.value 9467777Sgblack@eecs.umich.edu 9477777Sgblack@eecs.umich.edu # UNIX is years since 1900 94810267SGeoffrey.Blake@arm.com c_time.tm_year = py_time.tm_year - 1900; 94910267SGeoffrey.Blake@arm.com 95010267SGeoffrey.Blake@arm.com # Python starts at 1, UNIX starts at 0 95110267SGeoffrey.Blake@arm.com c_time.tm_mon = py_time.tm_mon - 1; 9528579Ssteve.reinhardt@amd.com c_time.tm_mday = py_time.tm_mday; 9538579Ssteve.reinhardt@amd.com c_time.tm_hour = py_time.tm_hour; 9548579Ssteve.reinhardt@amd.com c_time.tm_min = py_time.tm_min; 9558579Ssteve.reinhardt@amd.com c_time.tm_sec = py_time.tm_sec; 9568579Ssteve.reinhardt@amd.com 9578579Ssteve.reinhardt@amd.com # Python has 0 as Monday, UNIX is 0 as sunday 9588579Ssteve.reinhardt@amd.com c_time.tm_wday = py_time.tm_wday + 1 9598579Ssteve.reinhardt@amd.com if c_time.tm_wday > 6: 9608579Ssteve.reinhardt@amd.com c_time.tm_wday -= 7; 9618579Ssteve.reinhardt@amd.com 9628579Ssteve.reinhardt@amd.com # Python starts at 1, Unix starts at 0 9638579Ssteve.reinhardt@amd.com c_time.tm_yday = py_time.tm_yday - 1; 9648579Ssteve.reinhardt@amd.com 9658579Ssteve.reinhardt@amd.com return c_time 9668579Ssteve.reinhardt@amd.com 9678579Ssteve.reinhardt@amd.com def __str__(self): 9688579Ssteve.reinhardt@amd.com return time.asctime(self.value) 9698579Ssteve.reinhardt@amd.com 9707777Sgblack@eecs.umich.edu def ini_str(self): 9717777Sgblack@eecs.umich.edu return str(self) 97213663Sandreas.sandberg@arm.com 9737777Sgblack@eecs.umich.edu def get_config_as_dict(self): 9747777Sgblack@eecs.umich.edu return str(self) 97511988Sandreas.sandberg@arm.com 9767777Sgblack@eecs.umich.edu# Enumerated types are a little more complex. The user specifies the 9777777Sgblack@eecs.umich.edu# type as Enum(foo) where foo is either a list or dictionary of 9787777Sgblack@eecs.umich.edu# alternatives (typically strings, but not necessarily so). (In the 9797777Sgblack@eecs.umich.edu# long run, the integer value of the parameter will be the list index 9807777Sgblack@eecs.umich.edu# or the corresponding dictionary value. For now, since we only check 9817777Sgblack@eecs.umich.edu# that the alternative is valid and then spit it into a .ini file, 9827777Sgblack@eecs.umich.edu# there's not much point in using the dictionary.) 98310267SGeoffrey.Blake@arm.com 98410267SGeoffrey.Blake@arm.com# What Enum() must do is generate a new type encapsulating the 9857777Sgblack@eecs.umich.edu# provided list/dictionary so that specific values of the parameter 9867777Sgblack@eecs.umich.edu# can be instances of that type. We define two hidden internal 9877777Sgblack@eecs.umich.edu# classes (_ListEnum and _DictEnum) to serve as base classes, then 9887777Sgblack@eecs.umich.edu# derive the new type from the appropriate base class on the fly. 9897777Sgblack@eecs.umich.edu 9907777Sgblack@eecs.umich.eduallEnums = {} 9917777Sgblack@eecs.umich.edu# Metaclass for Enum types 9927777Sgblack@eecs.umich.educlass MetaEnum(MetaParamValue): 9937777Sgblack@eecs.umich.edu def __new__(mcls, name, bases, dict): 9947777Sgblack@eecs.umich.edu assert name not in allEnums 9957777Sgblack@eecs.umich.edu 9967777Sgblack@eecs.umich.edu cls = super(MetaEnum, mcls).__new__(mcls, name, bases, dict) 99713663Sandreas.sandberg@arm.com allEnums[name] = cls 9987777Sgblack@eecs.umich.edu return cls 9997777Sgblack@eecs.umich.edu 10007777Sgblack@eecs.umich.edu def __init__(cls, name, bases, init_dict): 10017777Sgblack@eecs.umich.edu if init_dict.has_key('map'): 10027777Sgblack@eecs.umich.edu if not isinstance(cls.map, dict): 10037777Sgblack@eecs.umich.edu raise TypeError, "Enum-derived class attribute 'map' " \ 10047777Sgblack@eecs.umich.edu "must be of type dict" 10057777Sgblack@eecs.umich.edu # build list of value strings from map 100613663Sandreas.sandberg@arm.com cls.vals = cls.map.keys() 10077777Sgblack@eecs.umich.edu cls.vals.sort() 10087777Sgblack@eecs.umich.edu elif init_dict.has_key('vals'): 10097777Sgblack@eecs.umich.edu if not isinstance(cls.vals, list): 10107777Sgblack@eecs.umich.edu raise TypeError, "Enum-derived class attribute 'vals' " \ 10117777Sgblack@eecs.umich.edu "must be of type list" 10127777Sgblack@eecs.umich.edu # build string->value map from vals sequence 10137777Sgblack@eecs.umich.edu cls.map = {} 10147777Sgblack@eecs.umich.edu for idx,val in enumerate(cls.vals): 10157777Sgblack@eecs.umich.edu cls.map[val] = idx 10167777Sgblack@eecs.umich.edu else: 10177777Sgblack@eecs.umich.edu raise TypeError, "Enum-derived class must define "\ 10187777Sgblack@eecs.umich.edu "attribute 'map' or 'vals'" 101913663Sandreas.sandberg@arm.com 10207777Sgblack@eecs.umich.edu cls.cxx_type = 'Enums::%s' % name 10217777Sgblack@eecs.umich.edu 102213663Sandreas.sandberg@arm.com super(MetaEnum, cls).__init__(name, bases, init_dict) 10237777Sgblack@eecs.umich.edu 10247777Sgblack@eecs.umich.edu # Generate C++ class declaration for this enum type. 10257777Sgblack@eecs.umich.edu # Note that we wrap the enum in a class/struct to act as a namespace, 102610267SGeoffrey.Blake@arm.com # so that the enum strings can be brief w/o worrying about collisions. 102710267SGeoffrey.Blake@arm.com def cxx_decl(cls, code): 102810267SGeoffrey.Blake@arm.com name = cls.__name__ 102910267SGeoffrey.Blake@arm.com code('''\ 10308579Ssteve.reinhardt@amd.com#ifndef __ENUM__${name}__ 10318579Ssteve.reinhardt@amd.com#define __ENUM__${name}__ 10328579Ssteve.reinhardt@amd.com 10338579Ssteve.reinhardt@amd.comnamespace Enums { 10348579Ssteve.reinhardt@amd.com enum $name { 10358579Ssteve.reinhardt@amd.com''') 10368579Ssteve.reinhardt@amd.com code.indent(2) 10378579Ssteve.reinhardt@amd.com for val in cls.vals: 10388579Ssteve.reinhardt@amd.com code('$val = ${{cls.map[val]}},') 10398579Ssteve.reinhardt@amd.com code('Num_$name = ${{len(cls.vals)}},') 10408579Ssteve.reinhardt@amd.com code.dedent(2) 10418579Ssteve.reinhardt@amd.com code('''\ 10428579Ssteve.reinhardt@amd.com }; 10438579Ssteve.reinhardt@amd.comextern const char *${name}Strings[Num_${name}]; 10447777Sgblack@eecs.umich.edu} 10457777Sgblack@eecs.umich.edu 10467777Sgblack@eecs.umich.edu#endif // __ENUM__${name}__ 104713663Sandreas.sandberg@arm.com''') 10487777Sgblack@eecs.umich.edu 10497777Sgblack@eecs.umich.edu def cxx_def(cls, code): 105011988Sandreas.sandberg@arm.com name = cls.__name__ 10517777Sgblack@eecs.umich.edu code('''\ 10527777Sgblack@eecs.umich.edu#include "enums/$name.hh" 10537777Sgblack@eecs.umich.edunamespace Enums { 10547777Sgblack@eecs.umich.edu const char *${name}Strings[Num_${name}] = 10557777Sgblack@eecs.umich.edu { 10567777Sgblack@eecs.umich.edu''') 105710267SGeoffrey.Blake@arm.com code.indent(2) 105810267SGeoffrey.Blake@arm.com for val in cls.vals: 10597777Sgblack@eecs.umich.edu code('"$val",') 10607777Sgblack@eecs.umich.edu code.dedent(2) 10617777Sgblack@eecs.umich.edu code(''' 10627777Sgblack@eecs.umich.edu }; 10637777Sgblack@eecs.umich.edu} // namespace Enums 10647777Sgblack@eecs.umich.edu''') 10657777Sgblack@eecs.umich.edu 10667777Sgblack@eecs.umich.edu def swig_decl(cls, code): 10677777Sgblack@eecs.umich.edu name = cls.__name__ 10687777Sgblack@eecs.umich.edu code('''\ 10697777Sgblack@eecs.umich.edu%module(package="m5.internal") enum_$name 10707777Sgblack@eecs.umich.edu 107113663Sandreas.sandberg@arm.com%{ 10727777Sgblack@eecs.umich.edu#include "enums/$name.hh" 10737777Sgblack@eecs.umich.edu%} 10747777Sgblack@eecs.umich.edu 10757777Sgblack@eecs.umich.edu%include "enums/$name.hh" 10767777Sgblack@eecs.umich.edu''') 10777777Sgblack@eecs.umich.edu 10787777Sgblack@eecs.umich.edu 10797777Sgblack@eecs.umich.edu# Base class for enum types. 108013663Sandreas.sandberg@arm.comclass Enum(ParamValue): 10817777Sgblack@eecs.umich.edu __metaclass__ = MetaEnum 10827777Sgblack@eecs.umich.edu vals = [] 10837777Sgblack@eecs.umich.edu 10847777Sgblack@eecs.umich.edu def __init__(self, value): 10857777Sgblack@eecs.umich.edu if value not in self.map: 10867777Sgblack@eecs.umich.edu raise TypeError, "Enum param got bad value '%s' (not in %s)" \ 10877777Sgblack@eecs.umich.edu % (value, self.vals) 10887777Sgblack@eecs.umich.edu self.value = value 10897777Sgblack@eecs.umich.edu 10907777Sgblack@eecs.umich.edu @classmethod 10917777Sgblack@eecs.umich.edu def cxx_predecls(cls, code): 10927777Sgblack@eecs.umich.edu code('#include "enums/$0.hh"', cls.__name__) 109313663Sandreas.sandberg@arm.com 10947777Sgblack@eecs.umich.edu @classmethod 10957777Sgblack@eecs.umich.edu def swig_predecls(cls, code): 109613663Sandreas.sandberg@arm.com code('%import "python/m5/internal/enum_$0.i"', cls.__name__) 10977777Sgblack@eecs.umich.edu 10987777Sgblack@eecs.umich.edu def getValue(self): 10997777Sgblack@eecs.umich.edu return int(self.map[self.value]) 110010267SGeoffrey.Blake@arm.com 110110267SGeoffrey.Blake@arm.com def __str__(self): 110210267SGeoffrey.Blake@arm.com return self.value 110310267SGeoffrey.Blake@arm.com 11048579Ssteve.reinhardt@amd.com# how big does a rounding error need to be before we warn about it? 11058579Ssteve.reinhardt@amd.comfrequency_tolerance = 0.001 # 0.1% 11068579Ssteve.reinhardt@amd.com 11078579Ssteve.reinhardt@amd.comclass TickParamValue(NumericParamValue): 11088579Ssteve.reinhardt@amd.com cxx_type = 'Tick' 11098579Ssteve.reinhardt@amd.com 11108579Ssteve.reinhardt@amd.com @classmethod 11118579Ssteve.reinhardt@amd.com def cxx_predecls(cls, code): 11128579Ssteve.reinhardt@amd.com code('#include "base/types.hh"') 11138579Ssteve.reinhardt@amd.com 11148579Ssteve.reinhardt@amd.com @classmethod 11158579Ssteve.reinhardt@amd.com def swig_predecls(cls, code): 11168579Ssteve.reinhardt@amd.com code('%import "stdint.i"') 11178579Ssteve.reinhardt@amd.com code('%import "base/types.hh"') 11187777Sgblack@eecs.umich.edu 11197777Sgblack@eecs.umich.edu def getValue(self): 11207777Sgblack@eecs.umich.edu return long(self.value) 112113663Sandreas.sandberg@arm.com 11227777Sgblack@eecs.umich.educlass Latency(TickParamValue): 11237777Sgblack@eecs.umich.edu def __init__(self, value): 112411988Sandreas.sandberg@arm.com if isinstance(value, (Latency, Clock)): 11257777Sgblack@eecs.umich.edu self.ticks = value.ticks 11267777Sgblack@eecs.umich.edu self.value = value.value 11273932Sbinkertn@umich.edu elif isinstance(value, Frequency): 112810380SAndrew.Bardsley@arm.com self.ticks = value.ticks 11293932Sbinkertn@umich.edu self.value = 1.0 / value.value 11303932Sbinkertn@umich.edu elif value.endswith('t'): 11313932Sbinkertn@umich.edu self.ticks = True 11323932Sbinkertn@umich.edu self.value = int(value[:-1]) 11333932Sbinkertn@umich.edu else: 11343932Sbinkertn@umich.edu self.ticks = False 11353932Sbinkertn@umich.edu self.value = convert.toLatency(value) 11363932Sbinkertn@umich.edu 11373932Sbinkertn@umich.edu def __getattr__(self, attr): 11383932Sbinkertn@umich.edu if attr in ('latency', 'period'): 11393932Sbinkertn@umich.edu return self 11403885Sbinkertn@umich.edu if attr == 'frequency': 11413932Sbinkertn@umich.edu return Frequency(self) 11423932Sbinkertn@umich.edu raise AttributeError, "Latency object has no attribute '%s'" % attr 11433885Sbinkertn@umich.edu 11443932Sbinkertn@umich.edu def getValue(self): 11453932Sbinkertn@umich.edu if self.ticks or self.value == 0: 11463932Sbinkertn@umich.edu value = self.value 11473932Sbinkertn@umich.edu else: 11483932Sbinkertn@umich.edu value = ticks.fromSeconds(self.value) 11493932Sbinkertn@umich.edu return long(value) 11503932Sbinkertn@umich.edu 11513932Sbinkertn@umich.edu # convert latency to ticks 11523932Sbinkertn@umich.edu def ini_str(self): 11533932Sbinkertn@umich.edu return '%d' % self.getValue() 11543932Sbinkertn@umich.edu 11553932Sbinkertn@umich.educlass Frequency(TickParamValue): 11563932Sbinkertn@umich.edu def __init__(self, value): 11573932Sbinkertn@umich.edu if isinstance(value, (Latency, Clock)): 11583932Sbinkertn@umich.edu if value.value == 0: 11593932Sbinkertn@umich.edu self.value = 0 11603932Sbinkertn@umich.edu else: 11613932Sbinkertn@umich.edu self.value = 1.0 / value.value 11623885Sbinkertn@umich.edu self.ticks = value.ticks 116313663Sandreas.sandberg@arm.com elif isinstance(value, Frequency): 11643885Sbinkertn@umich.edu self.value = value.value 11653885Sbinkertn@umich.edu self.ticks = value.ticks 11664762Snate@binkert.org else: 11677673Snate@binkert.org self.ticks = False 11687673Snate@binkert.org self.value = convert.toFrequency(value) 11697673Snate@binkert.org 11707673Snate@binkert.org def __getattr__(self, attr): 11717673Snate@binkert.org if attr == 'frequency': 11723885Sbinkertn@umich.edu return self 11733932Sbinkertn@umich.edu if attr in ('latency', 'period'): 11743885Sbinkertn@umich.edu return Latency(self) 117510267SGeoffrey.Blake@arm.com raise AttributeError, "Frequency object has no attribute '%s'" % attr 117610267SGeoffrey.Blake@arm.com 117710267SGeoffrey.Blake@arm.com # convert latency to ticks 117810267SGeoffrey.Blake@arm.com def getValue(self): 11794762Snate@binkert.org if self.ticks or self.value == 0: 118011988Sandreas.sandberg@arm.com value = self.value 118111988Sandreas.sandberg@arm.com else: 11824762Snate@binkert.org value = ticks.fromSeconds(1.0 / self.value) 118311988Sandreas.sandberg@arm.com return long(value) 11844762Snate@binkert.org 11853885Sbinkertn@umich.edu def ini_str(self): 11864762Snate@binkert.org return '%d' % self.getValue() 11873885Sbinkertn@umich.edu 11883885Sbinkertn@umich.edu# A generic frequency and/or Latency value. Value is stored as a latency, 11893932Sbinkertn@umich.edu# but to avoid ambiguity this object does not support numeric ops (* or /). 11903885Sbinkertn@umich.edu# An explicit conversion to a Latency or Frequency must be made first. 11918664SAli.Saidi@ARM.comclass Clock(ParamValue): 119210380SAndrew.Bardsley@arm.com cxx_type = 'Tick' 11938664SAli.Saidi@ARM.com 11948664SAli.Saidi@ARM.com @classmethod 119510458Sandreas.hansson@arm.com def cxx_predecls(cls, code): 119610458Sandreas.hansson@arm.com code('#include "base/types.hh"') 119710458Sandreas.hansson@arm.com 119810458Sandreas.hansson@arm.com @classmethod 119910458Sandreas.hansson@arm.com def swig_predecls(cls, code): 120010458Sandreas.hansson@arm.com code('%import "stdint.i"') 120110458Sandreas.hansson@arm.com code('%import "base/types.hh"') 120210458Sandreas.hansson@arm.com 120310458Sandreas.hansson@arm.com def __init__(self, value): 120410458Sandreas.hansson@arm.com if isinstance(value, (Latency, Clock)): 12053101Sstever@eecs.umich.edu self.ticks = value.ticks 12063101Sstever@eecs.umich.edu self.value = value.value 12073101Sstever@eecs.umich.edu elif isinstance(value, Frequency): 12083101Sstever@eecs.umich.edu self.ticks = value.ticks 12093101Sstever@eecs.umich.edu self.value = 1.0 / value.value 12103101Sstever@eecs.umich.edu elif value.endswith('t'): 12113101Sstever@eecs.umich.edu self.ticks = True 12123101Sstever@eecs.umich.edu self.value = int(value[:-1]) 12133101Sstever@eecs.umich.edu else: 12143101Sstever@eecs.umich.edu self.ticks = False 12153101Sstever@eecs.umich.edu self.value = convert.anyToLatency(value) 12163101Sstever@eecs.umich.edu 12173101Sstever@eecs.umich.edu def __getattr__(self, attr): 12183101Sstever@eecs.umich.edu if attr == 'frequency': 12194762Snate@binkert.org return Frequency(self) 12203101Sstever@eecs.umich.edu if attr in ('latency', 'period'): 12215033Smilesck@eecs.umich.edu return Latency(self) 12224762Snate@binkert.org raise AttributeError, "Frequency object has no attribute '%s'" % attr 12234762Snate@binkert.org 12244762Snate@binkert.org def getValue(self): 12254762Snate@binkert.org return self.period.getValue() 12264762Snate@binkert.org 12274762Snate@binkert.org def ini_str(self): 12284762Snate@binkert.org return self.period.ini_str() 12293101Sstever@eecs.umich.edu 123013675Sandreas.sandberg@arm.comclass NetworkBandwidth(float,ParamValue): 12313101Sstever@eecs.umich.edu cxx_type = 'float' 123213663Sandreas.sandberg@arm.com def __new__(cls, value): 123313663Sandreas.sandberg@arm.com # convert to bits per second 12343101Sstever@eecs.umich.edu val = convert.toNetworkBandwidth(value) 12353101Sstever@eecs.umich.edu return super(cls, NetworkBandwidth).__new__(cls, val) 12363101Sstever@eecs.umich.edu 123713675Sandreas.sandberg@arm.com def __str__(self): 12383101Sstever@eecs.umich.edu return str(self.val) 123913663Sandreas.sandberg@arm.com 124013663Sandreas.sandberg@arm.com def getValue(self): 12413101Sstever@eecs.umich.edu # convert to seconds per byte 12423101Sstever@eecs.umich.edu value = 8.0 / float(self) 12433101Sstever@eecs.umich.edu # convert to ticks per byte 12443101Sstever@eecs.umich.edu value = ticks.fromSeconds(value) 12453101Sstever@eecs.umich.edu return float(value) 124613663Sandreas.sandberg@arm.com 124713663Sandreas.sandberg@arm.com def ini_str(self): 12483101Sstever@eecs.umich.edu return '%f' % self.getValue() 124913558Snikos.nikoleris@arm.com 125013558Snikos.nikoleris@arm.comclass MemoryBandwidth(float,ParamValue): 125113558Snikos.nikoleris@arm.com cxx_type = 'float' 125213558Snikos.nikoleris@arm.com def __new__(cls, value): 12533101Sstever@eecs.umich.edu # convert to bytes per second 12543101Sstever@eecs.umich.edu val = convert.toMemoryBandwidth(value) 12553101Sstever@eecs.umich.edu return super(cls, MemoryBandwidth).__new__(cls, val) 12563101Sstever@eecs.umich.edu 12573101Sstever@eecs.umich.edu def __str__(self): 12583101Sstever@eecs.umich.edu return str(self.val) 12597673Snate@binkert.org 126010201SAndrew.Bardsley@arm.com def getValue(self): 126110201SAndrew.Bardsley@arm.com # convert to seconds per byte 126210201SAndrew.Bardsley@arm.com value = float(self) 126310201SAndrew.Bardsley@arm.com if value: 126410201SAndrew.Bardsley@arm.com value = 1.0 / float(self) 12657673Snate@binkert.org # convert to ticks per byte 126610201SAndrew.Bardsley@arm.com value = ticks.fromSeconds(value) 126710201SAndrew.Bardsley@arm.com return float(value) 12687673Snate@binkert.org 126913558Snikos.nikoleris@arm.com def ini_str(self): 127013558Snikos.nikoleris@arm.com return '%f' % self.getValue() 127113558Snikos.nikoleris@arm.com 127213558Snikos.nikoleris@arm.com# 127313558Snikos.nikoleris@arm.com# "Constants"... handy aliases for various values. 127413558Snikos.nikoleris@arm.com# 127513558Snikos.nikoleris@arm.com 127610201SAndrew.Bardsley@arm.com# Special class for NULL pointers. Note the special check in 12777673Snate@binkert.org# make_param_value() above that lets these be assigned where a 12787673Snate@binkert.org# SimObject is required. 127913558Snikos.nikoleris@arm.com# only one copy of a particular node 128013558Snikos.nikoleris@arm.comclass NullSimObject(object): 12814762Snate@binkert.org __metaclass__ = Singleton 12827673Snate@binkert.org 12838902Sandreas.hansson@arm.com def __call__(cls): 128413558Snikos.nikoleris@arm.com return cls 128513558Snikos.nikoleris@arm.com 12864762Snate@binkert.org def _instantiate(self, parent = None, path = ''): 128713558Snikos.nikoleris@arm.com pass 128813558Snikos.nikoleris@arm.com 128913558Snikos.nikoleris@arm.com def ini_str(self): 129013558Snikos.nikoleris@arm.com return 'Null' 129113558Snikos.nikoleris@arm.com 129213558Snikos.nikoleris@arm.com def unproxy(self, base): 129310201SAndrew.Bardsley@arm.com return self 129410201SAndrew.Bardsley@arm.com 129513558Snikos.nikoleris@arm.com def set_path(self, parent, name): 129613558Snikos.nikoleris@arm.com pass 129713558Snikos.nikoleris@arm.com 129813558Snikos.nikoleris@arm.com def __str__(self): 129910201SAndrew.Bardsley@arm.com return 'Null' 130010201SAndrew.Bardsley@arm.com 130110201SAndrew.Bardsley@arm.com def getValue(self): 13027673Snate@binkert.org return None 13037673Snate@binkert.org 130410201SAndrew.Bardsley@arm.com# The only instance you'll ever need... 130510201SAndrew.Bardsley@arm.comNULL = NullSimObject() 130610201SAndrew.Bardsley@arm.com 130710201SAndrew.Bardsley@arm.comdef isNullPointer(value): 130810201SAndrew.Bardsley@arm.com return isinstance(value, NullSimObject) 130910201SAndrew.Bardsley@arm.com 131010201SAndrew.Bardsley@arm.com# Some memory range specifications use this as a default upper bound. 131110201SAndrew.Bardsley@arm.comMaxAddr = Addr.max 131210201SAndrew.Bardsley@arm.comMaxTick = Tick.max 131313558Snikos.nikoleris@arm.comAllMemory = AddrRange(0, MaxAddr) 131413558Snikos.nikoleris@arm.com 131513558Snikos.nikoleris@arm.com 131613558Snikos.nikoleris@arm.com##################################################################### 131713558Snikos.nikoleris@arm.com# 131813558Snikos.nikoleris@arm.com# Port objects 131913558Snikos.nikoleris@arm.com# 132013558Snikos.nikoleris@arm.com# Ports are used to interconnect objects in the memory system. 132110201SAndrew.Bardsley@arm.com# 132210201SAndrew.Bardsley@arm.com##################################################################### 132310201SAndrew.Bardsley@arm.com 13244762Snate@binkert.org# Port reference: encapsulates a reference to a particular port on a 13257673Snate@binkert.org# particular SimObject. 132610201SAndrew.Bardsley@arm.comclass PortRef(object): 132710201SAndrew.Bardsley@arm.com def __init__(self, simobj, name): 132810201SAndrew.Bardsley@arm.com assert(isSimObject(simobj) or isSimObjectClass(simobj)) 132913558Snikos.nikoleris@arm.com self.simobj = simobj 133013558Snikos.nikoleris@arm.com self.name = name 133110201SAndrew.Bardsley@arm.com self.peer = None # not associated with another port yet 133213558Snikos.nikoleris@arm.com self.ccConnected = False # C++ port connection done? 13333101Sstever@eecs.umich.edu self.index = -1 # always -1 for non-vector ports 133411988Sandreas.sandberg@arm.com 133511988Sandreas.sandberg@arm.com def __str__(self): 133611988Sandreas.sandberg@arm.com return '%s.%s' % (self.simobj, self.name) 133713558Snikos.nikoleris@arm.com 133811988Sandreas.sandberg@arm.com # for config.ini, print peer's name (not ours) 133911988Sandreas.sandberg@arm.com def ini_str(self): 134011988Sandreas.sandberg@arm.com return str(self.peer) 134111988Sandreas.sandberg@arm.com 134211988Sandreas.sandberg@arm.com def __getattr__(self, attr): 134311988Sandreas.sandberg@arm.com if attr == 'peerObj': 134411988Sandreas.sandberg@arm.com # shorthand for proxies 134511988Sandreas.sandberg@arm.com return self.peer.simobj 134611988Sandreas.sandberg@arm.com raise AttributeError, "'%s' object has no attribute '%s'" % \ 134711988Sandreas.sandberg@arm.com (self.__class__.__name__, attr) 134811988Sandreas.sandberg@arm.com 134911988Sandreas.sandberg@arm.com # Full connection is symmetric (both ways). Called via 135011988Sandreas.sandberg@arm.com # SimObject.__setattr__ as a result of a port assignment, e.g., 135111988Sandreas.sandberg@arm.com # "obj1.portA = obj2.portB", or via VectorPortElementRef.__setitem__, 135213558Snikos.nikoleris@arm.com # e.g., "obj1.portA[3] = obj2.portB". 135313558Snikos.nikoleris@arm.com def connect(self, other): 135413558Snikos.nikoleris@arm.com if isinstance(other, VectorPortRef): 135513558Snikos.nikoleris@arm.com # reference to plain VectorPort is implicit append 135611988Sandreas.sandberg@arm.com other = other._get_next() 135711988Sandreas.sandberg@arm.com if self.peer and not proxy.isproxy(self.peer): 135811988Sandreas.sandberg@arm.com print "warning: overwriting port", self, \ 135911988Sandreas.sandberg@arm.com "value", self.peer, "with", other 136011988Sandreas.sandberg@arm.com self.peer.peer = None 136111988Sandreas.sandberg@arm.com self.peer = other 136211988Sandreas.sandberg@arm.com if proxy.isproxy(other): 136311988Sandreas.sandberg@arm.com other.set_param_desc(PortParamDesc()) 136411988Sandreas.sandberg@arm.com elif isinstance(other, PortRef): 136511988Sandreas.sandberg@arm.com if other.peer is not self: 136611988Sandreas.sandberg@arm.com other.connect(self) 136711988Sandreas.sandberg@arm.com else: 136811988Sandreas.sandberg@arm.com raise TypeError, \ 136911988Sandreas.sandberg@arm.com "assigning non-port reference '%s' to port '%s'" \ 137011988Sandreas.sandberg@arm.com % (other, self) 13718596Ssteve.reinhardt@amd.com 13723101Sstever@eecs.umich.edu def clone(self, simobj, memo): 13733101Sstever@eecs.umich.edu if memo.has_key(self): 13743101Sstever@eecs.umich.edu return memo[self] 13753101Sstever@eecs.umich.edu newRef = copy.copy(self) 137610267SGeoffrey.Blake@arm.com memo[self] = newRef 13773101Sstever@eecs.umich.edu newRef.simobj = simobj 137810201SAndrew.Bardsley@arm.com assert(isSimObject(newRef.simobj)) 137910201SAndrew.Bardsley@arm.com if self.peer and not proxy.isproxy(self.peer): 138010201SAndrew.Bardsley@arm.com peerObj = self.peer.simobj(_memo=memo) 138110201SAndrew.Bardsley@arm.com newRef.peer = self.peer.clone(peerObj, memo) 138210201SAndrew.Bardsley@arm.com assert(not isinstance(newRef.peer, VectorPortRef)) 138310201SAndrew.Bardsley@arm.com return newRef 138413558Snikos.nikoleris@arm.com 138513558Snikos.nikoleris@arm.com def unproxy(self, simobj): 138610201SAndrew.Bardsley@arm.com assert(simobj is self.simobj) 138710201SAndrew.Bardsley@arm.com if proxy.isproxy(self.peer): 138810201SAndrew.Bardsley@arm.com try: 13893101Sstever@eecs.umich.edu realPeer = self.peer.unproxy(self.simobj) 13903101Sstever@eecs.umich.edu except: 139113663Sandreas.sandberg@arm.com print "Error in unproxying port '%s' of %s" % \ 139213663Sandreas.sandberg@arm.com (self.name, self.simobj.path()) 13933101Sstever@eecs.umich.edu raise 13943101Sstever@eecs.umich.edu self.connect(realPeer) 139510267SGeoffrey.Blake@arm.com 139610267SGeoffrey.Blake@arm.com # Call C++ to create corresponding port connection between C++ objects 139710267SGeoffrey.Blake@arm.com def ccConnect(self): 139810267SGeoffrey.Blake@arm.com from m5.internal.pyobject import connectPorts 13997675Snate@binkert.org 14007675Snate@binkert.org if self.ccConnected: # already done this 14017675Snate@binkert.org return 14027675Snate@binkert.org peer = self.peer 14037675Snate@binkert.org if not self.peer: # nothing to connect to 140410458Sandreas.hansson@arm.com return 140510458Sandreas.hansson@arm.com try: 140610458Sandreas.hansson@arm.com connectPorts(self.simobj.getCCObject(), self.name, self.index, 140710458Sandreas.hansson@arm.com peer.simobj.getCCObject(), peer.name, peer.index) 140810458Sandreas.hansson@arm.com except: 140910458Sandreas.hansson@arm.com print "Error connecting port %s.%s to %s.%s" % \ 141010458Sandreas.hansson@arm.com (self.simobj.path(), self.name, 141110458Sandreas.hansson@arm.com peer.simobj.path(), peer.name) 141210458Sandreas.hansson@arm.com raise 141310458Sandreas.hansson@arm.com self.ccConnected = True 141410458Sandreas.hansson@arm.com peer.ccConnected = True 141510458Sandreas.hansson@arm.com 14164762Snate@binkert.org# A reference to an individual element of a VectorPort... much like a 141711988Sandreas.sandberg@arm.com# PortRef, but has an index. 141811988Sandreas.sandberg@arm.comclass VectorPortElementRef(PortRef): 141911988Sandreas.sandberg@arm.com def __init__(self, simobj, name, index): 14204762Snate@binkert.org PortRef.__init__(self, simobj, name) 14213101Sstever@eecs.umich.edu self.index = index 14223101Sstever@eecs.umich.edu 14233101Sstever@eecs.umich.edu def __str__(self): 142413558Snikos.nikoleris@arm.com return '%s.%s[%d]' % (self.simobj, self.name, self.index) 142513558Snikos.nikoleris@arm.com 142613558Snikos.nikoleris@arm.com# A reference to a complete vector-valued port (not just a single element). 142713558Snikos.nikoleris@arm.com# Can be indexed to retrieve individual VectorPortElementRef instances. 142813558Snikos.nikoleris@arm.comclass VectorPortRef(object): 142913558Snikos.nikoleris@arm.com def __init__(self, simobj, name): 143013558Snikos.nikoleris@arm.com assert(isSimObject(simobj) or isSimObjectClass(simobj)) 143113558Snikos.nikoleris@arm.com self.simobj = simobj 143213558Snikos.nikoleris@arm.com self.name = name 143313558Snikos.nikoleris@arm.com self.elements = [] 143413558Snikos.nikoleris@arm.com 143513558Snikos.nikoleris@arm.com def __str__(self): 143613558Snikos.nikoleris@arm.com return '%s.%s[:]' % (self.simobj, self.name) 143713558Snikos.nikoleris@arm.com 143813558Snikos.nikoleris@arm.com # for config.ini, print peer's name (not ours) 143913558Snikos.nikoleris@arm.com def ini_str(self): 144013558Snikos.nikoleris@arm.com return ' '.join([el.ini_str() for el in self.elements]) 144113558Snikos.nikoleris@arm.com 14423101Sstever@eecs.umich.edu def __getitem__(self, key): 14433101Sstever@eecs.umich.edu if not isinstance(key, int): 14443101Sstever@eecs.umich.edu raise TypeError, "VectorPort index must be integer" 14454167Sbinkertn@umich.edu if key >= len(self.elements): 14463101Sstever@eecs.umich.edu # need to extend list 144710267SGeoffrey.Blake@arm.com ext = [VectorPortElementRef(self.simobj, self.name, i) 144810267SGeoffrey.Blake@arm.com for i in range(len(self.elements), key+1)] 14497673Snate@binkert.org self.elements.extend(ext) 14507673Snate@binkert.org return self.elements[key] 14517673Snate@binkert.org 14527673Snate@binkert.org def _get_next(self): 14537673Snate@binkert.org return self[len(self.elements)] 145410267SGeoffrey.Blake@arm.com 145510267SGeoffrey.Blake@arm.com def __setitem__(self, key, value): 145610267SGeoffrey.Blake@arm.com if not isinstance(key, int): 145710267SGeoffrey.Blake@arm.com raise TypeError, "VectorPort index must be integer" 14584762Snate@binkert.org self[key].connect(value) 14594762Snate@binkert.org 14604762Snate@binkert.org def connect(self, other): 146110458Sandreas.hansson@arm.com if isinstance(other, (list, tuple)): 146210458Sandreas.hansson@arm.com # Assign list of port refs to vector port. 146310458Sandreas.hansson@arm.com # For now, append them... not sure if that's the right semantics 146410458Sandreas.hansson@arm.com # or if it should replace the current vector. 146510458Sandreas.hansson@arm.com for ref in other: 146610458Sandreas.hansson@arm.com self._get_next().connect(ref) 146710458Sandreas.hansson@arm.com else: 146810458Sandreas.hansson@arm.com # scalar assignment to plain VectorPort is implicit append 146910458Sandreas.hansson@arm.com self._get_next().connect(other) 147010458Sandreas.hansson@arm.com 14714167Sbinkertn@umich.edu def clone(self, simobj, memo): 147210267SGeoffrey.Blake@arm.com if memo.has_key(self): 147310267SGeoffrey.Blake@arm.com return memo[self] 14743101Sstever@eecs.umich.edu newRef = copy.copy(self) 14754167Sbinkertn@umich.edu memo[self] = newRef 14764167Sbinkertn@umich.edu newRef.simobj = simobj 14774167Sbinkertn@umich.edu assert(isSimObject(newRef.simobj)) 14784167Sbinkertn@umich.edu newRef.elements = [el.clone(simobj, memo) for el in self.elements] 14794167Sbinkertn@umich.edu return newRef 14804167Sbinkertn@umich.edu 14814167Sbinkertn@umich.edu def unproxy(self, simobj): 14824167Sbinkertn@umich.edu [el.unproxy(simobj) for el in self.elements] 14834167Sbinkertn@umich.edu 14844167Sbinkertn@umich.edu def ccConnect(self): 14854167Sbinkertn@umich.edu [el.ccConnect() for el in self.elements] 14864167Sbinkertn@umich.edu 14873101Sstever@eecs.umich.edu# Port description object. Like a ParamDesc object, this represents a 148810267SGeoffrey.Blake@arm.com# logical port in the SimObject class, not a particular port on a 148910267SGeoffrey.Blake@arm.com# SimObject instance. The latter are represented by PortRef objects. 149010267SGeoffrey.Blake@arm.comclass Port(object): 149110267SGeoffrey.Blake@arm.com # Port("description") or Port(default, "description") 14923101Sstever@eecs.umich.edu def __init__(self, *args): 14933101Sstever@eecs.umich.edu if len(args) == 1: 14943101Sstever@eecs.umich.edu self.desc = args[0] 14953101Sstever@eecs.umich.edu elif len(args) == 2: 14963101Sstever@eecs.umich.edu self.default = args[0] 149713663Sandreas.sandberg@arm.com self.desc = args[1] 14983101Sstever@eecs.umich.edu else: 14994762Snate@binkert.org raise TypeError, 'wrong number of arguments' 15004762Snate@binkert.org # self.name is set by SimObject class on assignment 15014762Snate@binkert.org # e.g., pio_port = Port("blah") sets self.name to 'pio_port' 15024762Snate@binkert.org 15034762Snate@binkert.org # Generate a PortRef for this port on the given SimObject with the 15044762Snate@binkert.org # given name 15054762Snate@binkert.org def makeRef(self, simobj): 150610380SAndrew.Bardsley@arm.com return PortRef(simobj, self.name) 150710380SAndrew.Bardsley@arm.com 150810380SAndrew.Bardsley@arm.com # Connect an instance of this port (on the given SimObject with 15093101Sstever@eecs.umich.edu # the given name) with the port described by the supplied PortRef 15103101Sstever@eecs.umich.edu def connect(self, simobj, ref): 15114762Snate@binkert.org self.makeRef(simobj).connect(ref) 15123101Sstever@eecs.umich.edu 15134167Sbinkertn@umich.edu# VectorPort description object. Like Port, but represents a vector 151410267SGeoffrey.Blake@arm.com# of connections (e.g., as on a Bus). 151510267SGeoffrey.Blake@arm.comclass VectorPort(Port): 15163101Sstever@eecs.umich.edu def __init__(self, *args): 15174167Sbinkertn@umich.edu Port.__init__(self, *args) 15184167Sbinkertn@umich.edu self.isVec = True 15194167Sbinkertn@umich.edu 15204167Sbinkertn@umich.edu def makeRef(self, simobj): 15214167Sbinkertn@umich.edu return VectorPortRef(simobj, self.name) 15224167Sbinkertn@umich.edu 15234167Sbinkertn@umich.edu# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of 15244167Sbinkertn@umich.edu# proxy objects (via set_param_desc()) so that proxy error messages 15254167Sbinkertn@umich.edu# make sense. 15264167Sbinkertn@umich.educlass PortParamDesc(object): 15274167Sbinkertn@umich.edu __metaclass__ = Singleton 15284167Sbinkertn@umich.edu 15293101Sstever@eecs.umich.edu ptype_str = 'Port' 153010267SGeoffrey.Blake@arm.com ptype = Port 153110267SGeoffrey.Blake@arm.com 153210267SGeoffrey.Blake@arm.combaseEnums = allEnums.copy() 153310267SGeoffrey.Blake@arm.combaseParams = allParams.copy() 15343101Sstever@eecs.umich.edu 15353101Sstever@eecs.umich.edudef clear(): 15363101Sstever@eecs.umich.edu global allEnums, allParams 15373101Sstever@eecs.umich.edu 15383101Sstever@eecs.umich.edu allEnums = baseEnums.copy() 153913663Sandreas.sandberg@arm.com allParams = baseParams.copy() 15403101Sstever@eecs.umich.edu 15414167Sbinkertn@umich.edu__all__ = ['Param', 'VectorParam', 15424762Snate@binkert.org 'Enum', 'Bool', 'String', 'Float', 15434762Snate@binkert.org 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 15444762Snate@binkert.org 'Int32', 'UInt32', 'Int64', 'UInt64', 15454762Snate@binkert.org 'Counter', 'Addr', 'Tick', 'Percent', 15464762Snate@binkert.org 'TcpPort', 'UdpPort', 'EthernetAddr', 15474762Snate@binkert.org 'IpAddress', 'IpNetmask', 'IpWithPort', 15484762Snate@binkert.org 'MemorySize', 'MemorySize32', 154910380SAndrew.Bardsley@arm.com 'Latency', 'Frequency', 'Clock', 155010380SAndrew.Bardsley@arm.com 'NetworkBandwidth', 'MemoryBandwidth', 155110380SAndrew.Bardsley@arm.com 'Range', 'AddrRange', 'TickRange', 15523101Sstever@eecs.umich.edu 'MaxAddr', 'MaxTick', 'AllMemory', 15534762Snate@binkert.org 'Time', 15543101Sstever@eecs.umich.edu 'NextEthernetAddr', 'NULL', 155510019Sandreas.hansson@arm.com 'Port', 'VectorPort'] 155610019Sandreas.hansson@arm.com 155710019Sandreas.hansson@arm.comimport SimObject 15583101Sstever@eecs.umich.edu