params.py (7534:c76a14014c27) params.py (7673:b28bd1fa9a35)
1# Copyright (c) 2004-2006 The Regents of The University of Michigan
2# Copyright (c) 2010 Advanced Micro Devices, Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met: redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer;

--- 66 unchanged lines hidden (view full) ---

75 return cls
76
77
78# Dummy base class to identify types that are legitimate for SimObject
79# parameters.
80class ParamValue(object):
81 __metaclass__ = MetaParamValue
82
1# Copyright (c) 2004-2006 The Regents of The University of Michigan
2# Copyright (c) 2010 Advanced Micro Devices, Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met: redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer;

--- 66 unchanged lines hidden (view full) ---

75 return cls
76
77
78# Dummy base class to identify types that are legitimate for SimObject
79# parameters.
80class ParamValue(object):
81 __metaclass__ = MetaParamValue
82
83 cxx_predecls = []
84 swig_predecls = []
83 @classmethod
84 def cxx_predecls(cls, code):
85 pass
85
86
87 @classmethod
88 def swig_predecls(cls, code):
89 pass
90
86 # default for printing to .ini file is regular string conversion.
87 # will be overridden in some cases
88 def ini_str(self):
89 return str(self)
90
91 # allows us to blithely call unproxy() on things without checking
92 # if they're really proxies or not
93 def unproxy(self, base):

--- 53 unchanged lines hidden (view full) ---

147 # we're just assigning a null pointer
148 return value
149 if isinstance(value, self.ptype):
150 return value
151 if isNullPointer(value) and isSimObjectClass(self.ptype):
152 return value
153 return self.ptype(value)
154
91 # default for printing to .ini file is regular string conversion.
92 # will be overridden in some cases
93 def ini_str(self):
94 return str(self)
95
96 # allows us to blithely call unproxy() on things without checking
97 # if they're really proxies or not
98 def unproxy(self, base):

--- 53 unchanged lines hidden (view full) ---

152 # we're just assigning a null pointer
153 return value
154 if isinstance(value, self.ptype):
155 return value
156 if isNullPointer(value) and isSimObjectClass(self.ptype):
157 return value
158 return self.ptype(value)
159
155 def cxx_predecls(self):
156 return self.ptype.cxx_predecls
160 def cxx_predecls(self, code):
161 self.ptype.cxx_predecls(code)
157
162
158 def swig_predecls(self):
159 return self.ptype.swig_predecls
163 def swig_predecls(self, code):
164 self.ptype.swig_predecls(code)
160
165
161 def cxx_decl(self):
162 return '%s %s;' % (self.ptype.cxx_type, self.name)
166 def cxx_decl(self, code):
167 code('${{self.ptype.cxx_type}} ${{self.name}};')
163
164# Vector-valued parameter description. Just like ParamDesc, except
165# that the value is a vector (list) of the specified type instead of a
166# single value.
167
168class VectorParamValue(list):
169 __metaclass__ = MetaParamValue
170 def __setattr__(self, attr, value):

--- 59 unchanged lines hidden (view full) ---

230 # singleton: coerce to a single-element list
231 tmp_list = [ ParamDesc.convert(self, value) ]
232
233 if isSimObjectSequence(tmp_list):
234 return SimObjectVector(tmp_list)
235 else:
236 return VectorParamValue(tmp_list)
237
168
169# Vector-valued parameter description. Just like ParamDesc, except
170# that the value is a vector (list) of the specified type instead of a
171# single value.
172
173class VectorParamValue(list):
174 __metaclass__ = MetaParamValue
175 def __setattr__(self, attr, value):

--- 59 unchanged lines hidden (view full) ---

235 # singleton: coerce to a single-element list
236 tmp_list = [ ParamDesc.convert(self, value) ]
237
238 if isSimObjectSequence(tmp_list):
239 return SimObjectVector(tmp_list)
240 else:
241 return VectorParamValue(tmp_list)
242
238 def swig_predecls(self):
239 return ['%%include "%s_vptype.i"' % self.ptype_str]
243 def swig_predecls(self, code):
244 code('%include "${{self.ptype_str}}_vptype.i"')
240
245
241 def swig_decl(self):
246 def swig_decl(self, code):
242 cxx_type = re.sub('std::', '', self.ptype.cxx_type)
247 cxx_type = re.sub('std::', '', self.ptype.cxx_type)
243 vdecl = 'namespace std { %%template(vector_%s) vector< %s >; }' % \
244 (self.ptype_str, cxx_type)
245 return ['%include "std_vector.i"'] + self.ptype.swig_predecls + [vdecl]
248 code('%include "std_vector.i"')
249 self.ptype.swig_predecls(code)
250 code('''\
251namespace std {
252%template(vector_${{self.ptype_str}}) vector< $cxx_type >;
253}
254''')
246
255
247 def cxx_predecls(self):
248 return ['#include <vector>'] + self.ptype.cxx_predecls
256 def cxx_predecls(self, code):
257 code('#include <vector>')
258 self.ptype.cxx_predecls(code)
249
259
250 def cxx_decl(self):
251 return 'std::vector< %s > %s;' % (self.ptype.cxx_type, self.name)
260 def cxx_decl(self, code):
261 code('std::vector< ${{self.ptype.cxx_type}} > ${{self.name}};')
252
253class ParamFactory(object):
254 def __init__(self, param_desc_class, ptype_str = None):
255 self.param_desc_class = param_desc_class
256 self.ptype_str = ptype_str
257
258 def __getattr__(self, attr):
259 if self.ptype_str:

