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
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):
495 if isinstance(value, (int, long, float, NumericParamValue, Float)):
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):
1266 return str(self.val)
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
1302 def __str__(self):
1303 return str(self.val)
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 ---