config.py (2714:baa3445b7b9e) config.py (2738:5d7a31c7fa29)
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
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
136
137# dict to look up SimObjects based on path
138instanceDict = {}
139
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,
140def isSimObject(value):
141 return isinstance(value, SimObject)
142
143def isSimObjectClass(value):
144 try:
145 return issubclass(value, SimObject)
146 except TypeError:
147 # happens if value is not a class at all

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

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

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

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

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

319 if attr.startswith('_'):
320 type.__setattr__(cls, attr, value)
321 return
322
323 if cls.keywords.has_key(attr):
324 cls._set_keyword(attr, value, cls.keywords[attr])
325 return
326
327 if cls._ports.has_key(attr):
328 self._ports[attr].connect(self, attr, value)
329 return
330
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
331 # must be SimObject param
332 param = cls._params.get(attr, None)
333 if param:
334 # It's ok: set attribute by delegating to 'object' class.
335 if isSimObjectOrSequence(value) and cls._instantiated:
336 raise AttributeError, \
337 "Cannot set SimObject parameter '%s' after\n" \
338 " class %s has been instantiated or subclassed" \

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

438 if isSimObjectClass(val):
439 setattr(self, key, val(_memo))
440 elif isSimObjectClassSequence(val) and len(val):
441 setattr(self, key, [ v(_memo) for v in val ])
442 # apply attribute assignments from keyword args, if any
443 for key,val in kwargs.iteritems():
444 setattr(self, key, val)
445
446 self._ccObject = None # pointer to C++ object
447 self._port_map = {} # map of port connections
448
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):
449 # Use this instance as a template to create a new class.
450 def makeClass(self, memo = {}):
451 cls = memo.get(self)
452 if not cls:
453 cls = self.__class__.makeSubclass(self._values.local)
454 memo[self] = cls
455 return cls
456
457 # Direct instantiation of instances (cloning) is no longer
458 # allowed; must generate class from instance first.
459 def __call__(self, **kwargs):
460 raise TypeError, "cannot instantiate SimObject; "\
461 "use makeClass() to make class first"
462
463 def __getattr__(self, attr):
464 if self._ports.has_key(attr):
465 # return reference that can be assigned to another port
466 # via __setattr__
467 return self._ports[attr].makeRef(self, attr)
468
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
469 if self._values.has_key(attr):
470 return self._values[attr]
471
472 raise AttributeError, "object '%s' has no attribute '%s'" \
473 % (self.__class__.__name__, attr)
474
475 # Set attribute (called on foo.attr = value when foo is an
476 # instance of class cls).
477 def __setattr__(self, attr, value):
478 # normal processing for private attributes
479 if attr.startswith('_'):
480 object.__setattr__(self, attr, value)
481 return
482
483 if self._ports.has_key(attr):
484 # set up port connection
485 self._ports[attr].connect(self, attr, value)
486 return
487
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
488 # must be SimObject param
489 param = self._params.get(attr, None)
490 if param:
491 # It's ok: set attribute by delegating to 'object' class.
492 try:
493 value = param.convert(value)
494 except Exception, e:
495 msg = "%s\nError setting param %s.%s to %s\n" % \

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

577 return found_obj, found_obj != None
578
579 def unproxy(self, base):
580 return self
581
582 def print_ini(self):
583 print '[' + self.path() + ']' # .ini section header
584
585 instanceDict[self.path()] = self
586
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
587 if hasattr(self, 'type') and not isinstance(self, ParamContext):
588 print 'type=%s' % self.type
589
590 child_names = self._children.keys()
591 child_names.sort()
592 np_child_names = [c for c in child_names \
593 if not isinstance(self._children[c], ParamContext)]
594 if len(np_child_names):

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

610 setattr(self, param, value)
611 print '%s=%s' % (param, self._values[param].ini_str())
612
613 print # blank line between objects
614
615 for child in child_names:
616 self._children[child].print_ini()
617
618 # Call C++ to create C++ object corresponding to this object and
619 # (recursively) all its children
620 def createCCObject(self):
621 if self._ccObject:
622 return
623 self._ccObject = -1
624 self._ccObject = m5.main.createSimObject(self.path())
625 for child in self._children.itervalues():
626 child.createCCObject()
627
628 # Create C++ port connections corresponding to the connections in
629 # _port_map (& recursively for all children)
630 def connectPorts(self):
631 for portRef in self._port_map.itervalues():
632 applyOrMap(portRef, 'ccConnect')
633 for child in self._children.itervalues():
634 child.connectPorts()
635
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
636 # generate output file for 'dot' to display as a pretty graph.
637 # this code is currently broken.
638 def outputDot(self, dot):
639 label = "{%s|" % self.path
640 if isSimObject(self.realtype):
641 label += '%s|' % self.type
642
643 if self.children:

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

