params.py revision 10427
110355SGeoffrey.Blake@arm.com# Copyright (c) 2012-2014 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 623885Sbinkertn@umich.eduimport copy 633885Sbinkertn@umich.eduimport datetime 644762Snate@binkert.orgimport re 653885Sbinkertn@umich.eduimport sys 663885Sbinkertn@umich.eduimport time 677528Ssteve.reinhardt@amd.comimport math 683885Sbinkertn@umich.edu 694380Sbinkertn@umich.eduimport proxy 704167Sbinkertn@umich.eduimport ticks 713102Sstever@eecs.umich.edufrom util import * 723101Sstever@eecs.umich.edu 734762Snate@binkert.orgdef isSimObject(*args, **kwargs): 744762Snate@binkert.org return SimObject.isSimObject(*args, **kwargs) 754762Snate@binkert.org 764762Snate@binkert.orgdef isSimObjectSequence(*args, **kwargs): 774762Snate@binkert.org return SimObject.isSimObjectSequence(*args, **kwargs) 784762Snate@binkert.org 794762Snate@binkert.orgdef isSimObjectClass(*args, **kwargs): 804762Snate@binkert.org return SimObject.isSimObjectClass(*args, **kwargs) 814762Snate@binkert.org 825033Smilesck@eecs.umich.eduallParams = {} 835033Smilesck@eecs.umich.edu 845033Smilesck@eecs.umich.educlass MetaParamValue(type): 855033Smilesck@eecs.umich.edu def __new__(mcls, name, bases, dct): 865033Smilesck@eecs.umich.edu cls = super(MetaParamValue, mcls).__new__(mcls, name, bases, dct) 875033Smilesck@eecs.umich.edu assert name not in allParams 885033Smilesck@eecs.umich.edu allParams[name] = cls 895033Smilesck@eecs.umich.edu return cls 905033Smilesck@eecs.umich.edu 915033Smilesck@eecs.umich.edu 923101Sstever@eecs.umich.edu# Dummy base class to identify types that are legitimate for SimObject 933101Sstever@eecs.umich.edu# parameters. 943101Sstever@eecs.umich.educlass ParamValue(object): 955033Smilesck@eecs.umich.edu __metaclass__ = MetaParamValue 9610267SGeoffrey.Blake@arm.com cmd_line_settable = False 978596Ssteve.reinhardt@amd.com 988596Ssteve.reinhardt@amd.com # Generate the code needed as a prerequisite for declaring a C++ 998596Ssteve.reinhardt@amd.com # object of this type. Typically generates one or more #include 1008596Ssteve.reinhardt@amd.com # statements. Used when declaring parameters of this type. 1017673Snate@binkert.org @classmethod 1027673Snate@binkert.org def cxx_predecls(cls, code): 1037673Snate@binkert.org pass 1047673Snate@binkert.org 1058596Ssteve.reinhardt@amd.com # Generate the code needed as a prerequisite for including a 1068596Ssteve.reinhardt@amd.com # reference to a C++ object of this type in a SWIG .i file. 1078596Ssteve.reinhardt@amd.com # Typically generates one or more %import or %include statements. 1087673Snate@binkert.org @classmethod 1097673Snate@binkert.org def swig_predecls(cls, code): 1107673Snate@binkert.org pass 1113101Sstever@eecs.umich.edu 1123101Sstever@eecs.umich.edu # default for printing to .ini file is regular string conversion. 1133101Sstever@eecs.umich.edu # will be overridden in some cases 1143101Sstever@eecs.umich.edu def ini_str(self): 1153101Sstever@eecs.umich.edu return str(self) 1163101Sstever@eecs.umich.edu 11710380SAndrew.Bardsley@arm.com # default for printing to .json file is regular string conversion. 11810380SAndrew.Bardsley@arm.com # will be overridden in some cases, mostly to use native Python 11910380SAndrew.Bardsley@arm.com # types where there are similar JSON types 12010380SAndrew.Bardsley@arm.com def config_value(self): 12110380SAndrew.Bardsley@arm.com return str(self) 12210380SAndrew.Bardsley@arm.com 1233101Sstever@eecs.umich.edu # allows us to blithely call unproxy() on things without checking 1243101Sstever@eecs.umich.edu # if they're really proxies or not 1253101Sstever@eecs.umich.edu def unproxy(self, base): 1263101Sstever@eecs.umich.edu return self 1273101Sstever@eecs.umich.edu 12810267SGeoffrey.Blake@arm.com # Produce a human readable version of the stored value 12910267SGeoffrey.Blake@arm.com def pretty_print(self, value): 13010267SGeoffrey.Blake@arm.com return str(value) 13110267SGeoffrey.Blake@arm.com 1323101Sstever@eecs.umich.edu# Regular parameter description. 1333101Sstever@eecs.umich.educlass ParamDesc(object): 1343101Sstever@eecs.umich.edu def __init__(self, ptype_str, ptype, *args, **kwargs): 1353101Sstever@eecs.umich.edu self.ptype_str = ptype_str 1363101Sstever@eecs.umich.edu # remember ptype only if it is provided 1373101Sstever@eecs.umich.edu if ptype != None: 1383101Sstever@eecs.umich.edu self.ptype = ptype 1393101Sstever@eecs.umich.edu 1403101Sstever@eecs.umich.edu if args: 1413101Sstever@eecs.umich.edu if len(args) == 1: 1423101Sstever@eecs.umich.edu self.desc = args[0] 1433101Sstever@eecs.umich.edu elif len(args) == 2: 1443101Sstever@eecs.umich.edu self.default = args[0] 1453101Sstever@eecs.umich.edu self.desc = args[1] 1463101Sstever@eecs.umich.edu else: 1473101Sstever@eecs.umich.edu raise TypeError, 'too many arguments' 1483101Sstever@eecs.umich.edu 1493101Sstever@eecs.umich.edu if kwargs.has_key('desc'): 1503101Sstever@eecs.umich.edu assert(not hasattr(self, 'desc')) 1513101Sstever@eecs.umich.edu self.desc = kwargs['desc'] 1523101Sstever@eecs.umich.edu del kwargs['desc'] 1533101Sstever@eecs.umich.edu 1543101Sstever@eecs.umich.edu if kwargs.has_key('default'): 1553101Sstever@eecs.umich.edu assert(not hasattr(self, 'default')) 1563101Sstever@eecs.umich.edu self.default = kwargs['default'] 1573101Sstever@eecs.umich.edu del kwargs['default'] 1583101Sstever@eecs.umich.edu 1593101Sstever@eecs.umich.edu if kwargs: 1603101Sstever@eecs.umich.edu raise TypeError, 'extra unknown kwargs %s' % kwargs 1613101Sstever@eecs.umich.edu 1623101Sstever@eecs.umich.edu if not hasattr(self, 'desc'): 1633101Sstever@eecs.umich.edu raise TypeError, 'desc attribute missing' 1643101Sstever@eecs.umich.edu 1653101Sstever@eecs.umich.edu def __getattr__(self, attr): 1663101Sstever@eecs.umich.edu if attr == 'ptype': 1675033Smilesck@eecs.umich.edu ptype = SimObject.allClasses[self.ptype_str] 1686656Snate@binkert.org assert isSimObjectClass(ptype) 1695033Smilesck@eecs.umich.edu self.ptype = ptype 1705033Smilesck@eecs.umich.edu return ptype 1715033Smilesck@eecs.umich.edu 1723101Sstever@eecs.umich.edu raise AttributeError, "'%s' object has no attribute '%s'" % \ 1733101Sstever@eecs.umich.edu (type(self).__name__, attr) 1743101Sstever@eecs.umich.edu 17510267SGeoffrey.Blake@arm.com def example_str(self): 17610267SGeoffrey.Blake@arm.com if hasattr(self.ptype, "ex_str"): 17710267SGeoffrey.Blake@arm.com return self.ptype.ex_str 17810267SGeoffrey.Blake@arm.com else: 17910267SGeoffrey.Blake@arm.com return self.ptype_str 18010267SGeoffrey.Blake@arm.com 18110267SGeoffrey.Blake@arm.com # Is the param available to be exposed on the command line 18210267SGeoffrey.Blake@arm.com def isCmdLineSettable(self): 18310267SGeoffrey.Blake@arm.com if hasattr(self.ptype, "cmd_line_settable"): 18410267SGeoffrey.Blake@arm.com return self.ptype.cmd_line_settable 18510267SGeoffrey.Blake@arm.com else: 18610267SGeoffrey.Blake@arm.com return False 18710267SGeoffrey.Blake@arm.com 1883101Sstever@eecs.umich.edu def convert(self, value): 1893101Sstever@eecs.umich.edu if isinstance(value, proxy.BaseProxy): 1903101Sstever@eecs.umich.edu value.set_param_desc(self) 1913101Sstever@eecs.umich.edu return value 1923101Sstever@eecs.umich.edu if not hasattr(self, 'ptype') and isNullPointer(value): 1933101Sstever@eecs.umich.edu # deferred evaluation of SimObject; continue to defer if 1943101Sstever@eecs.umich.edu # we're just assigning a null pointer 1953101Sstever@eecs.umich.edu return value 1963101Sstever@eecs.umich.edu if isinstance(value, self.ptype): 1973101Sstever@eecs.umich.edu return value 1983102Sstever@eecs.umich.edu if isNullPointer(value) and isSimObjectClass(self.ptype): 1993101Sstever@eecs.umich.edu return value 2003101Sstever@eecs.umich.edu return self.ptype(value) 2013101Sstever@eecs.umich.edu 20210267SGeoffrey.Blake@arm.com def pretty_print(self, value): 20310267SGeoffrey.Blake@arm.com if isinstance(value, proxy.BaseProxy): 20410267SGeoffrey.Blake@arm.com return str(value) 20510267SGeoffrey.Blake@arm.com if isNullPointer(value): 20610267SGeoffrey.Blake@arm.com return NULL 20710267SGeoffrey.Blake@arm.com return self.ptype(value).pretty_print(value) 20810267SGeoffrey.Blake@arm.com 2097673Snate@binkert.org def cxx_predecls(self, code): 2108607Sgblack@eecs.umich.edu code('#include <cstddef>') 2117673Snate@binkert.org self.ptype.cxx_predecls(code) 2123101Sstever@eecs.umich.edu 2137673Snate@binkert.org def swig_predecls(self, code): 2147673Snate@binkert.org self.ptype.swig_predecls(code) 2153101Sstever@eecs.umich.edu 2167673Snate@binkert.org def cxx_decl(self, code): 2177673Snate@binkert.org code('${{self.ptype.cxx_type}} ${{self.name}};') 2183101Sstever@eecs.umich.edu 2193101Sstever@eecs.umich.edu# Vector-valued parameter description. Just like ParamDesc, except 2203101Sstever@eecs.umich.edu# that the value is a vector (list) of the specified type instead of a 2213101Sstever@eecs.umich.edu# single value. 2223101Sstever@eecs.umich.edu 2233101Sstever@eecs.umich.educlass VectorParamValue(list): 2245033Smilesck@eecs.umich.edu __metaclass__ = MetaParamValue 2255475Snate@binkert.org def __setattr__(self, attr, value): 2265475Snate@binkert.org raise AttributeError, \ 2275475Snate@binkert.org "Not allowed to set %s on '%s'" % (attr, type(self).__name__) 2285475Snate@binkert.org 22910380SAndrew.Bardsley@arm.com def config_value(self): 23010380SAndrew.Bardsley@arm.com return [v.config_value() for v in self] 23110380SAndrew.Bardsley@arm.com 2323101Sstever@eecs.umich.edu def ini_str(self): 2333101Sstever@eecs.umich.edu return ' '.join([v.ini_str() for v in self]) 2343101Sstever@eecs.umich.edu 2354762Snate@binkert.org def getValue(self): 2364762Snate@binkert.org return [ v.getValue() for v in self ] 2374762Snate@binkert.org 2383101Sstever@eecs.umich.edu def unproxy(self, base): 2398460SAli.Saidi@ARM.com if len(self) == 1 and isinstance(self[0], proxy.AllProxy): 2408459SAli.Saidi@ARM.com return self[0].unproxy(base) 2418459SAli.Saidi@ARM.com else: 2428459SAli.Saidi@ARM.com return [v.unproxy(base) for v in self] 2433101Sstever@eecs.umich.edu 2447528Ssteve.reinhardt@amd.comclass SimObjectVector(VectorParamValue): 2457528Ssteve.reinhardt@amd.com # support clone operation 2467528Ssteve.reinhardt@amd.com def __call__(self, **kwargs): 2477528Ssteve.reinhardt@amd.com return SimObjectVector([v(**kwargs) for v in self]) 2487528Ssteve.reinhardt@amd.com 2497528Ssteve.reinhardt@amd.com def clear_parent(self, old_parent): 2503101Sstever@eecs.umich.edu for v in self: 2517528Ssteve.reinhardt@amd.com v.clear_parent(old_parent) 2527528Ssteve.reinhardt@amd.com 2537528Ssteve.reinhardt@amd.com def set_parent(self, parent, name): 2547528Ssteve.reinhardt@amd.com if len(self) == 1: 2557528Ssteve.reinhardt@amd.com self[0].set_parent(parent, name) 2567528Ssteve.reinhardt@amd.com else: 2577528Ssteve.reinhardt@amd.com width = int(math.ceil(math.log(len(self))/math.log(10))) 2587528Ssteve.reinhardt@amd.com for i,v in enumerate(self): 2597528Ssteve.reinhardt@amd.com v.set_parent(parent, "%s%0*d" % (name, width, i)) 2607528Ssteve.reinhardt@amd.com 2618321Ssteve.reinhardt@amd.com def has_parent(self): 2628321Ssteve.reinhardt@amd.com return reduce(lambda x,y: x and y, [v.has_parent() for v in self]) 2637528Ssteve.reinhardt@amd.com 2647528Ssteve.reinhardt@amd.com # return 'cpu0 cpu1' etc. for print_ini() 2657528Ssteve.reinhardt@amd.com def get_name(self): 2667528Ssteve.reinhardt@amd.com return ' '.join([v._name for v in self]) 2677528Ssteve.reinhardt@amd.com 2687528Ssteve.reinhardt@amd.com # By iterating through the constituent members of the vector here 2697528Ssteve.reinhardt@amd.com # we can nicely handle iterating over all a SimObject's children 2707528Ssteve.reinhardt@amd.com # without having to provide lots of special functions on 2717528Ssteve.reinhardt@amd.com # SimObjectVector directly. 2727528Ssteve.reinhardt@amd.com def descendants(self): 2737528Ssteve.reinhardt@amd.com for v in self: 2747528Ssteve.reinhardt@amd.com for obj in v.descendants(): 2757528Ssteve.reinhardt@amd.com yield obj 2763101Sstever@eecs.umich.edu 2778664SAli.Saidi@ARM.com def get_config_as_dict(self): 2788664SAli.Saidi@ARM.com a = [] 2798664SAli.Saidi@ARM.com for v in self: 2808664SAli.Saidi@ARM.com a.append(v.get_config_as_dict()) 2818664SAli.Saidi@ARM.com return a 2828664SAli.Saidi@ARM.com 2839953Sgeoffrey.blake@arm.com # If we are replacing an item in the vector, make sure to set the 2849953Sgeoffrey.blake@arm.com # parent reference of the new SimObject to be the same as the parent 2859953Sgeoffrey.blake@arm.com # of the SimObject being replaced. Useful to have if we created 2869953Sgeoffrey.blake@arm.com # a SimObjectVector of temporary objects that will be modified later in 2879953Sgeoffrey.blake@arm.com # configuration scripts. 2889953Sgeoffrey.blake@arm.com def __setitem__(self, key, value): 2899953Sgeoffrey.blake@arm.com val = self[key] 2909953Sgeoffrey.blake@arm.com if value.has_parent(): 2919953Sgeoffrey.blake@arm.com warn("SimObject %s already has a parent" % value.get_name() +\ 2929953Sgeoffrey.blake@arm.com " that is being overwritten by a SimObjectVector") 2939953Sgeoffrey.blake@arm.com value.set_parent(val.get_parent(), val._name) 2949953Sgeoffrey.blake@arm.com super(SimObjectVector, self).__setitem__(key, value) 2959953Sgeoffrey.blake@arm.com 29610267SGeoffrey.Blake@arm.com # Enumerate the params of each member of the SimObject vector. Creates 29710267SGeoffrey.Blake@arm.com # strings that will allow indexing into the vector by the python code and 29810267SGeoffrey.Blake@arm.com # allow it to be specified on the command line. 29910267SGeoffrey.Blake@arm.com def enumerateParams(self, flags_dict = {}, 30010267SGeoffrey.Blake@arm.com cmd_line_str = "", 30110267SGeoffrey.Blake@arm.com access_str = ""): 30210267SGeoffrey.Blake@arm.com if hasattr(self, "_paramEnumed"): 30310267SGeoffrey.Blake@arm.com print "Cycle detected enumerating params at %s?!" % (cmd_line_str) 30410267SGeoffrey.Blake@arm.com else: 30510267SGeoffrey.Blake@arm.com x = 0 30610267SGeoffrey.Blake@arm.com for vals in self: 30710267SGeoffrey.Blake@arm.com # Each entry in the SimObjectVector should be an 30810267SGeoffrey.Blake@arm.com # instance of a SimObject 30910267SGeoffrey.Blake@arm.com flags_dict = vals.enumerateParams(flags_dict, 31010267SGeoffrey.Blake@arm.com cmd_line_str + "%d." % x, 31110267SGeoffrey.Blake@arm.com access_str + "[%d]." % x) 31210267SGeoffrey.Blake@arm.com x = x + 1 31310267SGeoffrey.Blake@arm.com 31410267SGeoffrey.Blake@arm.com return flags_dict 31510267SGeoffrey.Blake@arm.com 3163101Sstever@eecs.umich.educlass VectorParamDesc(ParamDesc): 3173101Sstever@eecs.umich.edu # Convert assigned value to appropriate type. If the RHS is not a 3183101Sstever@eecs.umich.edu # list or tuple, it generates a single-element list. 3193101Sstever@eecs.umich.edu def convert(self, value): 3203101Sstever@eecs.umich.edu if isinstance(value, (list, tuple)): 3213101Sstever@eecs.umich.edu # list: coerce each element into new list 3223101Sstever@eecs.umich.edu tmp_list = [ ParamDesc.convert(self, v) for v in value ] 32310364SGeoffrey.Blake@arm.com elif isinstance(value, str): 32410364SGeoffrey.Blake@arm.com # If input is a csv string 32510364SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.convert(self, v) \ 32610364SGeoffrey.Blake@arm.com for v in value.strip('[').strip(']').split(',') ] 3273101Sstever@eecs.umich.edu else: 3284762Snate@binkert.org # singleton: coerce to a single-element list 3294762Snate@binkert.org tmp_list = [ ParamDesc.convert(self, value) ] 3304762Snate@binkert.org 3314762Snate@binkert.org if isSimObjectSequence(tmp_list): 3327528Ssteve.reinhardt@amd.com return SimObjectVector(tmp_list) 3334762Snate@binkert.org else: 3344762Snate@binkert.org return VectorParamValue(tmp_list) 3354762Snate@binkert.org 33610267SGeoffrey.Blake@arm.com # Produce a human readable example string that describes 33710267SGeoffrey.Blake@arm.com # how to set this vector parameter in the absence of a default 33810267SGeoffrey.Blake@arm.com # value. 33910267SGeoffrey.Blake@arm.com def example_str(self): 34010267SGeoffrey.Blake@arm.com s = super(VectorParamDesc, self).example_str() 34110267SGeoffrey.Blake@arm.com help_str = "[" + s + "," + s + ", ...]" 34210267SGeoffrey.Blake@arm.com return help_str 34310267SGeoffrey.Blake@arm.com 34410267SGeoffrey.Blake@arm.com # Produce a human readable representation of the value of this vector param. 34510267SGeoffrey.Blake@arm.com def pretty_print(self, value): 34610267SGeoffrey.Blake@arm.com if isinstance(value, (list, tuple)): 34710267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.pretty_print(self, v) for v in value ] 34810267SGeoffrey.Blake@arm.com elif isinstance(value, str): 34910267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.pretty_print(self, v) for v in value.split(',') ] 35010267SGeoffrey.Blake@arm.com else: 35110267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.pretty_print(self, value) ] 35210267SGeoffrey.Blake@arm.com 35310267SGeoffrey.Blake@arm.com return tmp_list 35410267SGeoffrey.Blake@arm.com 35510267SGeoffrey.Blake@arm.com # This is a helper function for the new config system 35610267SGeoffrey.Blake@arm.com def __call__(self, value): 35710267SGeoffrey.Blake@arm.com if isinstance(value, (list, tuple)): 35810267SGeoffrey.Blake@arm.com # list: coerce each element into new list 35910267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.convert(self, v) for v in value ] 36010267SGeoffrey.Blake@arm.com elif isinstance(value, str): 36110267SGeoffrey.Blake@arm.com # If input is a csv string 36210364SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.convert(self, v) \ 36310364SGeoffrey.Blake@arm.com for v in value.strip('[').strip(']').split(',') ] 36410267SGeoffrey.Blake@arm.com else: 36510267SGeoffrey.Blake@arm.com # singleton: coerce to a single-element list 36610267SGeoffrey.Blake@arm.com tmp_list = [ ParamDesc.convert(self, value) ] 36710267SGeoffrey.Blake@arm.com 36810267SGeoffrey.Blake@arm.com return VectorParamValue(tmp_list) 36910267SGeoffrey.Blake@arm.com 3708596Ssteve.reinhardt@amd.com def swig_module_name(self): 3718596Ssteve.reinhardt@amd.com return "%s_vector" % self.ptype_str 3728596Ssteve.reinhardt@amd.com 3737673Snate@binkert.org def swig_predecls(self, code): 3748596Ssteve.reinhardt@amd.com code('%import "${{self.swig_module_name()}}.i"') 3754762Snate@binkert.org 3767673Snate@binkert.org def swig_decl(self, code): 3778596Ssteve.reinhardt@amd.com code('%module(package="m5.internal") ${{self.swig_module_name()}}') 3787675Snate@binkert.org code('%{') 3797675Snate@binkert.org self.ptype.cxx_predecls(code) 3807675Snate@binkert.org code('%}') 3817675Snate@binkert.org code() 3828656Sandreas.hansson@arm.com # Make sure the SWIGPY_SLICE_ARG is defined through this inclusion 3838656Sandreas.hansson@arm.com code('%include "std_container.i"') 3848656Sandreas.hansson@arm.com code() 3857675Snate@binkert.org self.ptype.swig_predecls(code) 3867675Snate@binkert.org code() 3877673Snate@binkert.org code('%include "std_vector.i"') 3887675Snate@binkert.org code() 3897675Snate@binkert.org 3907675Snate@binkert.org ptype = self.ptype_str 3917675Snate@binkert.org cxx_type = self.ptype.cxx_type 3927675Snate@binkert.org 3937675Snate@binkert.org code('%template(vector_$ptype) std::vector< $cxx_type >;') 3947675Snate@binkert.org 3957673Snate@binkert.org def cxx_predecls(self, code): 3967673Snate@binkert.org code('#include <vector>') 3977673Snate@binkert.org self.ptype.cxx_predecls(code) 3983101Sstever@eecs.umich.edu 3997673Snate@binkert.org def cxx_decl(self, code): 4007673Snate@binkert.org code('std::vector< ${{self.ptype.cxx_type}} > ${{self.name}};') 4013101Sstever@eecs.umich.edu 4023101Sstever@eecs.umich.educlass ParamFactory(object): 4033101Sstever@eecs.umich.edu def __init__(self, param_desc_class, ptype_str = None): 4043101Sstever@eecs.umich.edu self.param_desc_class = param_desc_class 4053101Sstever@eecs.umich.edu self.ptype_str = ptype_str 4063101Sstever@eecs.umich.edu 4073101Sstever@eecs.umich.edu def __getattr__(self, attr): 4083101Sstever@eecs.umich.edu if self.ptype_str: 4093101Sstever@eecs.umich.edu attr = self.ptype_str + '.' + attr 4103101Sstever@eecs.umich.edu return ParamFactory(self.param_desc_class, attr) 4113101Sstever@eecs.umich.edu 4123101Sstever@eecs.umich.edu # E.g., Param.Int(5, "number of widgets") 4133101Sstever@eecs.umich.edu def __call__(self, *args, **kwargs): 4143101Sstever@eecs.umich.edu ptype = None 4153101Sstever@eecs.umich.edu try: 4165033Smilesck@eecs.umich.edu ptype = allParams[self.ptype_str] 4175033Smilesck@eecs.umich.edu except KeyError: 4183101Sstever@eecs.umich.edu # if name isn't defined yet, assume it's a SimObject, and 4193101Sstever@eecs.umich.edu # try to resolve it later 4203101Sstever@eecs.umich.edu pass 4213101Sstever@eecs.umich.edu return self.param_desc_class(self.ptype_str, ptype, *args, **kwargs) 4223101Sstever@eecs.umich.edu 4233101Sstever@eecs.umich.eduParam = ParamFactory(ParamDesc) 4243101Sstever@eecs.umich.eduVectorParam = ParamFactory(VectorParamDesc) 4253101Sstever@eecs.umich.edu 4263101Sstever@eecs.umich.edu##################################################################### 4273101Sstever@eecs.umich.edu# 4283101Sstever@eecs.umich.edu# Parameter Types 4293101Sstever@eecs.umich.edu# 4303101Sstever@eecs.umich.edu# Though native Python types could be used to specify parameter types 4313101Sstever@eecs.umich.edu# (the 'ptype' field of the Param and VectorParam classes), it's more 4323101Sstever@eecs.umich.edu# flexible to define our own set of types. This gives us more control 4333101Sstever@eecs.umich.edu# over how Python expressions are converted to values (via the 4343101Sstever@eecs.umich.edu# __init__() constructor) and how these values are printed out (via 4353101Sstever@eecs.umich.edu# the __str__() conversion method). 4363101Sstever@eecs.umich.edu# 4373101Sstever@eecs.umich.edu##################################################################### 4383101Sstever@eecs.umich.edu 4393101Sstever@eecs.umich.edu# String-valued parameter. Just mixin the ParamValue class with the 4403101Sstever@eecs.umich.edu# built-in str class. 4413101Sstever@eecs.umich.educlass String(ParamValue,str): 4423101Sstever@eecs.umich.edu cxx_type = 'std::string' 44310267SGeoffrey.Blake@arm.com cmd_line_settable = True 4447673Snate@binkert.org 4457673Snate@binkert.org @classmethod 4467673Snate@binkert.org def cxx_predecls(self, code): 4477673Snate@binkert.org code('#include <string>') 4487673Snate@binkert.org 4497673Snate@binkert.org @classmethod 4507673Snate@binkert.org def swig_predecls(cls, code): 4517673Snate@binkert.org code('%include "std_string.i"') 4524762Snate@binkert.org 45310267SGeoffrey.Blake@arm.com def __call__(self, value): 45410267SGeoffrey.Blake@arm.com self = value 45510267SGeoffrey.Blake@arm.com return value 45610267SGeoffrey.Blake@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): 4643101Sstever@eecs.umich.edu def __str__(self): 4653101Sstever@eecs.umich.edu return str(self.value) 4663101Sstever@eecs.umich.edu 4673101Sstever@eecs.umich.edu def __float__(self): 4683101Sstever@eecs.umich.edu return float(self.value) 4693101Sstever@eecs.umich.edu 4703714Sstever@eecs.umich.edu def __long__(self): 4713714Sstever@eecs.umich.edu return long(self.value) 4723714Sstever@eecs.umich.edu 4733714Sstever@eecs.umich.edu def __int__(self): 4743714Sstever@eecs.umich.edu return int(self.value) 4753714Sstever@eecs.umich.edu 4763101Sstever@eecs.umich.edu # hook for bounds checking 4773101Sstever@eecs.umich.edu def _check(self): 4783101Sstever@eecs.umich.edu return 4793101Sstever@eecs.umich.edu 4803101Sstever@eecs.umich.edu def __mul__(self, other): 4813101Sstever@eecs.umich.edu newobj = self.__class__(self) 4823101Sstever@eecs.umich.edu newobj.value *= other 4833101Sstever@eecs.umich.edu newobj._check() 4843101Sstever@eecs.umich.edu return newobj 4853101Sstever@eecs.umich.edu 4863101Sstever@eecs.umich.edu __rmul__ = __mul__ 4873101Sstever@eecs.umich.edu 4883101Sstever@eecs.umich.edu def __div__(self, other): 4893101Sstever@eecs.umich.edu newobj = self.__class__(self) 4903101Sstever@eecs.umich.edu newobj.value /= other 4913101Sstever@eecs.umich.edu newobj._check() 4923101Sstever@eecs.umich.edu return newobj 4933101Sstever@eecs.umich.edu 4943101Sstever@eecs.umich.edu def __sub__(self, other): 4953101Sstever@eecs.umich.edu newobj = self.__class__(self) 4963101Sstever@eecs.umich.edu newobj.value -= other 4973101Sstever@eecs.umich.edu newobj._check() 4983101Sstever@eecs.umich.edu return newobj 4993101Sstever@eecs.umich.edu 50010380SAndrew.Bardsley@arm.com def config_value(self): 50110380SAndrew.Bardsley@arm.com return self.value 50210380SAndrew.Bardsley@arm.com 5033101Sstever@eecs.umich.edu# Metaclass for bounds-checked integer parameters. See CheckedInt. 5045033Smilesck@eecs.umich.educlass CheckedIntType(MetaParamValue): 5053101Sstever@eecs.umich.edu def __init__(cls, name, bases, dict): 5063101Sstever@eecs.umich.edu super(CheckedIntType, cls).__init__(name, bases, dict) 5073101Sstever@eecs.umich.edu 5083101Sstever@eecs.umich.edu # CheckedInt is an abstract base class, so we actually don't 5093101Sstever@eecs.umich.edu # want to do any processing on it... the rest of this code is 5103101Sstever@eecs.umich.edu # just for classes that derive from CheckedInt. 5113101Sstever@eecs.umich.edu if name == 'CheckedInt': 5123101Sstever@eecs.umich.edu return 5133101Sstever@eecs.umich.edu 5143101Sstever@eecs.umich.edu if not (hasattr(cls, 'min') and hasattr(cls, 'max')): 5153101Sstever@eecs.umich.edu if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')): 5163101Sstever@eecs.umich.edu panic("CheckedInt subclass %s must define either\n" \ 5175822Ssaidi@eecs.umich.edu " 'min' and 'max' or 'size' and 'unsigned'\n", 5185822Ssaidi@eecs.umich.edu name); 5193101Sstever@eecs.umich.edu if cls.unsigned: 5203101Sstever@eecs.umich.edu cls.min = 0 5213101Sstever@eecs.umich.edu cls.max = 2 ** cls.size - 1 5223101Sstever@eecs.umich.edu else: 5233101Sstever@eecs.umich.edu cls.min = -(2 ** (cls.size - 1)) 5243101Sstever@eecs.umich.edu cls.max = (2 ** (cls.size - 1)) - 1 5253101Sstever@eecs.umich.edu 5263101Sstever@eecs.umich.edu# Abstract superclass for bounds-checked integer parameters. This 5273101Sstever@eecs.umich.edu# class is subclassed to generate parameter classes with specific 5283101Sstever@eecs.umich.edu# bounds. Initialization of the min and max bounds is done in the 5293101Sstever@eecs.umich.edu# metaclass CheckedIntType.__init__. 5303101Sstever@eecs.umich.educlass CheckedInt(NumericParamValue): 5313101Sstever@eecs.umich.edu __metaclass__ = CheckedIntType 53210267SGeoffrey.Blake@arm.com cmd_line_settable = True 5333101Sstever@eecs.umich.edu 5343101Sstever@eecs.umich.edu def _check(self): 5353101Sstever@eecs.umich.edu if not self.min <= self.value <= self.max: 5363101Sstever@eecs.umich.edu raise TypeError, 'Integer param out of bounds %d < %d < %d' % \ 5373101Sstever@eecs.umich.edu (self.min, self.value, self.max) 5383101Sstever@eecs.umich.edu 5393101Sstever@eecs.umich.edu def __init__(self, value): 5403101Sstever@eecs.umich.edu if isinstance(value, str): 5413102Sstever@eecs.umich.edu self.value = convert.toInteger(value) 5423714Sstever@eecs.umich.edu elif isinstance(value, (int, long, float, NumericParamValue)): 5433101Sstever@eecs.umich.edu self.value = long(value) 5443714Sstever@eecs.umich.edu else: 5453714Sstever@eecs.umich.edu raise TypeError, "Can't convert object of type %s to CheckedInt" \ 5463714Sstever@eecs.umich.edu % type(value).__name__ 5473101Sstever@eecs.umich.edu self._check() 5483101Sstever@eecs.umich.edu 54910267SGeoffrey.Blake@arm.com def __call__(self, value): 55010267SGeoffrey.Blake@arm.com self.__init__(value) 55110267SGeoffrey.Blake@arm.com return value 55210267SGeoffrey.Blake@arm.com 5537673Snate@binkert.org @classmethod 5547673Snate@binkert.org def cxx_predecls(cls, code): 5557673Snate@binkert.org # most derived types require this, so we just do it here once 5567673Snate@binkert.org code('#include "base/types.hh"') 5577673Snate@binkert.org 5587673Snate@binkert.org @classmethod 5597673Snate@binkert.org def swig_predecls(cls, code): 5607673Snate@binkert.org # most derived types require this, so we just do it here once 5617673Snate@binkert.org code('%import "stdint.i"') 5627673Snate@binkert.org code('%import "base/types.hh"') 5637673Snate@binkert.org 5644762Snate@binkert.org def getValue(self): 5654762Snate@binkert.org return long(self.value) 5664762Snate@binkert.org 5673101Sstever@eecs.umich.educlass Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False 5683101Sstever@eecs.umich.educlass Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True 5693101Sstever@eecs.umich.edu 5703101Sstever@eecs.umich.educlass Int8(CheckedInt): cxx_type = 'int8_t'; size = 8; unsigned = False 5713101Sstever@eecs.umich.educlass UInt8(CheckedInt): cxx_type = 'uint8_t'; size = 8; unsigned = True 5723101Sstever@eecs.umich.educlass Int16(CheckedInt): cxx_type = 'int16_t'; size = 16; unsigned = False 5733101Sstever@eecs.umich.educlass UInt16(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 5743101Sstever@eecs.umich.educlass Int32(CheckedInt): cxx_type = 'int32_t'; size = 32; unsigned = False 5753101Sstever@eecs.umich.educlass UInt32(CheckedInt): cxx_type = 'uint32_t'; size = 32; unsigned = True 5763101Sstever@eecs.umich.educlass Int64(CheckedInt): cxx_type = 'int64_t'; size = 64; unsigned = False 5773101Sstever@eecs.umich.educlass UInt64(CheckedInt): cxx_type = 'uint64_t'; size = 64; unsigned = True 5783101Sstever@eecs.umich.edu 5793101Sstever@eecs.umich.educlass Counter(CheckedInt): cxx_type = 'Counter'; size = 64; unsigned = True 5803101Sstever@eecs.umich.educlass Tick(CheckedInt): cxx_type = 'Tick'; size = 64; unsigned = True 5813101Sstever@eecs.umich.educlass TcpPort(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 5823101Sstever@eecs.umich.educlass UdpPort(CheckedInt): cxx_type = 'uint16_t'; size = 16; unsigned = True 5833101Sstever@eecs.umich.edu 5843101Sstever@eecs.umich.educlass Percent(CheckedInt): cxx_type = 'int'; min = 0; max = 100 5853101Sstever@eecs.umich.edu 5869184Sandreas.hansson@arm.comclass Cycles(CheckedInt): 5879184Sandreas.hansson@arm.com cxx_type = 'Cycles' 5889184Sandreas.hansson@arm.com size = 64 5899184Sandreas.hansson@arm.com unsigned = True 5909184Sandreas.hansson@arm.com 5919184Sandreas.hansson@arm.com def getValue(self): 5929184Sandreas.hansson@arm.com from m5.internal.core import Cycles 5939184Sandreas.hansson@arm.com return Cycles(self.value) 5949184Sandreas.hansson@arm.com 5953101Sstever@eecs.umich.educlass Float(ParamValue, float): 5964446Sbinkertn@umich.edu cxx_type = 'double' 59710267SGeoffrey.Blake@arm.com cmdLineSettable = True 5983101Sstever@eecs.umich.edu 5995468Snate@binkert.org def __init__(self, value): 60010267SGeoffrey.Blake@arm.com if isinstance(value, (int, long, float, NumericParamValue, Float, str)): 6015468Snate@binkert.org self.value = float(value) 6025468Snate@binkert.org else: 6035468Snate@binkert.org raise TypeError, "Can't convert object of type %s to Float" \ 6045468Snate@binkert.org % type(value).__name__ 6055468Snate@binkert.org 60610267SGeoffrey.Blake@arm.com def __call__(self, value): 60710267SGeoffrey.Blake@arm.com self.__init__(value) 60810267SGeoffrey.Blake@arm.com return value 60910267SGeoffrey.Blake@arm.com 6104762Snate@binkert.org def getValue(self): 6114762Snate@binkert.org return float(self.value) 6124762Snate@binkert.org 61310380SAndrew.Bardsley@arm.com def config_value(self): 61410380SAndrew.Bardsley@arm.com return self 61510380SAndrew.Bardsley@arm.com 6163101Sstever@eecs.umich.educlass MemorySize(CheckedInt): 6173101Sstever@eecs.umich.edu cxx_type = 'uint64_t' 61810267SGeoffrey.Blake@arm.com ex_str = '512MB' 6193101Sstever@eecs.umich.edu size = 64 6203101Sstever@eecs.umich.edu unsigned = True 6213101Sstever@eecs.umich.edu def __init__(self, value): 6223101Sstever@eecs.umich.edu if isinstance(value, MemorySize): 6233101Sstever@eecs.umich.edu self.value = value.value 6243101Sstever@eecs.umich.edu else: 6253102Sstever@eecs.umich.edu self.value = convert.toMemorySize(value) 6263101Sstever@eecs.umich.edu self._check() 6273101Sstever@eecs.umich.edu 6283101Sstever@eecs.umich.educlass MemorySize32(CheckedInt): 6294168Sbinkertn@umich.edu cxx_type = 'uint32_t' 63010267SGeoffrey.Blake@arm.com ex_str = '512MB' 6313101Sstever@eecs.umich.edu size = 32 6323101Sstever@eecs.umich.edu unsigned = True 6333101Sstever@eecs.umich.edu def __init__(self, value): 6343101Sstever@eecs.umich.edu if isinstance(value, MemorySize): 6353101Sstever@eecs.umich.edu self.value = value.value 6363101Sstever@eecs.umich.edu else: 6373102Sstever@eecs.umich.edu self.value = convert.toMemorySize(value) 6383101Sstever@eecs.umich.edu self._check() 6393101Sstever@eecs.umich.edu 6403101Sstever@eecs.umich.educlass Addr(CheckedInt): 6413101Sstever@eecs.umich.edu cxx_type = 'Addr' 6423101Sstever@eecs.umich.edu size = 64 6433101Sstever@eecs.umich.edu unsigned = True 6443101Sstever@eecs.umich.edu def __init__(self, value): 6453101Sstever@eecs.umich.edu if isinstance(value, Addr): 6463101Sstever@eecs.umich.edu self.value = value.value 6473101Sstever@eecs.umich.edu else: 6483101Sstever@eecs.umich.edu try: 64910317Smitch.hayenga@arm.com # Often addresses are referred to with sizes. Ex: A device 65010317Smitch.hayenga@arm.com # base address is at "512MB". Use toMemorySize() to convert 65110317Smitch.hayenga@arm.com # these into addresses. If the address is not specified with a 65210317Smitch.hayenga@arm.com # "size", an exception will occur and numeric translation will 65310317Smitch.hayenga@arm.com # proceed below. 6543102Sstever@eecs.umich.edu self.value = convert.toMemorySize(value) 65510317Smitch.hayenga@arm.com except (TypeError, ValueError): 65610317Smitch.hayenga@arm.com # Convert number to string and use long() to do automatic 65710317Smitch.hayenga@arm.com # base conversion (requires base=0 for auto-conversion) 65810317Smitch.hayenga@arm.com self.value = long(str(value), base=0) 65910317Smitch.hayenga@arm.com 6603101Sstever@eecs.umich.edu self._check() 6613584Ssaidi@eecs.umich.edu def __add__(self, other): 6623584Ssaidi@eecs.umich.edu if isinstance(other, Addr): 6633584Ssaidi@eecs.umich.edu return self.value + other.value 6643584Ssaidi@eecs.umich.edu else: 6653584Ssaidi@eecs.umich.edu return self.value + other 66610267SGeoffrey.Blake@arm.com def pretty_print(self, value): 66710267SGeoffrey.Blake@arm.com try: 66810267SGeoffrey.Blake@arm.com val = convert.toMemorySize(value) 66910267SGeoffrey.Blake@arm.com except TypeError: 67010267SGeoffrey.Blake@arm.com val = long(value) 67110267SGeoffrey.Blake@arm.com return "0x%x" % long(val) 6723101Sstever@eecs.umich.edu 6739232Sandreas.hansson@arm.comclass AddrRange(ParamValue): 6749235Sandreas.hansson@arm.com cxx_type = 'AddrRange' 6753101Sstever@eecs.umich.edu 6763101Sstever@eecs.umich.edu def __init__(self, *args, **kwargs): 6779411Sandreas.hansson@arm.com # Disable interleaving by default 6789411Sandreas.hansson@arm.com self.intlvHighBit = 0 6799411Sandreas.hansson@arm.com self.intlvBits = 0 6809411Sandreas.hansson@arm.com self.intlvMatch = 0 6819411Sandreas.hansson@arm.com 6823101Sstever@eecs.umich.edu def handle_kwargs(self, kwargs): 6839411Sandreas.hansson@arm.com # An address range needs to have an upper limit, specified 6849411Sandreas.hansson@arm.com # either explicitly with an end, or as an offset using the 6859411Sandreas.hansson@arm.com # size keyword. 6863101Sstever@eecs.umich.edu if 'end' in kwargs: 6879232Sandreas.hansson@arm.com self.end = Addr(kwargs.pop('end')) 6883101Sstever@eecs.umich.edu elif 'size' in kwargs: 6899232Sandreas.hansson@arm.com self.end = self.start + Addr(kwargs.pop('size')) - 1 6903101Sstever@eecs.umich.edu else: 6913101Sstever@eecs.umich.edu raise TypeError, "Either end or size must be specified" 6923101Sstever@eecs.umich.edu 6939411Sandreas.hansson@arm.com # Now on to the optional bit 6949411Sandreas.hansson@arm.com if 'intlvHighBit' in kwargs: 6959411Sandreas.hansson@arm.com self.intlvHighBit = int(kwargs.pop('intlvHighBit')) 6969411Sandreas.hansson@arm.com if 'intlvBits' in kwargs: 6979411Sandreas.hansson@arm.com self.intlvBits = int(kwargs.pop('intlvBits')) 6989411Sandreas.hansson@arm.com if 'intlvMatch' in kwargs: 6999411Sandreas.hansson@arm.com self.intlvMatch = int(kwargs.pop('intlvMatch')) 7009411Sandreas.hansson@arm.com 7013101Sstever@eecs.umich.edu if len(args) == 0: 7029232Sandreas.hansson@arm.com self.start = Addr(kwargs.pop('start')) 7033101Sstever@eecs.umich.edu handle_kwargs(self, kwargs) 7043101Sstever@eecs.umich.edu 7053101Sstever@eecs.umich.edu elif len(args) == 1: 7063101Sstever@eecs.umich.edu if kwargs: 7079232Sandreas.hansson@arm.com self.start = Addr(args[0]) 7083101Sstever@eecs.umich.edu handle_kwargs(self, kwargs) 7095219Ssaidi@eecs.umich.edu elif isinstance(args[0], (list, tuple)): 7109232Sandreas.hansson@arm.com self.start = Addr(args[0][0]) 7119232Sandreas.hansson@arm.com self.end = Addr(args[0][1]) 7123101Sstever@eecs.umich.edu else: 7139232Sandreas.hansson@arm.com self.start = Addr(0) 7149232Sandreas.hansson@arm.com self.end = Addr(args[0]) - 1 7153101Sstever@eecs.umich.edu 7163101Sstever@eecs.umich.edu elif len(args) == 2: 7179232Sandreas.hansson@arm.com self.start = Addr(args[0]) 7189232Sandreas.hansson@arm.com self.end = Addr(args[1]) 7193101Sstever@eecs.umich.edu else: 7203101Sstever@eecs.umich.edu raise TypeError, "Too many arguments specified" 7213101Sstever@eecs.umich.edu 7223101Sstever@eecs.umich.edu if kwargs: 7239232Sandreas.hansson@arm.com raise TypeError, "Too many keywords: %s" % kwargs.keys() 7243101Sstever@eecs.umich.edu 7253101Sstever@eecs.umich.edu def __str__(self): 7269232Sandreas.hansson@arm.com return '%s:%s' % (self.start, self.end) 7279232Sandreas.hansson@arm.com 7289232Sandreas.hansson@arm.com def size(self): 7299411Sandreas.hansson@arm.com # Divide the size by the size of the interleaving slice 7309411Sandreas.hansson@arm.com return (long(self.end) - long(self.start) + 1) >> self.intlvBits 7313101Sstever@eecs.umich.edu 7327673Snate@binkert.org @classmethod 7337673Snate@binkert.org def cxx_predecls(cls, code): 7349232Sandreas.hansson@arm.com Addr.cxx_predecls(code) 7359235Sandreas.hansson@arm.com code('#include "base/addr_range.hh"') 7367675Snate@binkert.org 7377675Snate@binkert.org @classmethod 7387675Snate@binkert.org def swig_predecls(cls, code): 7399232Sandreas.hansson@arm.com Addr.swig_predecls(code) 7407673Snate@binkert.org 7414762Snate@binkert.org def getValue(self): 7429235Sandreas.hansson@arm.com # Go from the Python class to the wrapped C++ class generated 7439235Sandreas.hansson@arm.com # by swig 7447675Snate@binkert.org from m5.internal.range import AddrRange 7454762Snate@binkert.org 7469411Sandreas.hansson@arm.com return AddrRange(long(self.start), long(self.end), 7479411Sandreas.hansson@arm.com int(self.intlvHighBit), int(self.intlvBits), 7489411Sandreas.hansson@arm.com int(self.intlvMatch)) 7493101Sstever@eecs.umich.edu 7503101Sstever@eecs.umich.edu# Boolean parameter type. Python doesn't let you subclass bool, since 7513101Sstever@eecs.umich.edu# it doesn't want to let you create multiple instances of True and 7523101Sstever@eecs.umich.edu# False. Thus this is a little more complicated than String. 7533101Sstever@eecs.umich.educlass Bool(ParamValue): 7543101Sstever@eecs.umich.edu cxx_type = 'bool' 75510267SGeoffrey.Blake@arm.com cmd_line_settable = True 75610267SGeoffrey.Blake@arm.com 7573101Sstever@eecs.umich.edu def __init__(self, value): 7583101Sstever@eecs.umich.edu try: 7593102Sstever@eecs.umich.edu self.value = convert.toBool(value) 7603101Sstever@eecs.umich.edu except TypeError: 7613101Sstever@eecs.umich.edu self.value = bool(value) 7623101Sstever@eecs.umich.edu 76310267SGeoffrey.Blake@arm.com def __call__(self, value): 76410267SGeoffrey.Blake@arm.com self.__init__(value) 76510267SGeoffrey.Blake@arm.com return value 76610267SGeoffrey.Blake@arm.com 7674762Snate@binkert.org def getValue(self): 7684762Snate@binkert.org return bool(self.value) 7694762Snate@binkert.org 7703101Sstever@eecs.umich.edu def __str__(self): 7713101Sstever@eecs.umich.edu return str(self.value) 7723101Sstever@eecs.umich.edu 7738934SBrad.Beckmann@amd.com # implement truth value testing for Bool parameters so that these params 7748934SBrad.Beckmann@amd.com # evaluate correctly during the python configuration phase 7758934SBrad.Beckmann@amd.com def __nonzero__(self): 7768934SBrad.Beckmann@amd.com return bool(self.value) 7778934SBrad.Beckmann@amd.com 7783101Sstever@eecs.umich.edu def ini_str(self): 7793101Sstever@eecs.umich.edu if self.value: 7803101Sstever@eecs.umich.edu return 'true' 7813101Sstever@eecs.umich.edu return 'false' 7823101Sstever@eecs.umich.edu 78310380SAndrew.Bardsley@arm.com def config_value(self): 78410380SAndrew.Bardsley@arm.com return self.value 78510380SAndrew.Bardsley@arm.com 7863101Sstever@eecs.umich.edudef IncEthernetAddr(addr, val = 1): 7873101Sstever@eecs.umich.edu bytes = map(lambda x: int(x, 16), addr.split(':')) 7883101Sstever@eecs.umich.edu bytes[5] += val 7893101Sstever@eecs.umich.edu for i in (5, 4, 3, 2, 1): 7903101Sstever@eecs.umich.edu val,rem = divmod(bytes[i], 256) 7913101Sstever@eecs.umich.edu bytes[i] = rem 7923101Sstever@eecs.umich.edu if val == 0: 7933101Sstever@eecs.umich.edu break 7943101Sstever@eecs.umich.edu bytes[i - 1] += val 7953101Sstever@eecs.umich.edu assert(bytes[0] <= 255) 7963101Sstever@eecs.umich.edu return ':'.join(map(lambda x: '%02x' % x, bytes)) 7973101Sstever@eecs.umich.edu 7984380Sbinkertn@umich.edu_NextEthernetAddr = "00:90:00:00:00:01" 7994380Sbinkertn@umich.edudef NextEthernetAddr(): 8004380Sbinkertn@umich.edu global _NextEthernetAddr 8013101Sstever@eecs.umich.edu 8024380Sbinkertn@umich.edu value = _NextEthernetAddr 8034380Sbinkertn@umich.edu _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1) 8044380Sbinkertn@umich.edu return value 8053101Sstever@eecs.umich.edu 8063101Sstever@eecs.umich.educlass EthernetAddr(ParamValue): 8073101Sstever@eecs.umich.edu cxx_type = 'Net::EthAddr' 80810267SGeoffrey.Blake@arm.com ex_str = "00:90:00:00:00:01" 80910267SGeoffrey.Blake@arm.com cmd_line_settable = True 8107673Snate@binkert.org 8117673Snate@binkert.org @classmethod 8127673Snate@binkert.org def cxx_predecls(cls, code): 8137673Snate@binkert.org code('#include "base/inet.hh"') 8147673Snate@binkert.org 8157673Snate@binkert.org @classmethod 8167673Snate@binkert.org def swig_predecls(cls, code): 8177673Snate@binkert.org code('%include "python/swig/inet.i"') 8187673Snate@binkert.org 8193101Sstever@eecs.umich.edu def __init__(self, value): 8203101Sstever@eecs.umich.edu if value == NextEthernetAddr: 8213101Sstever@eecs.umich.edu self.value = value 8223101Sstever@eecs.umich.edu return 8233101Sstever@eecs.umich.edu 8243101Sstever@eecs.umich.edu if not isinstance(value, str): 8253101Sstever@eecs.umich.edu raise TypeError, "expected an ethernet address and didn't get one" 8263101Sstever@eecs.umich.edu 8273101Sstever@eecs.umich.edu bytes = value.split(':') 8283101Sstever@eecs.umich.edu if len(bytes) != 6: 8293101Sstever@eecs.umich.edu raise TypeError, 'invalid ethernet address %s' % value 8303101Sstever@eecs.umich.edu 8313101Sstever@eecs.umich.edu for byte in bytes: 8329941SGeoffrey.Blake@arm.com if not 0 <= int(byte, base=16) <= 0xff: 8333101Sstever@eecs.umich.edu raise TypeError, 'invalid ethernet address %s' % value 8343101Sstever@eecs.umich.edu 8353101Sstever@eecs.umich.edu self.value = value 8363101Sstever@eecs.umich.edu 83710267SGeoffrey.Blake@arm.com def __call__(self, value): 83810267SGeoffrey.Blake@arm.com self.__init__(value) 83910267SGeoffrey.Blake@arm.com return value 84010267SGeoffrey.Blake@arm.com 8413101Sstever@eecs.umich.edu def unproxy(self, base): 8423101Sstever@eecs.umich.edu if self.value == NextEthernetAddr: 8434380Sbinkertn@umich.edu return EthernetAddr(self.value()) 8443101Sstever@eecs.umich.edu return self 8453101Sstever@eecs.umich.edu 8464762Snate@binkert.org def getValue(self): 8477677Snate@binkert.org from m5.internal.params import EthAddr 8484762Snate@binkert.org return EthAddr(self.value) 8494762Snate@binkert.org 8504380Sbinkertn@umich.edu def ini_str(self): 8514380Sbinkertn@umich.edu return self.value 8523101Sstever@eecs.umich.edu 8537777Sgblack@eecs.umich.edu# When initializing an IpAddress, pass in an existing IpAddress, a string of 8547777Sgblack@eecs.umich.edu# the form "a.b.c.d", or an integer representing an IP. 8557777Sgblack@eecs.umich.educlass IpAddress(ParamValue): 8567777Sgblack@eecs.umich.edu cxx_type = 'Net::IpAddress' 85710267SGeoffrey.Blake@arm.com ex_str = "127.0.0.1" 85810267SGeoffrey.Blake@arm.com cmd_line_settable = True 8597777Sgblack@eecs.umich.edu 8607777Sgblack@eecs.umich.edu @classmethod 8617777Sgblack@eecs.umich.edu def cxx_predecls(cls, code): 8627777Sgblack@eecs.umich.edu code('#include "base/inet.hh"') 8637777Sgblack@eecs.umich.edu 8647777Sgblack@eecs.umich.edu @classmethod 8657777Sgblack@eecs.umich.edu def swig_predecls(cls, code): 8667777Sgblack@eecs.umich.edu code('%include "python/swig/inet.i"') 8677777Sgblack@eecs.umich.edu 8687777Sgblack@eecs.umich.edu def __init__(self, value): 8697777Sgblack@eecs.umich.edu if isinstance(value, IpAddress): 8707777Sgblack@eecs.umich.edu self.ip = value.ip 8717777Sgblack@eecs.umich.edu else: 8727777Sgblack@eecs.umich.edu try: 8737777Sgblack@eecs.umich.edu self.ip = convert.toIpAddress(value) 8747777Sgblack@eecs.umich.edu except TypeError: 8757777Sgblack@eecs.umich.edu self.ip = long(value) 8767777Sgblack@eecs.umich.edu self.verifyIp() 8777777Sgblack@eecs.umich.edu 87810267SGeoffrey.Blake@arm.com def __call__(self, value): 87910267SGeoffrey.Blake@arm.com self.__init__(value) 88010267SGeoffrey.Blake@arm.com return value 88110267SGeoffrey.Blake@arm.com 8828579Ssteve.reinhardt@amd.com def __str__(self): 8838579Ssteve.reinhardt@amd.com tup = [(self.ip >> i) & 0xff for i in (24, 16, 8, 0)] 8848579Ssteve.reinhardt@amd.com return '%d.%d.%d.%d' % tuple(tup) 8858579Ssteve.reinhardt@amd.com 8868579Ssteve.reinhardt@amd.com def __eq__(self, other): 8878579Ssteve.reinhardt@amd.com if isinstance(other, IpAddress): 8888579Ssteve.reinhardt@amd.com return self.ip == other.ip 8898579Ssteve.reinhardt@amd.com elif isinstance(other, str): 8908579Ssteve.reinhardt@amd.com try: 8918579Ssteve.reinhardt@amd.com return self.ip == convert.toIpAddress(other) 8928579Ssteve.reinhardt@amd.com except: 8938579Ssteve.reinhardt@amd.com return False 8948579Ssteve.reinhardt@amd.com else: 8958579Ssteve.reinhardt@amd.com return self.ip == other 8968579Ssteve.reinhardt@amd.com 8978579Ssteve.reinhardt@amd.com def __ne__(self, other): 8988579Ssteve.reinhardt@amd.com return not (self == other) 8998579Ssteve.reinhardt@amd.com 9007777Sgblack@eecs.umich.edu def verifyIp(self): 9017777Sgblack@eecs.umich.edu if self.ip < 0 or self.ip >= (1 << 32): 9027798Sgblack@eecs.umich.edu raise TypeError, "invalid ip address %#08x" % self.ip 9037777Sgblack@eecs.umich.edu 9047777Sgblack@eecs.umich.edu def getValue(self): 9057777Sgblack@eecs.umich.edu from m5.internal.params import IpAddress 9067777Sgblack@eecs.umich.edu return IpAddress(self.ip) 9077777Sgblack@eecs.umich.edu 9087777Sgblack@eecs.umich.edu# When initializing an IpNetmask, pass in an existing IpNetmask, a string of 9097777Sgblack@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 9107777Sgblack@eecs.umich.edu# positional or keyword arguments. 9117777Sgblack@eecs.umich.educlass IpNetmask(IpAddress): 9127777Sgblack@eecs.umich.edu cxx_type = 'Net::IpNetmask' 91310267SGeoffrey.Blake@arm.com ex_str = "127.0.0.0/24" 91410267SGeoffrey.Blake@arm.com cmd_line_settable = True 9157777Sgblack@eecs.umich.edu 9167777Sgblack@eecs.umich.edu @classmethod 9177777Sgblack@eecs.umich.edu def cxx_predecls(cls, code): 9187777Sgblack@eecs.umich.edu code('#include "base/inet.hh"') 9197777Sgblack@eecs.umich.edu 9207777Sgblack@eecs.umich.edu @classmethod 9217777Sgblack@eecs.umich.edu def swig_predecls(cls, code): 9227777Sgblack@eecs.umich.edu code('%include "python/swig/inet.i"') 9237777Sgblack@eecs.umich.edu 9247777Sgblack@eecs.umich.edu def __init__(self, *args, **kwargs): 9257777Sgblack@eecs.umich.edu def handle_kwarg(self, kwargs, key, elseVal = None): 9267777Sgblack@eecs.umich.edu if key in kwargs: 9277777Sgblack@eecs.umich.edu setattr(self, key, kwargs.pop(key)) 9287777Sgblack@eecs.umich.edu elif elseVal: 9297777Sgblack@eecs.umich.edu setattr(self, key, elseVal) 9307777Sgblack@eecs.umich.edu else: 9317777Sgblack@eecs.umich.edu raise TypeError, "No value set for %s" % key 9327777Sgblack@eecs.umich.edu 9337777Sgblack@eecs.umich.edu if len(args) == 0: 9347777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'ip') 9357777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'netmask') 9367777Sgblack@eecs.umich.edu 9377777Sgblack@eecs.umich.edu elif len(args) == 1: 9387777Sgblack@eecs.umich.edu if kwargs: 9397777Sgblack@eecs.umich.edu if not 'ip' in kwargs and not 'netmask' in kwargs: 9407777Sgblack@eecs.umich.edu raise TypeError, "Invalid arguments" 9417777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'ip', args[0]) 9427777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'netmask', args[0]) 9437777Sgblack@eecs.umich.edu elif isinstance(args[0], IpNetmask): 9447777Sgblack@eecs.umich.edu self.ip = args[0].ip 9457777Sgblack@eecs.umich.edu self.netmask = args[0].netmask 9467777Sgblack@eecs.umich.edu else: 9477777Sgblack@eecs.umich.edu (self.ip, self.netmask) = convert.toIpNetmask(args[0]) 9487777Sgblack@eecs.umich.edu 9497777Sgblack@eecs.umich.edu elif len(args) == 2: 9507777Sgblack@eecs.umich.edu self.ip = args[0] 9517777Sgblack@eecs.umich.edu self.netmask = args[1] 9527777Sgblack@eecs.umich.edu else: 9537777Sgblack@eecs.umich.edu raise TypeError, "Too many arguments specified" 9547777Sgblack@eecs.umich.edu 9557777Sgblack@eecs.umich.edu if kwargs: 9567777Sgblack@eecs.umich.edu raise TypeError, "Too many keywords: %s" % kwargs.keys() 9577777Sgblack@eecs.umich.edu 9587777Sgblack@eecs.umich.edu self.verify() 9597777Sgblack@eecs.umich.edu 96010267SGeoffrey.Blake@arm.com def __call__(self, value): 96110267SGeoffrey.Blake@arm.com self.__init__(value) 96210267SGeoffrey.Blake@arm.com return value 96310267SGeoffrey.Blake@arm.com 9648579Ssteve.reinhardt@amd.com def __str__(self): 9658579Ssteve.reinhardt@amd.com return "%s/%d" % (super(IpNetmask, self).__str__(), self.netmask) 9668579Ssteve.reinhardt@amd.com 9678579Ssteve.reinhardt@amd.com def __eq__(self, other): 9688579Ssteve.reinhardt@amd.com if isinstance(other, IpNetmask): 9698579Ssteve.reinhardt@amd.com return self.ip == other.ip and self.netmask == other.netmask 9708579Ssteve.reinhardt@amd.com elif isinstance(other, str): 9718579Ssteve.reinhardt@amd.com try: 9728579Ssteve.reinhardt@amd.com return (self.ip, self.netmask) == convert.toIpNetmask(other) 9738579Ssteve.reinhardt@amd.com except: 9748579Ssteve.reinhardt@amd.com return False 9758579Ssteve.reinhardt@amd.com else: 9768579Ssteve.reinhardt@amd.com return False 9778579Ssteve.reinhardt@amd.com 9787777Sgblack@eecs.umich.edu def verify(self): 9797777Sgblack@eecs.umich.edu self.verifyIp() 9807777Sgblack@eecs.umich.edu if self.netmask < 0 or self.netmask > 32: 9817777Sgblack@eecs.umich.edu raise TypeError, "invalid netmask %d" % netmask 9827777Sgblack@eecs.umich.edu 9837777Sgblack@eecs.umich.edu def getValue(self): 9847777Sgblack@eecs.umich.edu from m5.internal.params import IpNetmask 9857777Sgblack@eecs.umich.edu return IpNetmask(self.ip, self.netmask) 9867777Sgblack@eecs.umich.edu 9877777Sgblack@eecs.umich.edu# When initializing an IpWithPort, pass in an existing IpWithPort, a string of 9887777Sgblack@eecs.umich.edu# the form "a.b.c.d:p", or an ip and port as positional or keyword arguments. 9897777Sgblack@eecs.umich.educlass IpWithPort(IpAddress): 9907777Sgblack@eecs.umich.edu cxx_type = 'Net::IpWithPort' 99110267SGeoffrey.Blake@arm.com ex_str = "127.0.0.1:80" 99210267SGeoffrey.Blake@arm.com cmd_line_settable = True 9937777Sgblack@eecs.umich.edu 9947777Sgblack@eecs.umich.edu @classmethod 9957777Sgblack@eecs.umich.edu def cxx_predecls(cls, code): 9967777Sgblack@eecs.umich.edu code('#include "base/inet.hh"') 9977777Sgblack@eecs.umich.edu 9987777Sgblack@eecs.umich.edu @classmethod 9997777Sgblack@eecs.umich.edu def swig_predecls(cls, code): 10007777Sgblack@eecs.umich.edu code('%include "python/swig/inet.i"') 10017777Sgblack@eecs.umich.edu 10027777Sgblack@eecs.umich.edu def __init__(self, *args, **kwargs): 10037777Sgblack@eecs.umich.edu def handle_kwarg(self, kwargs, key, elseVal = None): 10047777Sgblack@eecs.umich.edu if key in kwargs: 10057777Sgblack@eecs.umich.edu setattr(self, key, kwargs.pop(key)) 10067777Sgblack@eecs.umich.edu elif elseVal: 10077777Sgblack@eecs.umich.edu setattr(self, key, elseVal) 10087777Sgblack@eecs.umich.edu else: 10097777Sgblack@eecs.umich.edu raise TypeError, "No value set for %s" % key 10107777Sgblack@eecs.umich.edu 10117777Sgblack@eecs.umich.edu if len(args) == 0: 10127777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'ip') 10137777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'port') 10147777Sgblack@eecs.umich.edu 10157777Sgblack@eecs.umich.edu elif len(args) == 1: 10167777Sgblack@eecs.umich.edu if kwargs: 10177777Sgblack@eecs.umich.edu if not 'ip' in kwargs and not 'port' in kwargs: 10187777Sgblack@eecs.umich.edu raise TypeError, "Invalid arguments" 10197777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'ip', args[0]) 10207777Sgblack@eecs.umich.edu handle_kwarg(self, kwargs, 'port', args[0]) 10217777Sgblack@eecs.umich.edu elif isinstance(args[0], IpWithPort): 10227777Sgblack@eecs.umich.edu self.ip = args[0].ip 10237777Sgblack@eecs.umich.edu self.port = args[0].port 10247777Sgblack@eecs.umich.edu else: 10257777Sgblack@eecs.umich.edu (self.ip, self.port) = convert.toIpWithPort(args[0]) 10267777Sgblack@eecs.umich.edu 10277777Sgblack@eecs.umich.edu elif len(args) == 2: 10287777Sgblack@eecs.umich.edu self.ip = args[0] 10297777Sgblack@eecs.umich.edu self.port = args[1] 10307777Sgblack@eecs.umich.edu else: 10317777Sgblack@eecs.umich.edu raise TypeError, "Too many arguments specified" 10327777Sgblack@eecs.umich.edu 10337777Sgblack@eecs.umich.edu if kwargs: 10347777Sgblack@eecs.umich.edu raise TypeError, "Too many keywords: %s" % kwargs.keys() 10357777Sgblack@eecs.umich.edu 10367777Sgblack@eecs.umich.edu self.verify() 10377777Sgblack@eecs.umich.edu 103810267SGeoffrey.Blake@arm.com def __call__(self, value): 103910267SGeoffrey.Blake@arm.com self.__init__(value) 104010267SGeoffrey.Blake@arm.com return value 104110267SGeoffrey.Blake@arm.com 10428579Ssteve.reinhardt@amd.com def __str__(self): 10438579Ssteve.reinhardt@amd.com return "%s:%d" % (super(IpWithPort, self).__str__(), self.port) 10448579Ssteve.reinhardt@amd.com 10458579Ssteve.reinhardt@amd.com def __eq__(self, other): 10468579Ssteve.reinhardt@amd.com if isinstance(other, IpWithPort): 10478579Ssteve.reinhardt@amd.com return self.ip == other.ip and self.port == other.port 10488579Ssteve.reinhardt@amd.com elif isinstance(other, str): 10498579Ssteve.reinhardt@amd.com try: 10508579Ssteve.reinhardt@amd.com return (self.ip, self.port) == convert.toIpWithPort(other) 10518579Ssteve.reinhardt@amd.com except: 10528579Ssteve.reinhardt@amd.com return False 10538579Ssteve.reinhardt@amd.com else: 10548579Ssteve.reinhardt@amd.com return False 10558579Ssteve.reinhardt@amd.com 10567777Sgblack@eecs.umich.edu def verify(self): 10577777Sgblack@eecs.umich.edu self.verifyIp() 10587777Sgblack@eecs.umich.edu if self.port < 0 or self.port > 0xffff: 10597777Sgblack@eecs.umich.edu raise TypeError, "invalid port %d" % self.port 10607777Sgblack@eecs.umich.edu 10617777Sgblack@eecs.umich.edu def getValue(self): 10627777Sgblack@eecs.umich.edu from m5.internal.params import IpWithPort 10637777Sgblack@eecs.umich.edu return IpWithPort(self.ip, self.port) 10647777Sgblack@eecs.umich.edu 10653932Sbinkertn@umich.edutime_formats = [ "%a %b %d %H:%M:%S %Z %Y", 106610380SAndrew.Bardsley@arm.com "%a %b %d %H:%M:%S %Y", 10673932Sbinkertn@umich.edu "%Y/%m/%d %H:%M:%S", 10683932Sbinkertn@umich.edu "%Y/%m/%d %H:%M", 10693932Sbinkertn@umich.edu "%Y/%m/%d", 10703932Sbinkertn@umich.edu "%m/%d/%Y %H:%M:%S", 10713932Sbinkertn@umich.edu "%m/%d/%Y %H:%M", 10723932Sbinkertn@umich.edu "%m/%d/%Y", 10733932Sbinkertn@umich.edu "%m/%d/%y %H:%M:%S", 10743932Sbinkertn@umich.edu "%m/%d/%y %H:%M", 10753932Sbinkertn@umich.edu "%m/%d/%y"] 10763932Sbinkertn@umich.edu 10773932Sbinkertn@umich.edu 10783885Sbinkertn@umich.edudef parse_time(value): 10793932Sbinkertn@umich.edu from time import gmtime, strptime, struct_time, time 10803932Sbinkertn@umich.edu from datetime import datetime, date 10813885Sbinkertn@umich.edu 10823932Sbinkertn@umich.edu if isinstance(value, struct_time): 10833932Sbinkertn@umich.edu return value 10843932Sbinkertn@umich.edu 10853932Sbinkertn@umich.edu if isinstance(value, (int, long)): 10863932Sbinkertn@umich.edu return gmtime(value) 10873932Sbinkertn@umich.edu 10883932Sbinkertn@umich.edu if isinstance(value, (datetime, date)): 10893932Sbinkertn@umich.edu return value.timetuple() 10903932Sbinkertn@umich.edu 10913932Sbinkertn@umich.edu if isinstance(value, str): 10923932Sbinkertn@umich.edu if value in ('Now', 'Today'): 10933932Sbinkertn@umich.edu return time.gmtime(time.time()) 10943932Sbinkertn@umich.edu 10953932Sbinkertn@umich.edu for format in time_formats: 10963932Sbinkertn@umich.edu try: 10973932Sbinkertn@umich.edu return strptime(value, format) 10983932Sbinkertn@umich.edu except ValueError: 10993932Sbinkertn@umich.edu pass 11003885Sbinkertn@umich.edu 11013885Sbinkertn@umich.edu raise ValueError, "Could not parse '%s' as a time" % value 11023885Sbinkertn@umich.edu 11033885Sbinkertn@umich.educlass Time(ParamValue): 11044762Snate@binkert.org cxx_type = 'tm' 11057673Snate@binkert.org 11067673Snate@binkert.org @classmethod 11077673Snate@binkert.org def cxx_predecls(cls, code): 11087673Snate@binkert.org code('#include <time.h>') 11097673Snate@binkert.org 11107673Snate@binkert.org @classmethod 11117673Snate@binkert.org def swig_predecls(cls, code): 11127673Snate@binkert.org code('%include "python/swig/time.i"') 11137673Snate@binkert.org 11143885Sbinkertn@umich.edu def __init__(self, value): 11153932Sbinkertn@umich.edu self.value = parse_time(value) 11163885Sbinkertn@umich.edu 111710267SGeoffrey.Blake@arm.com def __call__(self, value): 111810267SGeoffrey.Blake@arm.com self.__init__(value) 111910267SGeoffrey.Blake@arm.com return value 112010267SGeoffrey.Blake@arm.com 11214762Snate@binkert.org def getValue(self): 11227677Snate@binkert.org from m5.internal.params import tm 11234762Snate@binkert.org 11244762Snate@binkert.org c_time = tm() 11254762Snate@binkert.org py_time = self.value 11264762Snate@binkert.org 11274762Snate@binkert.org # UNIX is years since 1900 11284762Snate@binkert.org c_time.tm_year = py_time.tm_year - 1900; 11294762Snate@binkert.org 11304762Snate@binkert.org # Python starts at 1, UNIX starts at 0 11314762Snate@binkert.org c_time.tm_mon = py_time.tm_mon - 1; 11324762Snate@binkert.org c_time.tm_mday = py_time.tm_mday; 11334762Snate@binkert.org c_time.tm_hour = py_time.tm_hour; 11344762Snate@binkert.org c_time.tm_min = py_time.tm_min; 11354762Snate@binkert.org c_time.tm_sec = py_time.tm_sec; 11364762Snate@binkert.org 11374762Snate@binkert.org # Python has 0 as Monday, UNIX is 0 as sunday 11384762Snate@binkert.org c_time.tm_wday = py_time.tm_wday + 1 11394762Snate@binkert.org if c_time.tm_wday > 6: 11404762Snate@binkert.org c_time.tm_wday -= 7; 11414762Snate@binkert.org 11424762Snate@binkert.org # Python starts at 1, Unix starts at 0 11434762Snate@binkert.org c_time.tm_yday = py_time.tm_yday - 1; 11444762Snate@binkert.org 11454762Snate@binkert.org return c_time 11464762Snate@binkert.org 11473885Sbinkertn@umich.edu def __str__(self): 11484762Snate@binkert.org return time.asctime(self.value) 11493885Sbinkertn@umich.edu 11503885Sbinkertn@umich.edu def ini_str(self): 11513932Sbinkertn@umich.edu return str(self) 11523885Sbinkertn@umich.edu 11538664SAli.Saidi@ARM.com def get_config_as_dict(self): 115410380SAndrew.Bardsley@arm.com assert false 11558664SAli.Saidi@ARM.com return str(self) 11568664SAli.Saidi@ARM.com 11573101Sstever@eecs.umich.edu# Enumerated types are a little more complex. The user specifies the 11583101Sstever@eecs.umich.edu# type as Enum(foo) where foo is either a list or dictionary of 11593101Sstever@eecs.umich.edu# alternatives (typically strings, but not necessarily so). (In the 11603101Sstever@eecs.umich.edu# long run, the integer value of the parameter will be the list index 11613101Sstever@eecs.umich.edu# or the corresponding dictionary value. For now, since we only check 11623101Sstever@eecs.umich.edu# that the alternative is valid and then spit it into a .ini file, 11633101Sstever@eecs.umich.edu# there's not much point in using the dictionary.) 11643101Sstever@eecs.umich.edu 11653101Sstever@eecs.umich.edu# What Enum() must do is generate a new type encapsulating the 11663101Sstever@eecs.umich.edu# provided list/dictionary so that specific values of the parameter 11673101Sstever@eecs.umich.edu# can be instances of that type. We define two hidden internal 11683101Sstever@eecs.umich.edu# classes (_ListEnum and _DictEnum) to serve as base classes, then 11693101Sstever@eecs.umich.edu# derive the new type from the appropriate base class on the fly. 11703101Sstever@eecs.umich.edu 11714762Snate@binkert.orgallEnums = {} 11723101Sstever@eecs.umich.edu# Metaclass for Enum types 11735033Smilesck@eecs.umich.educlass MetaEnum(MetaParamValue): 11744762Snate@binkert.org def __new__(mcls, name, bases, dict): 11754762Snate@binkert.org assert name not in allEnums 11764762Snate@binkert.org 11774762Snate@binkert.org cls = super(MetaEnum, mcls).__new__(mcls, name, bases, dict) 11784762Snate@binkert.org allEnums[name] = cls 11794762Snate@binkert.org return cls 11804762Snate@binkert.org 11813101Sstever@eecs.umich.edu def __init__(cls, name, bases, init_dict): 11823101Sstever@eecs.umich.edu if init_dict.has_key('map'): 11833101Sstever@eecs.umich.edu if not isinstance(cls.map, dict): 11843101Sstever@eecs.umich.edu raise TypeError, "Enum-derived class attribute 'map' " \ 11853101Sstever@eecs.umich.edu "must be of type dict" 11863101Sstever@eecs.umich.edu # build list of value strings from map 11873101Sstever@eecs.umich.edu cls.vals = cls.map.keys() 11883101Sstever@eecs.umich.edu cls.vals.sort() 11893101Sstever@eecs.umich.edu elif init_dict.has_key('vals'): 11903101Sstever@eecs.umich.edu if not isinstance(cls.vals, list): 11913101Sstever@eecs.umich.edu raise TypeError, "Enum-derived class attribute 'vals' " \ 11923101Sstever@eecs.umich.edu "must be of type list" 11933101Sstever@eecs.umich.edu # build string->value map from vals sequence 11943101Sstever@eecs.umich.edu cls.map = {} 11953101Sstever@eecs.umich.edu for idx,val in enumerate(cls.vals): 11963101Sstever@eecs.umich.edu cls.map[val] = idx 11973101Sstever@eecs.umich.edu else: 11983101Sstever@eecs.umich.edu raise TypeError, "Enum-derived class must define "\ 11993101Sstever@eecs.umich.edu "attribute 'map' or 'vals'" 12003101Sstever@eecs.umich.edu 12014762Snate@binkert.org cls.cxx_type = 'Enums::%s' % name 12023101Sstever@eecs.umich.edu 12033101Sstever@eecs.umich.edu super(MetaEnum, cls).__init__(name, bases, init_dict) 12043101Sstever@eecs.umich.edu 12053101Sstever@eecs.umich.edu # Generate C++ class declaration for this enum type. 12063101Sstever@eecs.umich.edu # Note that we wrap the enum in a class/struct to act as a namespace, 12073101Sstever@eecs.umich.edu # so that the enum strings can be brief w/o worrying about collisions. 12087673Snate@binkert.org def cxx_decl(cls, code): 120910201SAndrew.Bardsley@arm.com wrapper_name = cls.wrapper_name 121010201SAndrew.Bardsley@arm.com wrapper = 'struct' if cls.wrapper_is_struct else 'namespace' 121110201SAndrew.Bardsley@arm.com name = cls.__name__ if cls.enum_name is None else cls.enum_name 121210201SAndrew.Bardsley@arm.com idem_macro = '__ENUM__%s__%s__' % (wrapper_name, name) 121310201SAndrew.Bardsley@arm.com 12147673Snate@binkert.org code('''\ 121510201SAndrew.Bardsley@arm.com#ifndef $idem_macro 121610201SAndrew.Bardsley@arm.com#define $idem_macro 12177673Snate@binkert.org 121810201SAndrew.Bardsley@arm.com$wrapper $wrapper_name { 12197673Snate@binkert.org enum $name { 12207673Snate@binkert.org''') 12217673Snate@binkert.org code.indent(2) 12224762Snate@binkert.org for val in cls.vals: 12237673Snate@binkert.org code('$val = ${{cls.map[val]}},') 12248902Sandreas.hansson@arm.com code('Num_$name = ${{len(cls.vals)}}') 12257673Snate@binkert.org code.dedent(2) 122610201SAndrew.Bardsley@arm.com code(' };') 12274762Snate@binkert.org 122810201SAndrew.Bardsley@arm.com if cls.wrapper_is_struct: 122910201SAndrew.Bardsley@arm.com code(' static const char *${name}Strings[Num_${name}];') 123010201SAndrew.Bardsley@arm.com code('};') 123110201SAndrew.Bardsley@arm.com else: 123210201SAndrew.Bardsley@arm.com code('extern const char *${name}Strings[Num_${name}];') 123310201SAndrew.Bardsley@arm.com code('}') 123410201SAndrew.Bardsley@arm.com 123510201SAndrew.Bardsley@arm.com code() 123610201SAndrew.Bardsley@arm.com code('#endif // $idem_macro') 12377673Snate@binkert.org 12387673Snate@binkert.org def cxx_def(cls, code): 123910201SAndrew.Bardsley@arm.com wrapper_name = cls.wrapper_name 124010201SAndrew.Bardsley@arm.com file_name = cls.__name__ 124110201SAndrew.Bardsley@arm.com name = cls.__name__ if cls.enum_name is None else cls.enum_name 124210201SAndrew.Bardsley@arm.com 124310201SAndrew.Bardsley@arm.com code('#include "enums/$file_name.hh"') 124410201SAndrew.Bardsley@arm.com if cls.wrapper_is_struct: 124510201SAndrew.Bardsley@arm.com code('const char *${wrapper_name}::${name}Strings' 124610201SAndrew.Bardsley@arm.com '[Num_${name}] =') 124710201SAndrew.Bardsley@arm.com else: 124810201SAndrew.Bardsley@arm.com code('namespace Enums {') 124910201SAndrew.Bardsley@arm.com code.indent(1) 125010201SAndrew.Bardsley@arm.com code(' const char *${name}Strings[Num_${name}] =') 125110201SAndrew.Bardsley@arm.com 125210201SAndrew.Bardsley@arm.com code('{') 125310201SAndrew.Bardsley@arm.com code.indent(1) 12544762Snate@binkert.org for val in cls.vals: 12557673Snate@binkert.org code('"$val",') 125610201SAndrew.Bardsley@arm.com code.dedent(1) 125710201SAndrew.Bardsley@arm.com code('};') 125810201SAndrew.Bardsley@arm.com 125910201SAndrew.Bardsley@arm.com if not cls.wrapper_is_struct: 126010201SAndrew.Bardsley@arm.com code('} // namespace $wrapper_name') 126110201SAndrew.Bardsley@arm.com code.dedent(1) 12623101Sstever@eecs.umich.edu 12638596Ssteve.reinhardt@amd.com def swig_decl(cls, code): 12648596Ssteve.reinhardt@amd.com name = cls.__name__ 12658596Ssteve.reinhardt@amd.com code('''\ 12668596Ssteve.reinhardt@amd.com%module(package="m5.internal") enum_$name 12678596Ssteve.reinhardt@amd.com 12688596Ssteve.reinhardt@amd.com%{ 12698596Ssteve.reinhardt@amd.com#include "enums/$name.hh" 12708596Ssteve.reinhardt@amd.com%} 12718596Ssteve.reinhardt@amd.com 12728596Ssteve.reinhardt@amd.com%include "enums/$name.hh" 12738596Ssteve.reinhardt@amd.com''') 12748596Ssteve.reinhardt@amd.com 12758596Ssteve.reinhardt@amd.com 12763101Sstever@eecs.umich.edu# Base class for enum types. 12773101Sstever@eecs.umich.educlass Enum(ParamValue): 12783101Sstever@eecs.umich.edu __metaclass__ = MetaEnum 12793101Sstever@eecs.umich.edu vals = [] 128010267SGeoffrey.Blake@arm.com cmd_line_settable = True 12813101Sstever@eecs.umich.edu 128210201SAndrew.Bardsley@arm.com # The name of the wrapping namespace or struct 128310201SAndrew.Bardsley@arm.com wrapper_name = 'Enums' 128410201SAndrew.Bardsley@arm.com 128510201SAndrew.Bardsley@arm.com # If true, the enum is wrapped in a struct rather than a namespace 128610201SAndrew.Bardsley@arm.com wrapper_is_struct = False 128710201SAndrew.Bardsley@arm.com 128810201SAndrew.Bardsley@arm.com # If not None, use this as the enum name rather than this class name 128910201SAndrew.Bardsley@arm.com enum_name = None 129010201SAndrew.Bardsley@arm.com 12913101Sstever@eecs.umich.edu def __init__(self, value): 12923101Sstever@eecs.umich.edu if value not in self.map: 12933101Sstever@eecs.umich.edu raise TypeError, "Enum param got bad value '%s' (not in %s)" \ 12943101Sstever@eecs.umich.edu % (value, self.vals) 12953101Sstever@eecs.umich.edu self.value = value 12963101Sstever@eecs.umich.edu 129710267SGeoffrey.Blake@arm.com def __call__(self, value): 129810267SGeoffrey.Blake@arm.com self.__init__(value) 129910267SGeoffrey.Blake@arm.com return value 130010267SGeoffrey.Blake@arm.com 13017675Snate@binkert.org @classmethod 13027675Snate@binkert.org def cxx_predecls(cls, code): 13037675Snate@binkert.org code('#include "enums/$0.hh"', cls.__name__) 13047675Snate@binkert.org 13057675Snate@binkert.org @classmethod 13067675Snate@binkert.org def swig_predecls(cls, code): 13077677Snate@binkert.org code('%import "python/m5/internal/enum_$0.i"', cls.__name__) 13087675Snate@binkert.org 13094762Snate@binkert.org def getValue(self): 13104762Snate@binkert.org return int(self.map[self.value]) 13114762Snate@binkert.org 13123101Sstever@eecs.umich.edu def __str__(self): 13133101Sstever@eecs.umich.edu return self.value 13143101Sstever@eecs.umich.edu 13153101Sstever@eecs.umich.edu# how big does a rounding error need to be before we warn about it? 13163101Sstever@eecs.umich.edufrequency_tolerance = 0.001 # 0.1% 13173101Sstever@eecs.umich.edu 13184167Sbinkertn@umich.educlass TickParamValue(NumericParamValue): 13193101Sstever@eecs.umich.edu cxx_type = 'Tick' 132010267SGeoffrey.Blake@arm.com ex_str = "1MHz" 132110267SGeoffrey.Blake@arm.com cmd_line_settable = True 13227673Snate@binkert.org 13237673Snate@binkert.org @classmethod 13247673Snate@binkert.org def cxx_predecls(cls, code): 13257673Snate@binkert.org code('#include "base/types.hh"') 13267673Snate@binkert.org 13277673Snate@binkert.org @classmethod 13287673Snate@binkert.org def swig_predecls(cls, code): 13297673Snate@binkert.org code('%import "stdint.i"') 13307673Snate@binkert.org code('%import "base/types.hh"') 13314167Sbinkertn@umich.edu 133210267SGeoffrey.Blake@arm.com def __call__(self, value): 133310267SGeoffrey.Blake@arm.com self.__init__(value) 133410267SGeoffrey.Blake@arm.com return value 133510267SGeoffrey.Blake@arm.com 13364762Snate@binkert.org def getValue(self): 13374762Snate@binkert.org return long(self.value) 13384762Snate@binkert.org 13394167Sbinkertn@umich.educlass Latency(TickParamValue): 134010267SGeoffrey.Blake@arm.com ex_str = "100ns" 134110267SGeoffrey.Blake@arm.com 13423101Sstever@eecs.umich.edu def __init__(self, value): 13434167Sbinkertn@umich.edu if isinstance(value, (Latency, Clock)): 13444167Sbinkertn@umich.edu self.ticks = value.ticks 13454167Sbinkertn@umich.edu self.value = value.value 13464167Sbinkertn@umich.edu elif isinstance(value, Frequency): 13474167Sbinkertn@umich.edu self.ticks = value.ticks 13484167Sbinkertn@umich.edu self.value = 1.0 / value.value 13494167Sbinkertn@umich.edu elif value.endswith('t'): 13504167Sbinkertn@umich.edu self.ticks = True 13514167Sbinkertn@umich.edu self.value = int(value[:-1]) 13524167Sbinkertn@umich.edu else: 13534167Sbinkertn@umich.edu self.ticks = False 13544167Sbinkertn@umich.edu self.value = convert.toLatency(value) 13553101Sstever@eecs.umich.edu 135610267SGeoffrey.Blake@arm.com def __call__(self, value): 135710267SGeoffrey.Blake@arm.com self.__init__(value) 135810267SGeoffrey.Blake@arm.com return value 135910267SGeoffrey.Blake@arm.com 13603101Sstever@eecs.umich.edu def __getattr__(self, attr): 13613101Sstever@eecs.umich.edu if attr in ('latency', 'period'): 13623101Sstever@eecs.umich.edu return self 13633101Sstever@eecs.umich.edu if attr == 'frequency': 13643101Sstever@eecs.umich.edu return Frequency(self) 13653101Sstever@eecs.umich.edu raise AttributeError, "Latency object has no attribute '%s'" % attr 13663101Sstever@eecs.umich.edu 13674762Snate@binkert.org def getValue(self): 13684762Snate@binkert.org if self.ticks or self.value == 0: 13694762Snate@binkert.org value = self.value 13704762Snate@binkert.org else: 13714762Snate@binkert.org value = ticks.fromSeconds(self.value) 13724762Snate@binkert.org return long(value) 13734762Snate@binkert.org 137410380SAndrew.Bardsley@arm.com def config_value(self): 137510380SAndrew.Bardsley@arm.com return self.getValue() 137610380SAndrew.Bardsley@arm.com 13773101Sstever@eecs.umich.edu # convert latency to ticks 13783101Sstever@eecs.umich.edu def ini_str(self): 13794762Snate@binkert.org return '%d' % self.getValue() 13803101Sstever@eecs.umich.edu 13814167Sbinkertn@umich.educlass Frequency(TickParamValue): 138210267SGeoffrey.Blake@arm.com ex_str = "1GHz" 138310267SGeoffrey.Blake@arm.com 13843101Sstever@eecs.umich.edu def __init__(self, value): 13854167Sbinkertn@umich.edu if isinstance(value, (Latency, Clock)): 13864167Sbinkertn@umich.edu if value.value == 0: 13874167Sbinkertn@umich.edu self.value = 0 13884167Sbinkertn@umich.edu else: 13894167Sbinkertn@umich.edu self.value = 1.0 / value.value 13904167Sbinkertn@umich.edu self.ticks = value.ticks 13914167Sbinkertn@umich.edu elif isinstance(value, Frequency): 13924167Sbinkertn@umich.edu self.value = value.value 13934167Sbinkertn@umich.edu self.ticks = value.ticks 13944167Sbinkertn@umich.edu else: 13954167Sbinkertn@umich.edu self.ticks = False 13964167Sbinkertn@umich.edu self.value = convert.toFrequency(value) 13973101Sstever@eecs.umich.edu 139810267SGeoffrey.Blake@arm.com def __call__(self, value): 139910267SGeoffrey.Blake@arm.com self.__init__(value) 140010267SGeoffrey.Blake@arm.com return value 140110267SGeoffrey.Blake@arm.com 14023101Sstever@eecs.umich.edu def __getattr__(self, attr): 14033101Sstever@eecs.umich.edu if attr == 'frequency': 14043101Sstever@eecs.umich.edu return self 14053101Sstever@eecs.umich.edu if attr in ('latency', 'period'): 14063101Sstever@eecs.umich.edu return Latency(self) 14073101Sstever@eecs.umich.edu raise AttributeError, "Frequency object has no attribute '%s'" % attr 14083101Sstever@eecs.umich.edu 14094167Sbinkertn@umich.edu # convert latency to ticks 14104762Snate@binkert.org def getValue(self): 14114762Snate@binkert.org if self.ticks or self.value == 0: 14124762Snate@binkert.org value = self.value 14134762Snate@binkert.org else: 14144762Snate@binkert.org value = ticks.fromSeconds(1.0 / self.value) 14154762Snate@binkert.org return long(value) 14164762Snate@binkert.org 141710380SAndrew.Bardsley@arm.com def config_value(self): 141810380SAndrew.Bardsley@arm.com return self.getValue() 141910380SAndrew.Bardsley@arm.com 14203101Sstever@eecs.umich.edu def ini_str(self): 14214762Snate@binkert.org return '%d' % self.getValue() 14223101Sstever@eecs.umich.edu 142310019Sandreas.hansson@arm.com# A generic Frequency and/or Latency value. Value is stored as a 142410019Sandreas.hansson@arm.com# latency, just like Latency and Frequency. 142510019Sandreas.hansson@arm.comclass Clock(TickParamValue): 14263101Sstever@eecs.umich.edu def __init__(self, value): 14274167Sbinkertn@umich.edu if isinstance(value, (Latency, Clock)): 14284167Sbinkertn@umich.edu self.ticks = value.ticks 14294167Sbinkertn@umich.edu self.value = value.value 14304167Sbinkertn@umich.edu elif isinstance(value, Frequency): 14314167Sbinkertn@umich.edu self.ticks = value.ticks 14324167Sbinkertn@umich.edu self.value = 1.0 / value.value 14334167Sbinkertn@umich.edu elif value.endswith('t'): 14344167Sbinkertn@umich.edu self.ticks = True 14354167Sbinkertn@umich.edu self.value = int(value[:-1]) 14364167Sbinkertn@umich.edu else: 14374167Sbinkertn@umich.edu self.ticks = False 14384167Sbinkertn@umich.edu self.value = convert.anyToLatency(value) 14393101Sstever@eecs.umich.edu 144010267SGeoffrey.Blake@arm.com def __call__(self, value): 144110267SGeoffrey.Blake@arm.com self.__init__(value) 144210267SGeoffrey.Blake@arm.com return value 144310267SGeoffrey.Blake@arm.com 144410267SGeoffrey.Blake@arm.com def __str__(self): 144510267SGeoffrey.Blake@arm.com return "%s" % Latency(self) 144610267SGeoffrey.Blake@arm.com 14473101Sstever@eecs.umich.edu def __getattr__(self, attr): 14483101Sstever@eecs.umich.edu if attr == 'frequency': 14493101Sstever@eecs.umich.edu return Frequency(self) 14503101Sstever@eecs.umich.edu if attr in ('latency', 'period'): 14513101Sstever@eecs.umich.edu return Latency(self) 14523101Sstever@eecs.umich.edu raise AttributeError, "Frequency object has no attribute '%s'" % attr 14533101Sstever@eecs.umich.edu 14544762Snate@binkert.org def getValue(self): 14554762Snate@binkert.org return self.period.getValue() 14564762Snate@binkert.org 145710380SAndrew.Bardsley@arm.com def config_value(self): 145810380SAndrew.Bardsley@arm.com return self.period.config_value() 145910380SAndrew.Bardsley@arm.com 14603101Sstever@eecs.umich.edu def ini_str(self): 14613101Sstever@eecs.umich.edu return self.period.ini_str() 14623101Sstever@eecs.umich.edu 14639827Sakash.bagdia@arm.comclass Voltage(float,ParamValue): 14649827Sakash.bagdia@arm.com cxx_type = 'double' 146510267SGeoffrey.Blake@arm.com ex_str = "1V" 146610267SGeoffrey.Blake@arm.com cmd_line_settable = False 146710267SGeoffrey.Blake@arm.com 14689827Sakash.bagdia@arm.com def __new__(cls, value): 14699827Sakash.bagdia@arm.com # convert to voltage 14709827Sakash.bagdia@arm.com val = convert.toVoltage(value) 14719827Sakash.bagdia@arm.com return super(cls, Voltage).__new__(cls, val) 14729827Sakash.bagdia@arm.com 147310267SGeoffrey.Blake@arm.com def __call__(self, value): 147410267SGeoffrey.Blake@arm.com val = convert.toVoltage(value) 147510267SGeoffrey.Blake@arm.com self.__init__(val) 147610267SGeoffrey.Blake@arm.com return value 147710267SGeoffrey.Blake@arm.com 14789827Sakash.bagdia@arm.com def __str__(self): 147910267SGeoffrey.Blake@arm.com return str(self.getValue()) 14809827Sakash.bagdia@arm.com 14819827Sakash.bagdia@arm.com def getValue(self): 14829827Sakash.bagdia@arm.com value = float(self) 14839827Sakash.bagdia@arm.com return value 14849827Sakash.bagdia@arm.com 14859827Sakash.bagdia@arm.com def ini_str(self): 14869827Sakash.bagdia@arm.com return '%f' % self.getValue() 14879827Sakash.bagdia@arm.com 148810427Sandreas.hansson@arm.comclass Current(float, ParamValue): 148910427Sandreas.hansson@arm.com cxx_type = 'double' 149010427Sandreas.hansson@arm.com ex_str = "1mA" 149110427Sandreas.hansson@arm.com cmd_line_settable = False 149210427Sandreas.hansson@arm.com 149310427Sandreas.hansson@arm.com def __new__(cls, value): 149410427Sandreas.hansson@arm.com # convert to current 149510427Sandreas.hansson@arm.com val = convert.toCurrent(value) 149610427Sandreas.hansson@arm.com return super(cls, Current).__new__(cls, val) 149710427Sandreas.hansson@arm.com 149810427Sandreas.hansson@arm.com def __call__(self, value): 149910427Sandreas.hansson@arm.com val = convert.toCurrent(value) 150010427Sandreas.hansson@arm.com self.__init__(val) 150110427Sandreas.hansson@arm.com return value 150210427Sandreas.hansson@arm.com 150310427Sandreas.hansson@arm.com def __str__(self): 150410427Sandreas.hansson@arm.com return str(self.getValue()) 150510427Sandreas.hansson@arm.com 150610427Sandreas.hansson@arm.com def getValue(self): 150710427Sandreas.hansson@arm.com value = float(self) 150810427Sandreas.hansson@arm.com return value 150910427Sandreas.hansson@arm.com 151010427Sandreas.hansson@arm.com def ini_str(self): 151110427Sandreas.hansson@arm.com return '%f' % self.getValue() 151210427Sandreas.hansson@arm.com 15133101Sstever@eecs.umich.educlass NetworkBandwidth(float,ParamValue): 15143101Sstever@eecs.umich.edu cxx_type = 'float' 151510267SGeoffrey.Blake@arm.com ex_str = "1Gbps" 151610267SGeoffrey.Blake@arm.com cmd_line_settable = True 151710267SGeoffrey.Blake@arm.com 15183101Sstever@eecs.umich.edu def __new__(cls, value): 15194167Sbinkertn@umich.edu # convert to bits per second 15204167Sbinkertn@umich.edu val = convert.toNetworkBandwidth(value) 15213101Sstever@eecs.umich.edu return super(cls, NetworkBandwidth).__new__(cls, val) 15223101Sstever@eecs.umich.edu 15233101Sstever@eecs.umich.edu def __str__(self): 15243101Sstever@eecs.umich.edu return str(self.val) 15253101Sstever@eecs.umich.edu 152610267SGeoffrey.Blake@arm.com def __call__(self, value): 152710267SGeoffrey.Blake@arm.com val = convert.toNetworkBandwidth(value) 152810267SGeoffrey.Blake@arm.com self.__init__(val) 152910267SGeoffrey.Blake@arm.com return value 153010267SGeoffrey.Blake@arm.com 15314762Snate@binkert.org def getValue(self): 15324167Sbinkertn@umich.edu # convert to seconds per byte 15334167Sbinkertn@umich.edu value = 8.0 / float(self) 15344167Sbinkertn@umich.edu # convert to ticks per byte 15354762Snate@binkert.org value = ticks.fromSeconds(value) 15364762Snate@binkert.org return float(value) 15374762Snate@binkert.org 15384762Snate@binkert.org def ini_str(self): 15394762Snate@binkert.org return '%f' % self.getValue() 15403101Sstever@eecs.umich.edu 154110380SAndrew.Bardsley@arm.com def config_value(self): 154210380SAndrew.Bardsley@arm.com return '%f' % self.getValue() 154310380SAndrew.Bardsley@arm.com 15443101Sstever@eecs.umich.educlass MemoryBandwidth(float,ParamValue): 15453101Sstever@eecs.umich.edu cxx_type = 'float' 154610267SGeoffrey.Blake@arm.com ex_str = "1GB/s" 154710267SGeoffrey.Blake@arm.com cmd_line_settable = True 154810267SGeoffrey.Blake@arm.com 15495469Snate@binkert.org def __new__(cls, value): 15507743Sgblack@eecs.umich.edu # convert to bytes per second 15513102Sstever@eecs.umich.edu val = convert.toMemoryBandwidth(value) 15523101Sstever@eecs.umich.edu return super(cls, MemoryBandwidth).__new__(cls, val) 15533101Sstever@eecs.umich.edu 155410267SGeoffrey.Blake@arm.com def __call__(self, value): 155510267SGeoffrey.Blake@arm.com val = convert.toMemoryBandwidth(value) 155610267SGeoffrey.Blake@arm.com self.__init__(val) 155710267SGeoffrey.Blake@arm.com return value 15583101Sstever@eecs.umich.edu 15594762Snate@binkert.org def getValue(self): 15604167Sbinkertn@umich.edu # convert to seconds per byte 15615468Snate@binkert.org value = float(self) 15625468Snate@binkert.org if value: 15635468Snate@binkert.org value = 1.0 / float(self) 15644167Sbinkertn@umich.edu # convert to ticks per byte 15654762Snate@binkert.org value = ticks.fromSeconds(value) 15664762Snate@binkert.org return float(value) 15674762Snate@binkert.org 15684762Snate@binkert.org def ini_str(self): 15694762Snate@binkert.org return '%f' % self.getValue() 15703101Sstever@eecs.umich.edu 157110380SAndrew.Bardsley@arm.com def config_value(self): 157210380SAndrew.Bardsley@arm.com return '%f' % self.getValue() 157310380SAndrew.Bardsley@arm.com 15743101Sstever@eecs.umich.edu# 15753101Sstever@eecs.umich.edu# "Constants"... handy aliases for various values. 15763101Sstever@eecs.umich.edu# 15773101Sstever@eecs.umich.edu 15783102Sstever@eecs.umich.edu# Special class for NULL pointers. Note the special check in 15793102Sstever@eecs.umich.edu# make_param_value() above that lets these be assigned where a 15803102Sstever@eecs.umich.edu# SimObject is required. 15813102Sstever@eecs.umich.edu# only one copy of a particular node 15823102Sstever@eecs.umich.educlass NullSimObject(object): 15833102Sstever@eecs.umich.edu __metaclass__ = Singleton 15843102Sstever@eecs.umich.edu 15853102Sstever@eecs.umich.edu def __call__(cls): 15863102Sstever@eecs.umich.edu return cls 15873102Sstever@eecs.umich.edu 15883102Sstever@eecs.umich.edu def _instantiate(self, parent = None, path = ''): 15893102Sstever@eecs.umich.edu pass 15903102Sstever@eecs.umich.edu 15913102Sstever@eecs.umich.edu def ini_str(self): 15923102Sstever@eecs.umich.edu return 'Null' 15933102Sstever@eecs.umich.edu 15943102Sstever@eecs.umich.edu def unproxy(self, base): 15953102Sstever@eecs.umich.edu return self 15963102Sstever@eecs.umich.edu 15973102Sstever@eecs.umich.edu def set_path(self, parent, name): 15983102Sstever@eecs.umich.edu pass 15994762Snate@binkert.org 16003102Sstever@eecs.umich.edu def __str__(self): 16013102Sstever@eecs.umich.edu return 'Null' 16023102Sstever@eecs.umich.edu 160310380SAndrew.Bardsley@arm.com def config_value(self): 160410380SAndrew.Bardsley@arm.com return None 160510380SAndrew.Bardsley@arm.com 16064762Snate@binkert.org def getValue(self): 16074762Snate@binkert.org return None 16084762Snate@binkert.org 16093102Sstever@eecs.umich.edu# The only instance you'll ever need... 16103102Sstever@eecs.umich.eduNULL = NullSimObject() 16113102Sstever@eecs.umich.edu 16123102Sstever@eecs.umich.edudef isNullPointer(value): 16133102Sstever@eecs.umich.edu return isinstance(value, NullSimObject) 16143102Sstever@eecs.umich.edu 16153101Sstever@eecs.umich.edu# Some memory range specifications use this as a default upper bound. 16163101Sstever@eecs.umich.eduMaxAddr = Addr.max 16173101Sstever@eecs.umich.eduMaxTick = Tick.max 16183101Sstever@eecs.umich.eduAllMemory = AddrRange(0, MaxAddr) 16193101Sstever@eecs.umich.edu 16203101Sstever@eecs.umich.edu 16213101Sstever@eecs.umich.edu##################################################################### 16223101Sstever@eecs.umich.edu# 16233101Sstever@eecs.umich.edu# Port objects 16243101Sstever@eecs.umich.edu# 16253101Sstever@eecs.umich.edu# Ports are used to interconnect objects in the memory system. 16263101Sstever@eecs.umich.edu# 16273101Sstever@eecs.umich.edu##################################################################### 16283101Sstever@eecs.umich.edu 16293101Sstever@eecs.umich.edu# Port reference: encapsulates a reference to a particular port on a 16303101Sstever@eecs.umich.edu# particular SimObject. 16313101Sstever@eecs.umich.educlass PortRef(object): 16328839Sandreas.hansson@arm.com def __init__(self, simobj, name, role): 16333105Sstever@eecs.umich.edu assert(isSimObject(simobj) or isSimObjectClass(simobj)) 16343101Sstever@eecs.umich.edu self.simobj = simobj 16353101Sstever@eecs.umich.edu self.name = name 16368839Sandreas.hansson@arm.com self.role = role 16373101Sstever@eecs.umich.edu self.peer = None # not associated with another port yet 16383101Sstever@eecs.umich.edu self.ccConnected = False # C++ port connection done? 16393105Sstever@eecs.umich.edu self.index = -1 # always -1 for non-vector ports 16403101Sstever@eecs.umich.edu 16413103Sstever@eecs.umich.edu def __str__(self): 16423105Sstever@eecs.umich.edu return '%s.%s' % (self.simobj, self.name) 16433103Sstever@eecs.umich.edu 16448840Sandreas.hansson@arm.com def __len__(self): 16458840Sandreas.hansson@arm.com # Return the number of connected ports, i.e. 0 is we have no 16468840Sandreas.hansson@arm.com # peer and 1 if we do. 16478840Sandreas.hansson@arm.com return int(self.peer != None) 16488840Sandreas.hansson@arm.com 16493105Sstever@eecs.umich.edu # for config.ini, print peer's name (not ours) 16503105Sstever@eecs.umich.edu def ini_str(self): 16513105Sstever@eecs.umich.edu return str(self.peer) 16523105Sstever@eecs.umich.edu 16539017Sandreas.hansson@arm.com # for config.json 16549017Sandreas.hansson@arm.com def get_config_as_dict(self): 16559017Sandreas.hansson@arm.com return {'role' : self.role, 'peer' : str(self.peer)} 16569017Sandreas.hansson@arm.com 16573105Sstever@eecs.umich.edu def __getattr__(self, attr): 16583105Sstever@eecs.umich.edu if attr == 'peerObj': 16593105Sstever@eecs.umich.edu # shorthand for proxies 16603105Sstever@eecs.umich.edu return self.peer.simobj 16613105Sstever@eecs.umich.edu raise AttributeError, "'%s' object has no attribute '%s'" % \ 16623105Sstever@eecs.umich.edu (self.__class__.__name__, attr) 16633105Sstever@eecs.umich.edu 16643105Sstever@eecs.umich.edu # Full connection is symmetric (both ways). Called via 16653105Sstever@eecs.umich.edu # SimObject.__setattr__ as a result of a port assignment, e.g., 16663109Sstever@eecs.umich.edu # "obj1.portA = obj2.portB", or via VectorPortElementRef.__setitem__, 16673105Sstever@eecs.umich.edu # e.g., "obj1.portA[3] = obj2.portB". 16683105Sstever@eecs.umich.edu def connect(self, other): 16693105Sstever@eecs.umich.edu if isinstance(other, VectorPortRef): 16703105Sstever@eecs.umich.edu # reference to plain VectorPort is implicit append 16713105Sstever@eecs.umich.edu other = other._get_next() 16723105Sstever@eecs.umich.edu if self.peer and not proxy.isproxy(self.peer): 16739014Sandreas.hansson@arm.com fatal("Port %s is already connected to %s, cannot connect %s\n", 16749014Sandreas.hansson@arm.com self, self.peer, other); 16753101Sstever@eecs.umich.edu self.peer = other 16763109Sstever@eecs.umich.edu if proxy.isproxy(other): 16773109Sstever@eecs.umich.edu other.set_param_desc(PortParamDesc()) 16783109Sstever@eecs.umich.edu elif isinstance(other, PortRef): 16793109Sstever@eecs.umich.edu if other.peer is not self: 16803109Sstever@eecs.umich.edu other.connect(self) 16813109Sstever@eecs.umich.edu else: 16823109Sstever@eecs.umich.edu raise TypeError, \ 16833109Sstever@eecs.umich.edu "assigning non-port reference '%s' to port '%s'" \ 16843109Sstever@eecs.umich.edu % (other, self) 16853101Sstever@eecs.umich.edu 168610355SGeoffrey.Blake@arm.com # Allow a master/slave port pair to be spliced between 168710355SGeoffrey.Blake@arm.com # a port and its connected peer. Useful operation for connecting 168810355SGeoffrey.Blake@arm.com # instrumentation structures into a system when it is necessary 168910355SGeoffrey.Blake@arm.com # to connect the instrumentation after the full system has been 169010355SGeoffrey.Blake@arm.com # constructed. 169110355SGeoffrey.Blake@arm.com def splice(self, new_master_peer, new_slave_peer): 169210355SGeoffrey.Blake@arm.com if self.peer and not proxy.isproxy(self.peer): 169310355SGeoffrey.Blake@arm.com if isinstance(new_master_peer, PortRef) and \ 169410355SGeoffrey.Blake@arm.com isinstance(new_slave_peer, PortRef): 169510355SGeoffrey.Blake@arm.com old_peer = self.peer 169610355SGeoffrey.Blake@arm.com if self.role == 'SLAVE': 169710355SGeoffrey.Blake@arm.com self.peer = new_master_peer 169810355SGeoffrey.Blake@arm.com old_peer.peer = new_slave_peer 169910355SGeoffrey.Blake@arm.com new_master_peer.connect(self) 170010355SGeoffrey.Blake@arm.com new_slave_peer.connect(old_peer) 170110355SGeoffrey.Blake@arm.com elif self.role == 'MASTER': 170210355SGeoffrey.Blake@arm.com self.peer = new_slave_peer 170310355SGeoffrey.Blake@arm.com old_peer.peer = new_master_peer 170410355SGeoffrey.Blake@arm.com new_slave_peer.connect(self) 170510355SGeoffrey.Blake@arm.com new_master_peer.connect(old_peer) 170610355SGeoffrey.Blake@arm.com else: 170710355SGeoffrey.Blake@arm.com panic("Port %s has unknown role, "+\ 170810355SGeoffrey.Blake@arm.com "cannot splice in new peers\n", self) 170910355SGeoffrey.Blake@arm.com else: 171010355SGeoffrey.Blake@arm.com raise TypeError, \ 171110355SGeoffrey.Blake@arm.com "Splicing non-port references '%s','%s' to port '%s'"\ 171210355SGeoffrey.Blake@arm.com % (new_peer, peers_new_peer, self) 171310355SGeoffrey.Blake@arm.com else: 171410355SGeoffrey.Blake@arm.com fatal("Port %s not connected, cannot splice in new peers\n", self) 171510355SGeoffrey.Blake@arm.com 17163105Sstever@eecs.umich.edu def clone(self, simobj, memo): 17173105Sstever@eecs.umich.edu if memo.has_key(self): 17183105Sstever@eecs.umich.edu return memo[self] 17193101Sstever@eecs.umich.edu newRef = copy.copy(self) 17203105Sstever@eecs.umich.edu memo[self] = newRef 17213105Sstever@eecs.umich.edu newRef.simobj = simobj 17223101Sstever@eecs.umich.edu assert(isSimObject(newRef.simobj)) 17233105Sstever@eecs.umich.edu if self.peer and not proxy.isproxy(self.peer): 17243179Sstever@eecs.umich.edu peerObj = self.peer.simobj(_memo=memo) 17253105Sstever@eecs.umich.edu newRef.peer = self.peer.clone(peerObj, memo) 17263105Sstever@eecs.umich.edu assert(not isinstance(newRef.peer, VectorPortRef)) 17273101Sstever@eecs.umich.edu return newRef 17283101Sstever@eecs.umich.edu 17293105Sstever@eecs.umich.edu def unproxy(self, simobj): 17303105Sstever@eecs.umich.edu assert(simobj is self.simobj) 17313105Sstever@eecs.umich.edu if proxy.isproxy(self.peer): 17323105Sstever@eecs.umich.edu try: 17333105Sstever@eecs.umich.edu realPeer = self.peer.unproxy(self.simobj) 17343105Sstever@eecs.umich.edu except: 17353105Sstever@eecs.umich.edu print "Error in unproxying port '%s' of %s" % \ 17363105Sstever@eecs.umich.edu (self.name, self.simobj.path()) 17373105Sstever@eecs.umich.edu raise 17383105Sstever@eecs.umich.edu self.connect(realPeer) 17393105Sstever@eecs.umich.edu 17403101Sstever@eecs.umich.edu # Call C++ to create corresponding port connection between C++ objects 17413101Sstever@eecs.umich.edu def ccConnect(self): 17428597Ssteve.reinhardt@amd.com from m5.internal.pyobject import connectPorts 17434762Snate@binkert.org 17448839Sandreas.hansson@arm.com if self.role == 'SLAVE': 17458839Sandreas.hansson@arm.com # do nothing and let the master take care of it 17468839Sandreas.hansson@arm.com return 17478839Sandreas.hansson@arm.com 17483101Sstever@eecs.umich.edu if self.ccConnected: # already done this 17493101Sstever@eecs.umich.edu return 17503101Sstever@eecs.umich.edu peer = self.peer 17515578SSteve.Reinhardt@amd.com if not self.peer: # nothing to connect to 17525578SSteve.Reinhardt@amd.com return 17538839Sandreas.hansson@arm.com 17548839Sandreas.hansson@arm.com # check that we connect a master to a slave 17558839Sandreas.hansson@arm.com if self.role == peer.role: 17568839Sandreas.hansson@arm.com raise TypeError, \ 17578839Sandreas.hansson@arm.com "cannot connect '%s' and '%s' due to identical role '%s'" \ 17588839Sandreas.hansson@arm.com % (peer, self, self.role) 17598839Sandreas.hansson@arm.com 17607526Ssteve.reinhardt@amd.com try: 17618839Sandreas.hansson@arm.com # self is always the master and peer the slave 17627526Ssteve.reinhardt@amd.com connectPorts(self.simobj.getCCObject(), self.name, self.index, 17637526Ssteve.reinhardt@amd.com peer.simobj.getCCObject(), peer.name, peer.index) 17647526Ssteve.reinhardt@amd.com except: 17657526Ssteve.reinhardt@amd.com print "Error connecting port %s.%s to %s.%s" % \ 17667526Ssteve.reinhardt@amd.com (self.simobj.path(), self.name, 17677526Ssteve.reinhardt@amd.com peer.simobj.path(), peer.name) 17687526Ssteve.reinhardt@amd.com raise 17693101Sstever@eecs.umich.edu self.ccConnected = True 17703101Sstever@eecs.umich.edu peer.ccConnected = True 17713101Sstever@eecs.umich.edu 17723105Sstever@eecs.umich.edu# A reference to an individual element of a VectorPort... much like a 17733105Sstever@eecs.umich.edu# PortRef, but has an index. 17743105Sstever@eecs.umich.educlass VectorPortElementRef(PortRef): 17758839Sandreas.hansson@arm.com def __init__(self, simobj, name, role, index): 17768839Sandreas.hansson@arm.com PortRef.__init__(self, simobj, name, role) 17773105Sstever@eecs.umich.edu self.index = index 17783105Sstever@eecs.umich.edu 17793105Sstever@eecs.umich.edu def __str__(self): 17803105Sstever@eecs.umich.edu return '%s.%s[%d]' % (self.simobj, self.name, self.index) 17813105Sstever@eecs.umich.edu 17823105Sstever@eecs.umich.edu# A reference to a complete vector-valued port (not just a single element). 17833105Sstever@eecs.umich.edu# Can be indexed to retrieve individual VectorPortElementRef instances. 17843105Sstever@eecs.umich.educlass VectorPortRef(object): 17858839Sandreas.hansson@arm.com def __init__(self, simobj, name, role): 17863105Sstever@eecs.umich.edu assert(isSimObject(simobj) or isSimObjectClass(simobj)) 17873105Sstever@eecs.umich.edu self.simobj = simobj 17883105Sstever@eecs.umich.edu self.name = name 17898839Sandreas.hansson@arm.com self.role = role 17903105Sstever@eecs.umich.edu self.elements = [] 17913105Sstever@eecs.umich.edu 17923109Sstever@eecs.umich.edu def __str__(self): 17933109Sstever@eecs.umich.edu return '%s.%s[:]' % (self.simobj, self.name) 17943109Sstever@eecs.umich.edu 17958840Sandreas.hansson@arm.com def __len__(self): 17968840Sandreas.hansson@arm.com # Return the number of connected peers, corresponding the the 17978840Sandreas.hansson@arm.com # length of the elements. 17988840Sandreas.hansson@arm.com return len(self.elements) 17998840Sandreas.hansson@arm.com 18003105Sstever@eecs.umich.edu # for config.ini, print peer's name (not ours) 18013105Sstever@eecs.umich.edu def ini_str(self): 18023105Sstever@eecs.umich.edu return ' '.join([el.ini_str() for el in self.elements]) 18033105Sstever@eecs.umich.edu 18049017Sandreas.hansson@arm.com # for config.json 18059017Sandreas.hansson@arm.com def get_config_as_dict(self): 18069017Sandreas.hansson@arm.com return {'role' : self.role, 18079017Sandreas.hansson@arm.com 'peer' : [el.ini_str() for el in self.elements]} 18089017Sandreas.hansson@arm.com 18093105Sstever@eecs.umich.edu def __getitem__(self, key): 18103105Sstever@eecs.umich.edu if not isinstance(key, int): 18113105Sstever@eecs.umich.edu raise TypeError, "VectorPort index must be integer" 18123105Sstever@eecs.umich.edu if key >= len(self.elements): 18133105Sstever@eecs.umich.edu # need to extend list 18148839Sandreas.hansson@arm.com ext = [VectorPortElementRef(self.simobj, self.name, self.role, i) 18153105Sstever@eecs.umich.edu for i in range(len(self.elements), key+1)] 18163105Sstever@eecs.umich.edu self.elements.extend(ext) 18173105Sstever@eecs.umich.edu return self.elements[key] 18183105Sstever@eecs.umich.edu 18193105Sstever@eecs.umich.edu def _get_next(self): 18203105Sstever@eecs.umich.edu return self[len(self.elements)] 18213105Sstever@eecs.umich.edu 18223105Sstever@eecs.umich.edu def __setitem__(self, key, value): 18233105Sstever@eecs.umich.edu if not isinstance(key, int): 18243105Sstever@eecs.umich.edu raise TypeError, "VectorPort index must be integer" 18253105Sstever@eecs.umich.edu self[key].connect(value) 18263105Sstever@eecs.umich.edu 18273105Sstever@eecs.umich.edu def connect(self, other): 18283109Sstever@eecs.umich.edu if isinstance(other, (list, tuple)): 18293109Sstever@eecs.umich.edu # Assign list of port refs to vector port. 18303109Sstever@eecs.umich.edu # For now, append them... not sure if that's the right semantics 18313109Sstever@eecs.umich.edu # or if it should replace the current vector. 18323109Sstever@eecs.umich.edu for ref in other: 18333109Sstever@eecs.umich.edu self._get_next().connect(ref) 18343109Sstever@eecs.umich.edu else: 18353109Sstever@eecs.umich.edu # scalar assignment to plain VectorPort is implicit append 18363109Sstever@eecs.umich.edu self._get_next().connect(other) 18373109Sstever@eecs.umich.edu 18383109Sstever@eecs.umich.edu def clone(self, simobj, memo): 18393109Sstever@eecs.umich.edu if memo.has_key(self): 18403109Sstever@eecs.umich.edu return memo[self] 18413109Sstever@eecs.umich.edu newRef = copy.copy(self) 18423109Sstever@eecs.umich.edu memo[self] = newRef 18433109Sstever@eecs.umich.edu newRef.simobj = simobj 18443109Sstever@eecs.umich.edu assert(isSimObject(newRef.simobj)) 18453109Sstever@eecs.umich.edu newRef.elements = [el.clone(simobj, memo) for el in self.elements] 18463109Sstever@eecs.umich.edu return newRef 18473105Sstever@eecs.umich.edu 18483105Sstever@eecs.umich.edu def unproxy(self, simobj): 18493105Sstever@eecs.umich.edu [el.unproxy(simobj) for el in self.elements] 18503105Sstever@eecs.umich.edu 18513105Sstever@eecs.umich.edu def ccConnect(self): 18523105Sstever@eecs.umich.edu [el.ccConnect() for el in self.elements] 18533105Sstever@eecs.umich.edu 18543101Sstever@eecs.umich.edu# Port description object. Like a ParamDesc object, this represents a 18553101Sstever@eecs.umich.edu# logical port in the SimObject class, not a particular port on a 18563101Sstever@eecs.umich.edu# SimObject instance. The latter are represented by PortRef objects. 18573101Sstever@eecs.umich.educlass Port(object): 18583101Sstever@eecs.umich.edu # Generate a PortRef for this port on the given SimObject with the 18593101Sstever@eecs.umich.edu # given name 18603105Sstever@eecs.umich.edu def makeRef(self, simobj): 18618839Sandreas.hansson@arm.com return PortRef(simobj, self.name, self.role) 18623101Sstever@eecs.umich.edu 18633101Sstever@eecs.umich.edu # Connect an instance of this port (on the given SimObject with 18643101Sstever@eecs.umich.edu # the given name) with the port described by the supplied PortRef 18653105Sstever@eecs.umich.edu def connect(self, simobj, ref): 18663105Sstever@eecs.umich.edu self.makeRef(simobj).connect(ref) 18673101Sstever@eecs.umich.edu 18688840Sandreas.hansson@arm.com # No need for any pre-declarations at the moment as we merely rely 18698840Sandreas.hansson@arm.com # on an unsigned int. 18708840Sandreas.hansson@arm.com def cxx_predecls(self, code): 18718840Sandreas.hansson@arm.com pass 18728840Sandreas.hansson@arm.com 18738840Sandreas.hansson@arm.com # Declare an unsigned int with the same name as the port, that 18748840Sandreas.hansson@arm.com # will eventually hold the number of connected ports (and thus the 18758840Sandreas.hansson@arm.com # number of elements for a VectorPort). 18768840Sandreas.hansson@arm.com def cxx_decl(self, code): 18778840Sandreas.hansson@arm.com code('unsigned int port_${{self.name}}_connection_count;') 18788840Sandreas.hansson@arm.com 18798839Sandreas.hansson@arm.comclass MasterPort(Port): 18808839Sandreas.hansson@arm.com # MasterPort("description") 18818839Sandreas.hansson@arm.com def __init__(self, *args): 18828839Sandreas.hansson@arm.com if len(args) == 1: 18838839Sandreas.hansson@arm.com self.desc = args[0] 18848839Sandreas.hansson@arm.com self.role = 'MASTER' 18858839Sandreas.hansson@arm.com else: 18868839Sandreas.hansson@arm.com raise TypeError, 'wrong number of arguments' 18878839Sandreas.hansson@arm.com 18888839Sandreas.hansson@arm.comclass SlavePort(Port): 18898839Sandreas.hansson@arm.com # SlavePort("description") 18908839Sandreas.hansson@arm.com def __init__(self, *args): 18918839Sandreas.hansson@arm.com if len(args) == 1: 18928839Sandreas.hansson@arm.com self.desc = args[0] 18938839Sandreas.hansson@arm.com self.role = 'SLAVE' 18948839Sandreas.hansson@arm.com else: 18958839Sandreas.hansson@arm.com raise TypeError, 'wrong number of arguments' 18968839Sandreas.hansson@arm.com 18973101Sstever@eecs.umich.edu# VectorPort description object. Like Port, but represents a vector 189810405Sandreas.hansson@arm.com# of connections (e.g., as on a XBar). 18993101Sstever@eecs.umich.educlass VectorPort(Port): 19003105Sstever@eecs.umich.edu def __init__(self, *args): 19013101Sstever@eecs.umich.edu self.isVec = True 19023101Sstever@eecs.umich.edu 19033105Sstever@eecs.umich.edu def makeRef(self, simobj): 19048839Sandreas.hansson@arm.com return VectorPortRef(simobj, self.name, self.role) 19058839Sandreas.hansson@arm.com 19068839Sandreas.hansson@arm.comclass VectorMasterPort(VectorPort): 19078839Sandreas.hansson@arm.com # VectorMasterPort("description") 19088839Sandreas.hansson@arm.com def __init__(self, *args): 19098839Sandreas.hansson@arm.com if len(args) == 1: 19108839Sandreas.hansson@arm.com self.desc = args[0] 19118839Sandreas.hansson@arm.com self.role = 'MASTER' 19128839Sandreas.hansson@arm.com VectorPort.__init__(self, *args) 19138839Sandreas.hansson@arm.com else: 19148839Sandreas.hansson@arm.com raise TypeError, 'wrong number of arguments' 19158839Sandreas.hansson@arm.com 19168839Sandreas.hansson@arm.comclass VectorSlavePort(VectorPort): 19178839Sandreas.hansson@arm.com # VectorSlavePort("description") 19188839Sandreas.hansson@arm.com def __init__(self, *args): 19198839Sandreas.hansson@arm.com if len(args) == 1: 19208839Sandreas.hansson@arm.com self.desc = args[0] 19218839Sandreas.hansson@arm.com self.role = 'SLAVE' 19228839Sandreas.hansson@arm.com VectorPort.__init__(self, *args) 19238839Sandreas.hansson@arm.com else: 19248839Sandreas.hansson@arm.com raise TypeError, 'wrong number of arguments' 19253105Sstever@eecs.umich.edu 19263109Sstever@eecs.umich.edu# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of 19273109Sstever@eecs.umich.edu# proxy objects (via set_param_desc()) so that proxy error messages 19283109Sstever@eecs.umich.edu# make sense. 19293109Sstever@eecs.umich.educlass PortParamDesc(object): 19303109Sstever@eecs.umich.edu __metaclass__ = Singleton 19313109Sstever@eecs.umich.edu 19323109Sstever@eecs.umich.edu ptype_str = 'Port' 19333109Sstever@eecs.umich.edu ptype = Port 19343105Sstever@eecs.umich.edu 19356654Snate@binkert.orgbaseEnums = allEnums.copy() 19366654Snate@binkert.orgbaseParams = allParams.copy() 19376654Snate@binkert.org 19386654Snate@binkert.orgdef clear(): 19396654Snate@binkert.org global allEnums, allParams 19406654Snate@binkert.org 19416654Snate@binkert.org allEnums = baseEnums.copy() 19426654Snate@binkert.org allParams = baseParams.copy() 19436654Snate@binkert.org 19443101Sstever@eecs.umich.edu__all__ = ['Param', 'VectorParam', 19453101Sstever@eecs.umich.edu 'Enum', 'Bool', 'String', 'Float', 19463101Sstever@eecs.umich.edu 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 19473101Sstever@eecs.umich.edu 'Int32', 'UInt32', 'Int64', 'UInt64', 19483101Sstever@eecs.umich.edu 'Counter', 'Addr', 'Tick', 'Percent', 19493101Sstever@eecs.umich.edu 'TcpPort', 'UdpPort', 'EthernetAddr', 19507777Sgblack@eecs.umich.edu 'IpAddress', 'IpNetmask', 'IpWithPort', 19513101Sstever@eecs.umich.edu 'MemorySize', 'MemorySize32', 19529827Sakash.bagdia@arm.com 'Latency', 'Frequency', 'Clock', 'Voltage', 19533101Sstever@eecs.umich.edu 'NetworkBandwidth', 'MemoryBandwidth', 19549232Sandreas.hansson@arm.com 'AddrRange', 19553101Sstever@eecs.umich.edu 'MaxAddr', 'MaxTick', 'AllMemory', 19563885Sbinkertn@umich.edu 'Time', 19573102Sstever@eecs.umich.edu 'NextEthernetAddr', 'NULL', 19588839Sandreas.hansson@arm.com 'MasterPort', 'SlavePort', 19598839Sandreas.hansson@arm.com 'VectorMasterPort', 'VectorSlavePort'] 19606654Snate@binkert.org 19616654Snate@binkert.orgimport SimObject 1962