--- 26 unchanged lines hidden (view full) ---

286# the __str__() conversion method).
287#
288#####################################################################
289
290# String-valued parameter. Just mixin the ParamValue class with the
291# built-in str class.
292class String(ParamValue,str):
293 cxx_type = 'std::string'
262
263class ParamFactory(object):
264 def __init__(self, param_desc_class, ptype_str = None):
265 self.param_desc_class = param_desc_class
266 self.ptype_str = ptype_str
267
268 def __getattr__(self, attr):
269 if self.ptype_str:

--- 26 unchanged lines hidden (view full) ---

296# the __str__() conversion method).
297#
298#####################################################################
299
300# String-valued parameter. Just mixin the ParamValue class with the
301# built-in str class.
302class String(ParamValue,str):
303 cxx_type = 'std::string'
294 cxx_predecls = ['#include <string>']
295 swig_predecls = ['%include "std_string.i"\n' +
296 '%apply const std::string& {std::string *};']
297 swig_predecls = ['%include "std_string.i"' ]
298
304
305 @classmethod
306 def cxx_predecls(self, code):
307 code('#include <string>')
308
309 @classmethod
310 def swig_predecls(cls, code):
311 code('%include "std_string.i"')
312
299 def getValue(self):
300 return self
301
302# superclass for "numeric" parameter values, to emulate math
303# operations in a type-safe way. e.g., a Latency times an int returns
304# a new Latency object.
305class NumericParamValue(ParamValue):
306 def __str__(self):

--- 38 unchanged lines hidden (view full) ---

345 super(CheckedIntType, cls).__init__(name, bases, dict)
346
347 # CheckedInt is an abstract base class, so we actually don't
348 # want to do any processing on it... the rest of this code is
349 # just for classes that derive from CheckedInt.
350 if name == 'CheckedInt':
351 return
352
313 def getValue(self):
314 return self
315
316# superclass for "numeric" parameter values, to emulate math
317# operations in a type-safe way. e.g., a Latency times an int returns
318# a new Latency object.
319class NumericParamValue(ParamValue):
320 def __str__(self):

--- 38 unchanged lines hidden (view full) ---

359 super(CheckedIntType, cls).__init__(name, bases, dict)
360
361 # CheckedInt is an abstract base class, so we actually don't
362 # want to do any processing on it... the rest of this code is
363 # just for classes that derive from CheckedInt.
364 if name == 'CheckedInt':
365 return
366
353 if not cls.cxx_predecls:
354 # most derived types require this, so we just do it here once
355 cls.cxx_predecls = ['#include "base/types.hh"']
356
357 if not cls.swig_predecls:
358 # most derived types require this, so we just do it here once
359 cls.swig_predecls = ['%import "stdint.i"\n' +
360 '%import "base/types.hh"']
361
362 if not (hasattr(cls, 'min') and hasattr(cls, 'max')):
363 if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')):
364 panic("CheckedInt subclass %s must define either\n" \
365 " 'min' and 'max' or 'size' and 'unsigned'\n",
366 name);
367 if cls.unsigned:
368 cls.min = 0
369 cls.max = 2 ** cls.size - 1

--- 18 unchanged lines hidden (view full) ---

388 self.value = convert.toInteger(value)
389 elif isinstance(value, (int, long, float, NumericParamValue)):
390 self.value = long(value)
391 else:
392 raise TypeError, "Can't convert object of type %s to CheckedInt" \
393 % type(value).__name__
394 self._check()
395
367 if not (hasattr(cls, 'min') and hasattr(cls, 'max')):
368 if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')):
369 panic("CheckedInt subclass %s must define either\n" \
370 " 'min' and 'max' or 'size' and 'unsigned'\n",
371 name);
372 if cls.unsigned:
373 cls.min = 0
374 cls.max = 2 ** cls.size - 1

