Deleted Added
sdiff udiff text old ( 7527:fe90827a663f ) new ( 7528:6efc3672733b )
full compact
1# Copyright (c) 2004-2006 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright

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

22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Steve Reinhardt
28# Nathan Binkert
29
30import math
31import sys
32from types import FunctionType
33
34try:
35 import pydot
36except:
37 pydot = False
38
39import m5
40from m5.util import *
41
42# Have to import params up top since Param is referenced on initial
43# load (when SimObject class references Param to create a class
44# variable, the 'name' param)...
45from m5.params import *
46# There are a few things we need that aren't in params.__all__ since
47# normal users don't need them
48from m5.params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
49
50from m5.proxy import *
51from m5.proxy import isproxy
52
53#####################################################################
54#
55# M5 Python Configuration Utility
56#

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

150 # initialize required attributes
151
152 # class-only attributes
153 cls._params = multidict() # param descriptions
154 cls._ports = multidict() # port descriptions
155
156 # class or instance attributes
157 cls._values = multidict() # param values
158 cls._port_refs = multidict() # port ref objects
159 cls._instantiated = False # really instantiated, cloned, or subclassed
160
161 # We don't support multiple inheritance. If you want to, you
162 # must fix multidict to deal with it properly.
163 if len(bases) > 1:
164 raise TypeError, "SimObjects do not support multiple inheritance"
165
166 base = bases[0]
167
168 # Set up general inheritance via multidicts. A subclass will
169 # inherit all its settings from the base class. The only time
170 # the following is not true is when we define the SimObject
171 # class itself (in which case the multidicts have no parent).
172 if isinstance(base, MetaSimObject):
173 cls._base = base
174 cls._params.parent = base._params
175 cls._ports.parent = base._ports
176 cls._values.parent = base._values
177 cls._port_refs.parent = base._port_refs
178 # mark base as having been subclassed
179 base._instantiated = True
180 else:
181 cls._base = None
182
183 # default keyword values
184 if 'type' in cls._value_dict:

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

300 # check for param
301 param = cls._params.get(attr)
302 if param:
303 cls._set_param(attr, value, param)
304 return
305
306 if isSimObjectOrSequence(value):
307 # If RHS is a SimObject, it's an implicit child assignment.
308 # Classes don't have children, so we just put this object
309 # in _values; later, each instance will do a 'setattr(self,
310 # attr, _values[attr])' in SimObject.__init__ which will
311 # add this object as a child.
312 cls._values[attr] = value
313 return
314
315 # no valid assignment... raise exception
316 raise AttributeError, \
317 "Class %s has no parameter \'%s\'" % (cls.__name__, attr)
318
319 def __getattr__(cls, attr):
320 if cls._values.has_key(attr):
321 return cls._values[attr]
322
323 raise AttributeError, \
324 "object '%s' has no attribute '%s'" % (cls.__name__, attr)
325
326 def __str__(cls):
327 return cls.__name__
328
329 def cxx_decl(cls):
330 code = "#ifndef __PARAMS__%s\n" % cls

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

460 memo_dict[ancestor] = self
461
462 if not ancestor:
463 ancestor = self.__class__
464 ancestor._instantiated = True
465
466 # initialize required attributes
467 self._parent = None
468 self._children = {}
469 self._ccObject = None # pointer to C++ object
470 self._ccParams = None
471 self._instantiated = False # really "cloned"
472
473 # Inherit parameter values from class using multidict so
474 # individual value settings can be overridden.
475 self._values = multidict(ancestor._values)
476 # clone SimObject-valued parameters
477 for key,val in ancestor._values.iteritems():
478 if isSimObject(val):
479 setattr(self, key, val(_memo=memo_dict))
480 elif isSimObjectSequence(val) and len(val):
481 setattr(self, key, [ v(_memo=memo_dict) for v in val ])
482 # clone port references. no need to use a multidict here
483 # since we will be creating new references for all ports.
484 self._port_refs = {}
485 for key,val in ancestor._port_refs.iteritems():
486 self._port_refs[key] = val.clone(self, memo_dict)
487 # apply attribute assignments from keyword args, if any
488 for key,val in kwargs.iteritems():
489 setattr(self, key, val)

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

522
523 def __getattr__(self, attr):
524 if self._ports.has_key(attr):
525 return self._get_port_ref(attr)
526
527 if self._values.has_key(attr):
528 return self._values[attr]
529
530 # If the attribute exists on the C++ object, transparently
531 # forward the reference there. This is typically used for
532 # SWIG-wrapped methods such as init(), regStats(),
533 # regFormulas(), resetStats(), startup(), drain(), and
534 # resume().
535 if self._ccObject and hasattr(self._ccObject, attr):
536 return getattr(self._ccObject, attr)
537

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

