1# Copyright (c) 2012-2013 ARM Limited 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license --- 79 unchanged lines hidden (view full) --- 88 allParams[name] = cls 89 return cls 90 91 92# Dummy base class to identify types that are legitimate for SimObject 93# parameters. 94class ParamValue(object): 95 __metaclass__ = MetaParamValue |
96 cmd_line_settable = False |
97 |
98 # Generate the code needed as a prerequisite for declaring a C++ 99 # object of this type. Typically generates one or more #include 100 # statements. Used when declaring parameters of this type. 101 @classmethod 102 def cxx_predecls(cls, code): 103 pass 104 105 # Generate the code needed as a prerequisite for including a --- 8 unchanged lines hidden (view full) --- 114 def ini_str(self): 115 return str(self) 116 117 # allows us to blithely call unproxy() on things without checking 118 # if they're really proxies or not 119 def unproxy(self, base): 120 return self 121 |
122 # Produce a human readable version of the stored value 123 def pretty_print(self, value): 124 return str(value) 125 |
126# Regular parameter description. 127class ParamDesc(object): 128 def __init__(self, ptype_str, ptype, *args, **kwargs): 129 self.ptype_str = ptype_str 130 # remember ptype only if it is provided 131 if ptype != None: 132 self.ptype = ptype 133 --- 27 unchanged lines hidden (view full) --- 161 ptype = SimObject.allClasses[self.ptype_str] 162 assert isSimObjectClass(ptype) 163 self.ptype = ptype 164 return ptype 165 166 raise AttributeError, "'%s' object has no attribute '%s'" % \ 167 (type(self).__name__, attr) 168 |
169 def example_str(self): 170 if hasattr(self.ptype, "ex_str"): 171 return self.ptype.ex_str 172 else: 173 return self.ptype_str 174 175 # Is the param available to be exposed on the command line 176 def isCmdLineSettable(self): 177 if hasattr(self.ptype, "cmd_line_settable"): 178 return self.ptype.cmd_line_settable 179 else: 180 return False 181 |
182 def convert(self, value): 183 if isinstance(value, proxy.BaseProxy): 184 value.set_param_desc(self) 185 return value 186 if not hasattr(self, 'ptype') and isNullPointer(value): 187 # deferred evaluation of SimObject; continue to defer if 188 # we're just assigning a null pointer 189 return value 190 if isinstance(value, self.ptype): 191 return value 192 if isNullPointer(value) and isSimObjectClass(self.ptype): 193 return value 194 return self.ptype(value) 195 |
196 def pretty_print(self, value): 197 if isinstance(value, proxy.BaseProxy): 198 return str(value) 199 if isNullPointer(value): 200 return NULL 201 return self.ptype(value).pretty_print(value) 202 |
203 def cxx_predecls(self, code): 204 code('#include <cstddef>') 205 self.ptype.cxx_predecls(code) 206 207 def swig_predecls(self, code): 208 self.ptype.swig_predecls(code) 209 210 def cxx_decl(self, code): --- 68 unchanged lines hidden (view full) --- 279 def __setitem__(self, key, value): 280 val = self[key] 281 if value.has_parent(): 282 warn("SimObject %s already has a parent" % value.get_name() +\ 283 " that is being overwritten by a SimObjectVector") 284 value.set_parent(val.get_parent(), val._name) 285 super(SimObjectVector, self).__setitem__(key, value) 286 |
287 # Enumerate the params of each member of the SimObject vector. Creates 288 # strings that will allow indexing into the vector by the python code and 289 # allow it to be specified on the command line. 290 def enumerateParams(self, flags_dict = {}, 291 cmd_line_str = "", 292 access_str = ""): 293 if hasattr(self, "_paramEnumed"): 294 print "Cycle detected enumerating params at %s?!" % (cmd_line_str) 295 else: 296 x = 0 297 for vals in self: 298 # Each entry in the SimObjectVector should be an 299 # instance of a SimObject 300 flags_dict = vals.enumerateParams(flags_dict, 301 cmd_line_str + "%d." % x, 302 access_str + "[%d]." % x) 303 x = x + 1 304 305 return flags_dict 306 |
307class VectorParamDesc(ParamDesc): 308 # Convert assigned value to appropriate type. If the RHS is not a 309 # list or tuple, it generates a single-element list. 310 def convert(self, value): 311 if isinstance(value, (list, tuple)): 312 # list: coerce each element into new list 313 tmp_list = [ ParamDesc.convert(self, v) for v in value ] 314 else: 315 # singleton: coerce to a single-element list 316 tmp_list = [ ParamDesc.convert(self, value) ] 317 318 if isSimObjectSequence(tmp_list): 319 return SimObjectVector(tmp_list) 320 else: 321 return VectorParamValue(tmp_list) 322 |
323 # Produce a human readable example string that describes 324 # how to set this vector parameter in the absence of a default 325 # value. 326 def example_str(self): 327 s = super(VectorParamDesc, self).example_str() 328 help_str = "[" + s + "," + s + ", ...]" 329 return help_str 330 331 # Produce a human readable representation of the value of this vector param. 332 def pretty_print(self, value): 333 if isinstance(value, (list, tuple)): 334 tmp_list = [ ParamDesc.pretty_print(self, v) for v in value ] 335 elif isinstance(value, str): 336 tmp_list = [ ParamDesc.pretty_print(self, v) for v in value.split(',') ] 337 else: 338 tmp_list = [ ParamDesc.pretty_print(self, value) ] 339 340 return tmp_list 341 342 # This is a helper function for the new config system 343 def __call__(self, value): 344 if isinstance(value, (list, tuple)): 345 # list: coerce each element into new list 346 tmp_list = [ ParamDesc.convert(self, v) for v in value ] 347 elif isinstance(value, str): 348 # If input is a csv string 349 tmp_list = [ ParamDesc.convert(self, v) for v in value.split(',') ] 350 else: 351 # singleton: coerce to a single-element list 352 tmp_list = [ ParamDesc.convert(self, value) ] 353 354 return VectorParamValue(tmp_list) 355 |
356 def swig_module_name(self): 357 return "%s_vector" % self.ptype_str 358 359 def swig_predecls(self, code): 360 code('%import "${{self.swig_module_name()}}.i"') 361 362 def swig_decl(self, code): 363 code('%module(package="m5.internal") ${{self.swig_module_name()}}') --- 57 unchanged lines hidden (view full) --- 421# the __str__() conversion method). 422# 423##################################################################### 424 425# String-valued parameter. Just mixin the ParamValue class with the 426# built-in str class. 427class String(ParamValue,str): 428 cxx_type = 'std::string' |
429 cmd_line_settable = True |
430 431 @classmethod 432 def cxx_predecls(self, code): 433 code('#include <string>') 434 435 @classmethod 436 def swig_predecls(cls, code): 437 code('%include "std_string.i"') 438 |
439 def __call__(self, value): 440 self = value 441 return value 442 |
443 def getValue(self): 444 return self 445 446# superclass for "numeric" parameter values, to emulate math 447# operations in a type-safe way. e.g., a Latency times an int returns 448# a new Latency object. 449class NumericParamValue(ParamValue): 450 def __str__(self): --- 56 unchanged lines hidden (view full) --- 507 cls.max = (2 ** (cls.size - 1)) - 1 508 509# Abstract superclass for bounds-checked integer parameters. This 510# class is subclassed to generate parameter classes with specific 511# bounds. Initialization of the min and max bounds is done in the 512# metaclass CheckedIntType.__init__. 513class CheckedInt(NumericParamValue): 514 __metaclass__ = CheckedIntType |
515 cmd_line_settable = True |
516 517 def _check(self): 518 if not self.min <= self.value <= self.max: 519 raise TypeError, 'Integer param out of bounds %d < %d < %d' % \ 520 (self.min, self.value, self.max) 521 522 def __init__(self, value): 523 if isinstance(value, str): 524 self.value = convert.toInteger(value) 525 elif isinstance(value, (int, long, float, NumericParamValue)): 526 self.value = long(value) 527 else: 528 raise TypeError, "Can't convert object of type %s to CheckedInt" \ 529 % type(value).__name__ 530 self._check() 531 |
532 def __call__(self, value): 533 self.__init__(value) 534 return value 535 |
536 @classmethod 537 def cxx_predecls(cls, code): 538 # most derived types require this, so we just do it here once 539 code('#include "base/types.hh"') 540 541 @classmethod 542 def swig_predecls(cls, code): 543 # most derived types require this, so we just do it here once --- 28 unchanged lines hidden (view full) --- 572 unsigned = True 573 574 def getValue(self): 575 from m5.internal.core import Cycles 576 return Cycles(self.value) 577 578class Float(ParamValue, float): 579 cxx_type = 'double' |
580 cmdLineSettable = True |
581 582 def __init__(self, value): |
583 if isinstance(value, (int, long, float, NumericParamValue, Float, str)): |
584 self.value = float(value) 585 else: 586 raise TypeError, "Can't convert object of type %s to Float" \ 587 % type(value).__name__ 588 |
589 def __call__(self, value): 590 self.__init__(value) 591 return value 592 |
593 def getValue(self): 594 return float(self.value) 595 596class MemorySize(CheckedInt): 597 cxx_type = 'uint64_t' |
598 ex_str = '512MB' |
599 size = 64 600 unsigned = True 601 def __init__(self, value): 602 if isinstance(value, MemorySize): 603 self.value = value.value 604 else: 605 self.value = convert.toMemorySize(value) 606 self._check() 607 608class MemorySize32(CheckedInt): 609 cxx_type = 'uint32_t' |
610 ex_str = '512MB' |
611 size = 32 612 unsigned = True 613 def __init__(self, value): 614 if isinstance(value, MemorySize): 615 self.value = value.value 616 else: 617 self.value = convert.toMemorySize(value) 618 self._check() --- 11 unchanged lines hidden (view full) --- 630 except TypeError: 631 self.value = long(value) 632 self._check() 633 def __add__(self, other): 634 if isinstance(other, Addr): 635 return self.value + other.value 636 else: 637 return self.value + other |
638 def pretty_print(self, value): 639 try: 640 val = convert.toMemorySize(value) 641 except TypeError: 642 val = long(value) 643 return "0x%x" % long(val) |
644 645class AddrRange(ParamValue): 646 cxx_type = 'AddrRange' 647 648 def __init__(self, *args, **kwargs): 649 # Disable interleaving by default 650 self.intlvHighBit = 0 651 self.intlvBits = 0 --- 67 unchanged lines hidden (view full) --- 719 int(self.intlvHighBit), int(self.intlvBits), 720 int(self.intlvMatch)) 721 722# Boolean parameter type. Python doesn't let you subclass bool, since 723# it doesn't want to let you create multiple instances of True and 724# False. Thus this is a little more complicated than String. 725class Bool(ParamValue): 726 cxx_type = 'bool' |
727 cmd_line_settable = True 728 |
729 def __init__(self, value): 730 try: 731 self.value = convert.toBool(value) 732 except TypeError: 733 self.value = bool(value) 734 |
735 def __call__(self, value): 736 self.__init__(value) 737 return value 738 |
739 def getValue(self): 740 return bool(self.value) 741 742 def __str__(self): 743 return str(self.value) 744 745 # implement truth value testing for Bool parameters so that these params 746 # evaluate correctly during the python configuration phase --- 22 unchanged lines hidden (view full) --- 769 global _NextEthernetAddr 770 771 value = _NextEthernetAddr 772 _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1) 773 return value 774 775class EthernetAddr(ParamValue): 776 cxx_type = 'Net::EthAddr' |
777 ex_str = "00:90:00:00:00:01" 778 cmd_line_settable = True |
779 780 @classmethod 781 def cxx_predecls(cls, code): 782 code('#include "base/inet.hh"') 783 784 @classmethod 785 def swig_predecls(cls, code): 786 code('%include "python/swig/inet.i"') --- 11 unchanged lines hidden (view full) --- 798 raise TypeError, 'invalid ethernet address %s' % value 799 800 for byte in bytes: 801 if not 0 <= int(byte, base=16) <= 0xff: 802 raise TypeError, 'invalid ethernet address %s' % value 803 804 self.value = value 805 |
806 def __call__(self, value): 807 self.__init__(value) 808 return value 809 |
810 def unproxy(self, base): 811 if self.value == NextEthernetAddr: 812 return EthernetAddr(self.value()) 813 return self 814 815 def getValue(self): 816 from m5.internal.params import EthAddr 817 return EthAddr(self.value) 818 819 def ini_str(self): 820 return self.value 821 822# When initializing an IpAddress, pass in an existing IpAddress, a string of 823# the form "a.b.c.d", or an integer representing an IP. 824class IpAddress(ParamValue): 825 cxx_type = 'Net::IpAddress' |
826 ex_str = "127.0.0.1" 827 cmd_line_settable = True |
828 829 @classmethod 830 def cxx_predecls(cls, code): 831 code('#include "base/inet.hh"') 832 833 @classmethod 834 def swig_predecls(cls, code): 835 code('%include "python/swig/inet.i"') 836 837 def __init__(self, value): 838 if isinstance(value, IpAddress): 839 self.ip = value.ip 840 else: 841 try: 842 self.ip = convert.toIpAddress(value) 843 except TypeError: 844 self.ip = long(value) 845 self.verifyIp() 846 |
847 def __call__(self, value): 848 self.__init__(value) 849 return value 850 |
851 def __str__(self): 852 tup = [(self.ip >> i) & 0xff for i in (24, 16, 8, 0)] 853 return '%d.%d.%d.%d' % tuple(tup) 854 855 def __eq__(self, other): 856 if isinstance(other, IpAddress): 857 return self.ip == other.ip 858 elif isinstance(other, str): --- 15 unchanged lines hidden (view full) --- 874 from m5.internal.params import IpAddress 875 return IpAddress(self.ip) 876 877# When initializing an IpNetmask, pass in an existing IpNetmask, a string of 878# the form "a.b.c.d/n" or "a.b.c.d/e.f.g.h", or an ip and netmask as 879# positional or keyword arguments. 880class IpNetmask(IpAddress): 881 cxx_type = 'Net::IpNetmask' |
882 ex_str = "127.0.0.0/24" 883 cmd_line_settable = True |
884 885 @classmethod 886 def cxx_predecls(cls, code): 887 code('#include "base/inet.hh"') 888 889 @classmethod 890 def swig_predecls(cls, code): 891 code('%include "python/swig/inet.i"') --- 29 unchanged lines hidden (view full) --- 921 else: 922 raise TypeError, "Too many arguments specified" 923 924 if kwargs: 925 raise TypeError, "Too many keywords: %s" % kwargs.keys() 926 927 self.verify() 928 |
929 def __call__(self, value): 930 self.__init__(value) 931 return value 932 |
933 def __str__(self): 934 return "%s/%d" % (super(IpNetmask, self).__str__(), self.netmask) 935 936 def __eq__(self, other): 937 if isinstance(other, IpNetmask): 938 return self.ip == other.ip and self.netmask == other.netmask 939 elif isinstance(other, str): 940 try: --- 11 unchanged lines hidden (view full) --- 952 def getValue(self): 953 from m5.internal.params import IpNetmask 954 return IpNetmask(self.ip, self.netmask) 955 956# When initializing an IpWithPort, pass in an existing IpWithPort, a string of 957# the form "a.b.c.d:p", or an ip and port as positional or keyword arguments. 958class IpWithPort(IpAddress): 959 cxx_type = 'Net::IpWithPort' |
960 ex_str = "127.0.0.1:80" 961 cmd_line_settable = True |
962 963 @classmethod 964 def cxx_predecls(cls, code): 965 code('#include "base/inet.hh"') 966 967 @classmethod 968 def swig_predecls(cls, code): 969 code('%include "python/swig/inet.i"') --- 29 unchanged lines hidden (view full) --- 999 else: 1000 raise TypeError, "Too many arguments specified" 1001 1002 if kwargs: 1003 raise TypeError, "Too many keywords: %s" % kwargs.keys() 1004 1005 self.verify() 1006 |
1007 def __call__(self, value): 1008 self.__init__(value) 1009 return value 1010 |
1011 def __str__(self): 1012 return "%s:%d" % (super(IpWithPort, self).__str__(), self.port) 1013 1014 def __eq__(self, other): 1015 if isinstance(other, IpWithPort): 1016 return self.ip == other.ip and self.port == other.port 1017 elif isinstance(other, str): 1018 try: --- 59 unchanged lines hidden (view full) --- 1078 1079 @classmethod 1080 def swig_predecls(cls, code): 1081 code('%include "python/swig/time.i"') 1082 1083 def __init__(self, value): 1084 self.value = parse_time(value) 1085 |
1086 def __call__(self, value): 1087 self.__init__(value) 1088 return value 1089 |
1090 def getValue(self): 1091 from m5.internal.params import tm 1092 1093 c_time = tm() 1094 py_time = self.value 1095 1096 # UNIX is years since 1900 1097 c_time.tm_year = py_time.tm_year - 1900; --- 142 unchanged lines hidden (view full) --- 1240%include "enums/$name.hh" 1241''') 1242 1243 1244# Base class for enum types. 1245class Enum(ParamValue): 1246 __metaclass__ = MetaEnum 1247 vals = [] |
1248 cmd_line_settable = True |
1249 1250 # The name of the wrapping namespace or struct 1251 wrapper_name = 'Enums' 1252 1253 # If true, the enum is wrapped in a struct rather than a namespace 1254 wrapper_is_struct = False 1255 1256 # If not None, use this as the enum name rather than this class name 1257 enum_name = None 1258 1259 def __init__(self, value): 1260 if value not in self.map: 1261 raise TypeError, "Enum param got bad value '%s' (not in %s)" \ 1262 % (value, self.vals) 1263 self.value = value 1264 |
1265 def __call__(self, value): 1266 self.__init__(value) 1267 return value 1268 |
1269 @classmethod 1270 def cxx_predecls(cls, code): 1271 code('#include "enums/$0.hh"', cls.__name__) 1272 1273 @classmethod 1274 def swig_predecls(cls, code): 1275 code('%import "python/m5/internal/enum_$0.i"', cls.__name__) 1276 1277 def getValue(self): 1278 return int(self.map[self.value]) 1279 1280 def __str__(self): 1281 return self.value 1282 1283# how big does a rounding error need to be before we warn about it? 1284frequency_tolerance = 0.001 # 0.1% 1285 1286class TickParamValue(NumericParamValue): 1287 cxx_type = 'Tick' |
1288 ex_str = "1MHz" 1289 cmd_line_settable = True |
1290 1291 @classmethod 1292 def cxx_predecls(cls, code): 1293 code('#include "base/types.hh"') 1294 1295 @classmethod 1296 def swig_predecls(cls, code): 1297 code('%import "stdint.i"') 1298 code('%import "base/types.hh"') 1299 |
1300 def __call__(self, value): 1301 self.__init__(value) 1302 return value 1303 |
1304 def getValue(self): 1305 return long(self.value) 1306 1307class Latency(TickParamValue): |
1308 ex_str = "100ns" 1309 |
1310 def __init__(self, value): 1311 if isinstance(value, (Latency, Clock)): 1312 self.ticks = value.ticks 1313 self.value = value.value 1314 elif isinstance(value, Frequency): 1315 self.ticks = value.ticks 1316 self.value = 1.0 / value.value 1317 elif value.endswith('t'): 1318 self.ticks = True 1319 self.value = int(value[:-1]) 1320 else: 1321 self.ticks = False 1322 self.value = convert.toLatency(value) 1323 |
1324 def __call__(self, value): 1325 self.__init__(value) 1326 return value 1327 |
1328 def __getattr__(self, attr): 1329 if attr in ('latency', 'period'): 1330 return self 1331 if attr == 'frequency': 1332 return Frequency(self) 1333 raise AttributeError, "Latency object has no attribute '%s'" % attr 1334 1335 def getValue(self): 1336 if self.ticks or self.value == 0: 1337 value = self.value 1338 else: 1339 value = ticks.fromSeconds(self.value) 1340 return long(value) 1341 1342 # convert latency to ticks 1343 def ini_str(self): 1344 return '%d' % self.getValue() 1345 1346class Frequency(TickParamValue): |
1347 ex_str = "1GHz" 1348 |
1349 def __init__(self, value): 1350 if isinstance(value, (Latency, Clock)): 1351 if value.value == 0: 1352 self.value = 0 1353 else: 1354 self.value = 1.0 / value.value 1355 self.ticks = value.ticks 1356 elif isinstance(value, Frequency): 1357 self.value = value.value 1358 self.ticks = value.ticks 1359 else: 1360 self.ticks = False 1361 self.value = convert.toFrequency(value) 1362 |
1363 def __call__(self, value): 1364 self.__init__(value) 1365 return value 1366 |
1367 def __getattr__(self, attr): 1368 if attr == 'frequency': 1369 return self 1370 if attr in ('latency', 'period'): 1371 return Latency(self) 1372 raise AttributeError, "Frequency object has no attribute '%s'" % attr 1373 1374 # convert latency to ticks --- 19 unchanged lines hidden (view full) --- 1394 self.value = 1.0 / value.value 1395 elif value.endswith('t'): 1396 self.ticks = True 1397 self.value = int(value[:-1]) 1398 else: 1399 self.ticks = False 1400 self.value = convert.anyToLatency(value) 1401 |
1402 def __call__(self, value): 1403 self.__init__(value) 1404 return value 1405 1406 def __str__(self): 1407 return "%s" % Latency(self) 1408 |
1409 def __getattr__(self, attr): 1410 if attr == 'frequency': 1411 return Frequency(self) 1412 if attr in ('latency', 'period'): 1413 return Latency(self) 1414 raise AttributeError, "Frequency object has no attribute '%s'" % attr 1415 1416 def getValue(self): 1417 return self.period.getValue() 1418 1419 def ini_str(self): 1420 return self.period.ini_str() 1421 1422class Voltage(float,ParamValue): 1423 cxx_type = 'double' |
1424 ex_str = "1V" 1425 cmd_line_settable = False 1426 |
1427 def __new__(cls, value): 1428 # convert to voltage 1429 val = convert.toVoltage(value) 1430 return super(cls, Voltage).__new__(cls, val) 1431 |
1432 def __call__(self, value): 1433 val = convert.toVoltage(value) 1434 self.__init__(val) 1435 return value 1436 |
1437 def __str__(self): |
1438 return str(self.getValue()) |
1439 1440 def getValue(self): 1441 value = float(self) 1442 return value 1443 1444 def ini_str(self): 1445 return '%f' % self.getValue() 1446 1447class NetworkBandwidth(float,ParamValue): 1448 cxx_type = 'float' |
1449 ex_str = "1Gbps" 1450 cmd_line_settable = True 1451 |
1452 def __new__(cls, value): 1453 # convert to bits per second 1454 val = convert.toNetworkBandwidth(value) 1455 return super(cls, NetworkBandwidth).__new__(cls, val) 1456 1457 def __str__(self): 1458 return str(self.val) 1459 |
1460 def __call__(self, value): 1461 val = convert.toNetworkBandwidth(value) 1462 self.__init__(val) 1463 return value 1464 |
1465 def getValue(self): 1466 # convert to seconds per byte 1467 value = 8.0 / float(self) 1468 # convert to ticks per byte 1469 value = ticks.fromSeconds(value) 1470 return float(value) 1471 1472 def ini_str(self): 1473 return '%f' % self.getValue() 1474 1475class MemoryBandwidth(float,ParamValue): 1476 cxx_type = 'float' |
1477 ex_str = "1GB/s" 1478 cmd_line_settable = True 1479 |
1480 def __new__(cls, value): 1481 # convert to bytes per second 1482 val = convert.toMemoryBandwidth(value) 1483 return super(cls, MemoryBandwidth).__new__(cls, val) 1484 |
1485 def __call__(self, value): 1486 val = convert.toMemoryBandwidth(value) 1487 self.__init__(val) 1488 return value |
1489 1490 def getValue(self): 1491 # convert to seconds per byte 1492 value = float(self) 1493 if value: 1494 value = 1.0 / float(self) 1495 # convert to ticks per byte 1496 value = ticks.fromSeconds(value) --- 360 unchanged lines hidden --- |