--- 18 unchanged lines hidden (view full) ---

393 self.value = convert.toInteger(value)
394 elif isinstance(value, (int, long, float, NumericParamValue)):
395 self.value = long(value)
396 else:
397 raise TypeError, "Can't convert object of type %s to CheckedInt" \
398 % type(value).__name__
399 self._check()
400
401 @classmethod
402 def cxx_predecls(cls, code):
403 # most derived types require this, so we just do it here once
404 code('#include "base/types.hh"')
405
406 @classmethod
407 def swig_predecls(cls, code):
408 # most derived types require this, so we just do it here once
409 code('%import "stdint.i"')
410 code('%import "base/types.hh"')
411
396 def getValue(self):
397 return long(self.value)
398
399class Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False
400class Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True
401
402class Int8(CheckedInt): cxx_type = 'int8_t'; size = 8; unsigned = False
403class UInt8(CheckedInt): cxx_type = 'uint8_t'; size = 8; unsigned = True

--- 67 unchanged lines hidden (view full) ---

471
472
473class MetaRange(MetaParamValue):
474 def __init__(cls, name, bases, dict):
475 super(MetaRange, cls).__init__(name, bases, dict)
476 if name == 'Range':
477 return
478 cls.cxx_type = 'Range< %s >' % cls.type.cxx_type
412 def getValue(self):
413 return long(self.value)
414
415class Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False
416class Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True
417
418class Int8(CheckedInt): cxx_type = 'int8_t'; size = 8; unsigned = False
419class UInt8(CheckedInt): cxx_type = 'uint8_t'; size = 8; unsigned = True

--- 67 unchanged lines hidden (view full) ---

487
488
489class MetaRange(MetaParamValue):
490 def __init__(cls, name, bases, dict):
491 super(MetaRange, cls).__init__(name, bases, dict)
492 if name == 'Range':
493 return
494 cls.cxx_type = 'Range< %s >' % cls.type.cxx_type
479 cls.cxx_predecls = \
480 ['#include "base/range.hh"'] + cls.type.cxx_predecls
481
482class Range(ParamValue):
483 __metaclass__ = MetaRange
484 type = Int # default; can be overridden in subclasses
485 def __init__(self, *args, **kwargs):
486 def handle_kwargs(self, kwargs):
487 if 'end' in kwargs:
488 self.second = self.type(kwargs.pop('end'))

--- 27 unchanged lines hidden (view full) ---

516 raise TypeError, "Too many arguments specified"
517
518 if kwargs:
519 raise TypeError, "too many keywords: %s" % kwargs.keys()
520
521 def __str__(self):
522 return '%s:%s' % (self.first, self.second)
523
495
496class Range(ParamValue):
497 __metaclass__ = MetaRange
498 type = Int # default; can be overridden in subclasses
499 def __init__(self, *args, **kwargs):
500 def handle_kwargs(self, kwargs):
501 if 'end' in kwargs:
502 self.second = self.type(kwargs.pop('end'))

--- 27 unchanged lines hidden (view full) ---

530 raise TypeError, "Too many arguments specified"
531
532 if kwargs:
533 raise TypeError, "too many keywords: %s" % kwargs.keys()
534
535 def __str__(self):
536 return '%s:%s' % (self.first, self.second)
537
538 @classmethod
539 def cxx_predecls(cls, code):
540 code('#include "base/range.hh"')
541 cls.type.cxx_predecls(code)
542
524class AddrRange(Range):
525 type = Addr
543class AddrRange(Range):
544 type = Addr
526 swig_predecls = ['%include "python/swig/range.i"']
527
545
546 @classmethod
547 def swig_predecls(cls, code):
548 code('%include "python/swig/range.i"')
549
528 def getValue(self):
529 from m5.objects.params import AddrRange
530
531 value = AddrRange()
532 value.start = long(self.first)
533 value.end = long(self.second)
534 return value
535
536class TickRange(Range):
537 type = Tick
550 def getValue(self):
551 from m5.objects.params import AddrRange
552
553 value = AddrRange()
554 value.start = long(self.first)
555 value.end = long(self.second)
556 return value
557
558class TickRange(Range):
559 type = Tick
538 swig_predecls = ['%include "python/swig/range.i"']
539
560
561 @classmethod
562 def swig_predecls(cls, code):
563 code('%include "python/swig/range.i"')
564
540 def getValue(self):
541 from m5.objects.params import TickRange
542
543 value = TickRange()
544 value.start = long(self.first)
545 value.end = long(self.second)
546 return value
547