551 self._get_port_ref(attr).connect(value)
552 return
553
554 if isSimObjectOrSequence(value) and self._instantiated:
555 raise RuntimeError, \
556 "cannot set SimObject parameter '%s' after\n" \
557 " instance been cloned %s" % (attr, `self`)
558
559 # must be SimObject param
560 param = self._params.get(attr)
561 if param:
562 try:
563 value = param.convert(value)
564 except Exception, e:
565 msg = "%s\nError setting param %s.%s to %s\n" % \
566 (e, self.__class__.__name__, attr, value)
567 e.args = (msg, )
568 raise
569 self._set_child(attr, value)
570 return
571
572 if isSimObjectOrSequence(value):
573 self._set_child(attr, value)
574 return
575
576 # no valid assignment... raise exception
577 raise AttributeError, "Class %s has no parameter %s" \
578 % (self.__class__.__name__, attr)
579
580
581 # this hack allows tacking a '[0]' onto parameters that may or may
582 # not be vectors, and always getting the first element (e.g. cpus)
583 def __getitem__(self, key):
584 if key == 0:
585 return self
586 raise TypeError, "Non-zero index '%s' to SimObject" % key
587
588 # clear out children with given name, even if it's a vector
589 def clear_child(self, name):
590 if not self._children.has_key(name):
591 return
592 child = self._children[name]
593 if isinstance(child, SimObjVector):
594 for i in xrange(len(child)):
595 del self._children["s%d" % (name, i)]
596 del self._children[name]
597
598 def add_child(self, name, value):
599 self._children[name] = value
600
601 def _maybe_set_parent(self, parent, name):
602 if not self._parent:
603 self._parent = parent
604 self._name = name
605 parent.add_child(name, self)
606
607 def _set_child(self, attr, value):
608 # if RHS is a SimObject, it's an implicit child assignment
609 # clear out old child with this name, if any
610 self.clear_child(attr)
611
612 if isSimObject(value):
613 value._maybe_set_parent(self, attr)
614 elif isSimObjectSequence(value):
615 value = SimObjVector(value)
616 if len(value) == 1:
617 value[0]._maybe_set_parent(self, attr)
618 else:
619 width = int(math.ceil(math.log(len(value))/math.log(10)))
620 for i,v in enumerate(value):
621 v._maybe_set_parent(self, "%s%0*d" % (attr, width, i))
622
623 self._values[attr] = value
624
625 def path(self):
626 if not self._parent:
627 return '(orphan)'
628 ppath = self._parent.path()
629 if ppath == 'root':
630 return self._name
631 return ppath + "." + self._name
632

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

688 instanceDict[self.path()] = self
689
690 if hasattr(self, 'type'):
691 print >>ini_file, 'type=%s' % self.type
692
693 child_names = self._children.keys()
694 child_names.sort()
695 if len(child_names):
696 print >>ini_file, 'children=%s' % ' '.join(child_names)
697
698 param_names = self._params.keys()
699 param_names.sort()
700 for param in param_names:
701 value = self._values.get(param)
702 if value != None:
703 print >>ini_file, '%s=%s' % (param,
704 self._values[param].ini_str())

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

851 return obj.getCCObject()
852
853def isSimObject(value):
854 return isinstance(value, SimObject)
855
856def isSimObjectClass(value):
857 return issubclass(value, SimObject)
858
859def isSimObjectSequence(value):
860 if not isinstance(value, (list, tuple)) or len(value) == 0:
861 return False
862
863 for val in value:
864 if not isNullPointer(val) and not isSimObject(val):
865 return False
866
867 return True
868
869def isSimObjectOrSequence(value):
870 return isSimObject(value) or isSimObjectSequence(value)
871
872def isRoot(obj):
873 from m5.objects import Root
874 return obj and obj is Root.getInstance()
875
876baseClasses = allClasses.copy()
877baseInstances = instanceDict.copy()
878
879def clear():
880 global allClasses, instanceDict
881
882 allClasses = baseClasses.copy()
883 instanceDict = baseInstances.copy()
884
885# __all__ defines the list of symbols that get exported when
886# 'from config import *' is invoked. Try to keep this reasonably
887# short to avoid polluting other namespaces.
888__all__ = [ 'SimObject' ]