1462# "Constants"... handy aliases for various values.
1463#
1464
1465# Some memory range specifications use this as a default upper bound.
1466MaxAddr = Addr.max
1467MaxTick = Tick.max
1468AllMemory = AddrRange(0, MaxAddr)
1469
1470
1422#####################################################################
1471#####################################################################
1472#
1473# Port objects
1474#
1475# Ports are used to interconnect objects in the memory system.
1476#
1477#####################################################################
1423
1478
1479# Port reference: encapsulates a reference to a particular port on a
1480# particular SimObject.
1481class PortRef(object):
1482 def __init__(self, simobj, name, isVec):
1483 self.simobj = simobj
1484 self.name = name
1485 self.index = -1
1486 self.isVec = isVec # is this a vector port?
1487 self.peer = None # not associated with another port yet
1488 self.ccConnected = False # C++ port connection done?
1489
1490 # Set peer port reference. Called via __setattr__ as a result of
1491 # a port assignment, e.g., "obj1.port1 = obj2.port2".
1492 def setPeer(self, other):
1493 if self.isVec:
1494 curMap = self.simobj._port_map.get(self.name, [])
1495 self.index = len(curMap)
1496 curMap.append(other)
1497 else:
1498 curMap = self.simobj._port_map.get(self.name)
1499 if curMap and not self.isVec:
1500 print "warning: overwriting port", self.simobj, self.name
1501 curMap = other
1502 self.simobj._port_map[self.name] = curMap
1503 self.peer = other
1504
1505 # Call C++ to create corresponding port connection between C++ objects
1506 def ccConnect(self):
1507 if self.ccConnected: # already done this
1508 return
1509 peer = self.peer
1510 m5.main.connectPorts(self.simobj._ccObject, self.name, self.index,
1511 peer.simobj._ccObject, peer.name, peer.index)
1512 self.ccConnected = True
1513 peer.ccConnected = True
1514
1515# Port description object. Like a ParamDesc object, this represents a
1516# logical port in the SimObject class, not a particular port on a
1517# SimObject instance. The latter are represented by PortRef objects.
1518class Port(object):
1519 def __init__(self, desc):
1520 self.desc = desc
1521 self.isVec = False
1522
1523 # Generate a PortRef for this port on the given SimObject with the
1524 # given name
1525 def makeRef(self, simobj, name):
1526 return PortRef(simobj, name, self.isVec)
1527
1528 # Connect an instance of this port (on the given SimObject with
1529 # the given name) with the port described by the supplied PortRef
1530 def connect(self, simobj, name, ref):
1531 myRef = self.makeRef(simobj, name)
1532 myRef.setPeer(ref)
1533 ref.setPeer(myRef)
1534
1535# VectorPort description object. Like Port, but represents a vector
1536# of connections (e.g., as on a Bus).
1537class VectorPort(Port):
1538 def __init__(self, desc):
1539 Port.__init__(self, desc)
1540 self.isVec = True
1541
1542#####################################################################
1543
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',
1544# __all__ defines the list of symbols that get exported when
1545# 'from config import *' is invoked. Try to keep this reasonably
1546# short to avoid polluting other namespaces.
1547__all__ = ['SimObject', 'ParamContext', 'Param', 'VectorParam',
1548 'Parent', 'Self',
1549 'Enum', 'Bool', 'String', 'Float',
1550 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
1551 'Int32', 'UInt32', 'Int64', 'UInt64',
1552 'Counter', 'Addr', 'Tick', 'Percent',
1553 'TcpPort', 'UdpPort', 'EthernetAddr',
1554 'MemorySize', 'MemorySize32',
1555 'Latency', 'Frequency', 'RootClock', 'Clock',
1556 'NetworkBandwidth', 'MemoryBandwidth',
1557 'Range', 'AddrRange', 'MaxAddr', 'MaxTick', 'AllMemory',
1558 'Null', 'NULL',
1439 'NextEthernetAddr']
1559 'NextEthernetAddr',
1560 'Port', 'VectorPort']
1440
1561