--- 36 unchanged lines hidden (view full) ---

584 global _NextEthernetAddr
585
586 value = _NextEthernetAddr
587 _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1)
588 return value
589
590class EthernetAddr(ParamValue):
591 cxx_type = 'Net::EthAddr'
565 def getValue(self):
566 from m5.objects.params import TickRange
567
568 value = TickRange()
569 value.start = long(self.first)
570 value.end = long(self.second)
571 return value
572

--- 36 unchanged lines hidden (view full) ---

609 global _NextEthernetAddr
610
611 value = _NextEthernetAddr
612 _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1)
613 return value
614
615class EthernetAddr(ParamValue):
616 cxx_type = 'Net::EthAddr'
592 cxx_predecls = ['#include "base/inet.hh"']
593 swig_predecls = ['%include "python/swig/inet.i"']
617
618 @classmethod
619 def cxx_predecls(cls, code):
620 code('#include "base/inet.hh"')
621
622 @classmethod
623 def swig_predecls(cls, code):
624 code('%include "python/swig/inet.i"')
625
594 def __init__(self, value):
595 if value == NextEthernetAddr:
596 self.value = value
597 return
598
599 if not isinstance(value, str):
600 raise TypeError, "expected an ethernet address and didn't get one"
601

--- 54 unchanged lines hidden (view full) ---

656 return strptime(value, format)
657 except ValueError:
658 pass
659
660 raise ValueError, "Could not parse '%s' as a time" % value
661
662class Time(ParamValue):
663 cxx_type = 'tm'
626 def __init__(self, value):
627 if value == NextEthernetAddr:
628 self.value = value
629 return
630
631 if not isinstance(value, str):
632 raise TypeError, "expected an ethernet address and didn't get one"
633

--- 54 unchanged lines hidden (view full) ---

688 return strptime(value, format)
689 except ValueError:
690 pass
691
692 raise ValueError, "Could not parse '%s' as a time" % value
693
694class Time(ParamValue):
695 cxx_type = 'tm'
664 cxx_predecls = [ '#include <time.h>' ]
665 swig_predecls = [ '%include "python/swig/time.i"' ]
696
697 @classmethod
698 def cxx_predecls(cls, code):
699 code('#include <time.h>')
700
701 @classmethod
702 def swig_predecls(cls, code):
703 code('%include "python/swig/time.i"')
704
666 def __init__(self, value):
667 self.value = parse_time(value)
668
669 def getValue(self):
670 from m5.objects.params import tm
671
672 c_time = tm()
673 py_time = self.value

--- 70 unchanged lines hidden (view full) ---

744
745 cls.cxx_type = 'Enums::%s' % name
746
747 super(MetaEnum, cls).__init__(name, bases, init_dict)
748
749 # Generate C++ class declaration for this enum type.
750 # Note that we wrap the enum in a class/struct to act as a namespace,
751 # so that the enum strings can be brief w/o worrying about collisions.
705 def __init__(self, value):
706 self.value = parse_time(value)
707
708 def getValue(self):
709 from m5.objects.params import tm
710
711 c_time = tm()
712 py_time = self.value

--- 70 unchanged lines hidden (view full) ---

783
784 cls.cxx_type = 'Enums::%s' % name
785
786 super(MetaEnum, cls).__init__(name, bases, init_dict)
787
788 # Generate C++ class declaration for this enum type.
789 # Note that we wrap the enum in a class/struct to act as a namespace,
790 # so that the enum strings can be brief w/o worrying about collisions.
752 def cxx_decl(cls):
791 def cxx_decl(cls, code):
753 name = cls.__name__
792 name = cls.__name__
754 code = "#ifndef __ENUM__%s\n" % name
755 code += '#define __ENUM__%s\n' % name
756 code += '\n'
757 code += 'namespace Enums {\n'
758 code += ' enum %s {\n' % name
793 code('''\
794#ifndef __ENUM__${name}__
795#define __ENUM__${name}__
796
797namespace Enums {
798 enum $name {
799''')
800 code.indent(2)
759 for val in cls.vals:
801 for val in cls.vals:
760 code += ' %s = %d,\n' % (val, cls.map[val])
761 code += ' Num_%s = %d,\n' % (name, len(cls.vals))
762 code += ' };\n'
763 code += ' extern const char *%sStrings[Num_%s];\n' % (name, name)
764 code += '}\n'
765 code += '\n'
766 code += '#endif\n'
767 return code
802 code('$val = ${{cls.map[val]}},')
803 code('Num_$name = ${{len(cls.vals)}},')
804 code.dedent(2)
805 code('''\
806 };
807extern const char *${name}Strings[Num_${name}];
808}
768
809
769 def cxx_def(cls):
810#endif // __ENUM__${name}__
811''')
812
813 def cxx_def(cls, code):
770 name = cls.__name__
814 name = cls.__name__
771 code = '#include "enums/%s.hh"\n' % name
772 code += 'namespace Enums {\n'
773 code += ' const char *%sStrings[Num_%s] =\n' % (name, name)
774 code += ' {\n'
815 code('''\
816#include "enums/${name}.hh"
817namespace Enums {
818 const char *${name}Strings[Num_${name}] =
819 {
820''')
821 code.indent(2)
775 for val in cls.vals:
822 for val in cls.vals:
776 code += ' "%s",\n' % val
777 code += ' };\n'
778 code += '}\n'
779 return code
823 code('"$val",')
824 code.dedent(2)
825 code('''
826 };
827/* namespace Enums */ }
828''')
780
781# Base class for enum types.
782class Enum(ParamValue):
783 __metaclass__ = MetaEnum
784 vals = []
785
786 def __init__(self, value):
787 if value not in self.map:

