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 |