Deleted Added
sdiff udiff text old ( 2714:baa3445b7b9e ) new ( 2738:5d7a31c7fa29 )
full compact
1# Copyright (c) 2004-2005 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

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

128# class specialization via inheritance (e.g., see the L1Cache class in
129# the simple-4cpu.py example), we must do parameter checking even on
130# class instantiation. To provide all these features, we use a
131# metaclass to define most of the SimObject parameter behavior for
132# this class hierarchy.
133#
134#####################################################################
135
136def isSimObject(value):
137 return isinstance(value, SimObject)
138
139def isSimObjectClass(value):
140 try:
141 return issubclass(value, SimObject)
142 except TypeError:
143 # happens if value is not a class at all

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

195# of that class are instantiated, and provides inherited instance
196# behavior).
197class MetaSimObject(type):
198 # Attributes that can be set only at initialization time
199 init_keywords = { 'abstract' : types.BooleanType,
200 'type' : types.StringType }
201 # Attributes that can be set any time
202 keywords = { 'check' : types.FunctionType,
203 'children' : types.ListType }
204
205 # __new__ is called before __init__, and is where the statements
206 # in the body of the class definition get loaded into the class's
207 # __dict__. We intercept this to filter out parameter assignments
208 # and only allow "private" attributes to be passed to the base
209 # __new__ (starting with underscore).
210 def __new__(mcls, name, bases, dict):
211 if dict.has_key('_init_dict'):

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

228 def __init__(cls, name, bases, dict):
229 # calls type.__init__()... I think that's a no-op, but leave
230 # it here just in case it's not.
231 super(MetaSimObject, cls).__init__(name, bases, dict)
232
233 # initialize required attributes
234 cls._params = multidict()
235 cls._values = multidict()
236 cls._instantiated = False # really instantiated or subclassed
237 cls._anon_subclass_counter = 0
238
239 # We don't support multiple inheritance. If you want to, you
240 # must fix multidict to deal with it properly.
241 if len(bases) > 1:
242 raise TypeError, "SimObjects do not support multiple inheritance"
243
244 base = bases[0]
245
246 # the only time the following is not true is when we define
247 # the SimObject class itself
248 if isinstance(base, MetaSimObject):
249 cls._params.parent = base._params
250 cls._values.parent = base._values
251 base._instantiated = True
252
253 # now process the _init_dict items
254 for key,val in cls._init_dict.items():
255 if isinstance(val, (types.FunctionType, types.TypeType)):
256 type.__setattr__(cls, key, val)
257
258 # param descriptions
259 elif isinstance(val, ParamDesc):
260 cls._new_param(key, val)
261
262 # init-time-only keywords
263 elif cls.init_keywords.has_key(key):
264 cls._set_keyword(key, val, cls.init_keywords[key])
265
266 # default: use normal path (ends up in __setattr__)
267 else:
268 setattr(cls, key, val)
269

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

308 if attr.startswith('_'):
309 type.__setattr__(cls, attr, value)
310 return
311
312 if cls.keywords.has_key(attr):
313 cls._set_keyword(attr, value, cls.keywords[attr])
314 return
315
316 # must be SimObject param
317 param = cls._params.get(attr, None)
318 if param:
319 # It's ok: set attribute by delegating to 'object' class.
320 if isSimObjectOrSequence(value) and cls._instantiated:
321 raise AttributeError, \
322 "Cannot set SimObject parameter '%s' after\n" \
323 " class %s has been instantiated or subclassed" \

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

423 if isSimObjectClass(val):
424 setattr(self, key, val(_memo))
425 elif isSimObjectClassSequence(val) and len(val):
426 setattr(self, key, [ v(_memo) for v in val ])
427 # apply attribute assignments from keyword args, if any
428 for key,val in kwargs.iteritems():
429 setattr(self, key, val)
430
431 # Use this instance as a template to create a new class.
432 def makeClass(self, memo = {}):
433 cls = memo.get(self)
434 if not cls:
435 cls = self.__class__.makeSubclass(self._values.local)
436 memo[self] = cls
437 return cls
438
439 # Direct instantiation of instances (cloning) is no longer
440 # allowed; must generate class from instance first.
441 def __call__(self, **kwargs):
442 raise TypeError, "cannot instantiate SimObject; "\
443 "use makeClass() to make class first"
444
445 def __getattr__(self, attr):
446 if self._values.has_key(attr):
447 return self._values[attr]
448
449 raise AttributeError, "object '%s' has no attribute '%s'" \
450 % (self.__class__.__name__, attr)
451
452 # Set attribute (called on foo.attr = value when foo is an
453 # instance of class cls).
454 def __setattr__(self, attr, value):
455 # normal processing for private attributes
456 if attr.startswith('_'):
457 object.__setattr__(self, attr, value)
458 return
459
460 # must be SimObject param
461 param = self._params.get(attr, None)
462 if param:
463 # It's ok: set attribute by delegating to 'object' class.
464 try:
465 value = param.convert(value)
466 except Exception, e:
467 msg = "%s\nError setting param %s.%s to %s\n" % \

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

549 return found_obj, found_obj != None
550
551 def unproxy(self, base):
552 return self
553
554 def print_ini(self):
555 print '[' + self.path() + ']' # .ini section header
556
557 if hasattr(self, 'type') and not isinstance(self, ParamContext):
558 print 'type=%s' % self.type
559
560 child_names = self._children.keys()
561 child_names.sort()
562 np_child_names = [c for c in child_names \
563 if not isinstance(self._children[c], ParamContext)]
564 if len(np_child_names):

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

580 setattr(self, param, value)
581 print '%s=%s' % (param, self._values[param].ini_str())
582
583 print # blank line between objects
584
585 for child in child_names:
586 self._children[child].print_ini()
587
588 # generate output file for 'dot' to display as a pretty graph.
589 # this code is currently broken.
590 def outputDot(self, dot):
591 label = "{%s|" % self.path
592 if isSimObject(self.realtype):
593 label += '%s|' % self.type
594
595 if self.children:

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

1414# "Constants"... handy aliases for various values.
1415#
1416
1417# Some memory range specifications use this as a default upper bound.
1418MaxAddr = Addr.max
1419MaxTick = Tick.max
1420AllMemory = AddrRange(0, MaxAddr)
1421
1422#####################################################################
1423
1424# __all__ defines the list of symbols that get exported when
1425# 'from config import *' is invoked. Try to keep this reasonably
1426# short to avoid polluting other namespaces.
1427__all__ = ['SimObject', 'ParamContext', 'Param', 'VectorParam',
1428 'Parent', 'Self',
1429 'Enum', 'Bool', 'String', 'Float',
1430 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
1431 'Int32', 'UInt32', 'Int64', 'UInt64',
1432 'Counter', 'Addr', 'Tick', 'Percent',
1433 'TcpPort', 'UdpPort', 'EthernetAddr',
1434 'MemorySize', 'MemorySize32',
1435 'Latency', 'Frequency', 'RootClock', 'Clock',
1436 'NetworkBandwidth', 'MemoryBandwidth',
1437 'Range', 'AddrRange', 'MaxAddr', 'MaxTick', 'AllMemory',
1438 'Null', 'NULL',
1439 'NextEthernetAddr']
1440