--- 7 unchanged lines hidden (view full) ---

795 def __str__(self):
796 return self.value
797
798# how big does a rounding error need to be before we warn about it?
799frequency_tolerance = 0.001 # 0.1%
800
801class TickParamValue(NumericParamValue):
802 cxx_type = 'Tick'
829
830# Base class for enum types.
831class Enum(ParamValue):
832 __metaclass__ = MetaEnum
833 vals = []
834
835 def __init__(self, value):
836 if value not in self.map:

--- 7 unchanged lines hidden (view full) ---

844 def __str__(self):
845 return self.value
846
847# how big does a rounding error need to be before we warn about it?
848frequency_tolerance = 0.001 # 0.1%
849
850class TickParamValue(NumericParamValue):
851 cxx_type = 'Tick'
803 cxx_predecls = ['#include "base/types.hh"']
804 swig_predecls = ['%import "stdint.i"\n' +
805 '%import "base/types.hh"']
806
852
853 @classmethod
854 def cxx_predecls(cls, code):
855 code('#include "base/types.hh"')
856
857 @classmethod
858 def swig_predecls(cls, code):
859 code('%import "stdint.i"')
860 code('%import "base/types.hh"')
861
807 def getValue(self):
808 return long(self.value)
809
810class Latency(TickParamValue):
811 def __init__(self, value):
812 if isinstance(value, (Latency, Clock)):
813 self.ticks = value.ticks
814 self.value = value.value

--- 58 unchanged lines hidden (view full) ---

873 def ini_str(self):
874 return '%d' % self.getValue()
875
876# A generic frequency and/or Latency value. Value is stored as a latency,
877# but to avoid ambiguity this object does not support numeric ops (* or /).
878# An explicit conversion to a Latency or Frequency must be made first.
879class Clock(ParamValue):
880 cxx_type = 'Tick'
862 def getValue(self):
863 return long(self.value)
864
865class Latency(TickParamValue):
866 def __init__(self, value):
867 if isinstance(value, (Latency, Clock)):
868 self.ticks = value.ticks
869 self.value = value.value

--- 58 unchanged lines hidden (view full) ---

928 def ini_str(self):
929 return '%d' % self.getValue()
930
931# A generic frequency and/or Latency value. Value is stored as a latency,
932# but to avoid ambiguity this object does not support numeric ops (* or /).
933# An explicit conversion to a Latency or Frequency must be made first.
934class Clock(ParamValue):
935 cxx_type = 'Tick'
881 cxx_predecls = ['#include "base/types.hh"']
882 swig_predecls = ['%import "stdint.i"\n' +
883 '%import "base/types.hh"']
936
937 @classmethod
938 def cxx_predecls(cls, code):
939 code('#include "base/types.hh"')
940
941 @classmethod
942 def swig_predecls(cls, code):
943 code('%import "stdint.i"')
944 code('%import "base/types.hh"')
945
884 def __init__(self, value):
885 if isinstance(value, (Latency, Clock)):
886 self.ticks = value.ticks
887 self.value = value.value
888 elif isinstance(value, Frequency):
889 self.ticks = value.ticks
890 self.value = 1.0 / value.value
891 elif value.endswith('t'):

--- 346 unchanged lines hidden ---
946 def __init__(self, value):
947 if isinstance(value, (Latency, Clock)):
948 self.ticks = value.ticks
949 self.value = value.value
950 elif isinstance(value, Frequency):
951 self.ticks = value.ticks
952 self.value = 1.0 / value.value
953 elif value.endswith('t'):

--- 346 unchanged lines hidden ---