SimObject.py (10195:7d4d0cd3f7e5) | SimObject.py (10267:ed97f6f2ed7a) |
---|---|
1# Copyright (c) 2012 ARM Limited 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license --- 158 unchanged lines hidden (view full) --- 167 # initialize required attributes 168 169 # class-only attributes 170 cls._params = multidict() # param descriptions 171 cls._ports = multidict() # port descriptions 172 173 # class or instance attributes 174 cls._values = multidict() # param values | 1# Copyright (c) 2012 ARM Limited 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license --- 158 unchanged lines hidden (view full) --- 167 # initialize required attributes 168 169 # class-only attributes 170 cls._params = multidict() # param descriptions 171 cls._ports = multidict() # port descriptions 172 173 # class or instance attributes 174 cls._values = multidict() # param values |
175 cls._hr_values = multidict() # human readable param values |
|
175 cls._children = multidict() # SimObject children 176 cls._port_refs = multidict() # port ref objects 177 cls._instantiated = False # really instantiated, cloned, or subclassed 178 179 # We don't support multiple inheritance of sim objects. If you want 180 # to, you must fix multidict to deal with it properly. Non sim-objects 181 # are ok, though 182 bTotal = 0 --- 9 unchanged lines hidden (view full) --- 192 # inherit all its settings from the base class. The only time 193 # the following is not true is when we define the SimObject 194 # class itself (in which case the multidicts have no parent). 195 if isinstance(base, MetaSimObject): 196 cls._base = base 197 cls._params.parent = base._params 198 cls._ports.parent = base._ports 199 cls._values.parent = base._values | 176 cls._children = multidict() # SimObject children 177 cls._port_refs = multidict() # port ref objects 178 cls._instantiated = False # really instantiated, cloned, or subclassed 179 180 # We don't support multiple inheritance of sim objects. If you want 181 # to, you must fix multidict to deal with it properly. Non sim-objects 182 # are ok, though 183 bTotal = 0 --- 9 unchanged lines hidden (view full) --- 193 # inherit all its settings from the base class. The only time 194 # the following is not true is when we define the SimObject 195 # class itself (in which case the multidicts have no parent). 196 if isinstance(base, MetaSimObject): 197 cls._base = base 198 cls._params.parent = base._params 199 cls._ports.parent = base._ports 200 cls._values.parent = base._values |
201 cls._hr_values.parent = base._hr_values |
|
200 cls._children.parent = base._children 201 cls._port_refs.parent = base._port_refs 202 # mark base as having been subclassed 203 base._instantiated = True 204 else: 205 cls._base = None 206 207 # default keyword values --- 60 unchanged lines hidden (view full) --- 268 pdesc.name = name 269 cls._params[name] = pdesc 270 if hasattr(pdesc, 'default'): 271 cls._set_param(name, pdesc.default, pdesc) 272 273 def _set_param(cls, name, value, param): 274 assert(param.name == name) 275 try: | 202 cls._children.parent = base._children 203 cls._port_refs.parent = base._port_refs 204 # mark base as having been subclassed 205 base._instantiated = True 206 else: 207 cls._base = None 208 209 # default keyword values --- 60 unchanged lines hidden (view full) --- 270 pdesc.name = name 271 cls._params[name] = pdesc 272 if hasattr(pdesc, 'default'): 273 cls._set_param(name, pdesc.default, pdesc) 274 275 def _set_param(cls, name, value, param): 276 assert(param.name == name) 277 try: |
278 hr_value = value |
|
276 value = param.convert(value) 277 except Exception, e: 278 msg = "%s\nError setting param %s.%s to %s\n" % \ 279 (e, cls.__name__, name, value) 280 e.args = (msg, ) 281 raise 282 cls._values[name] = value 283 # if param value is a SimObject, make it a child too, so that 284 # it gets cloned properly when the class is instantiated 285 if isSimObjectOrVector(value) and not value.has_parent(): 286 cls._add_cls_child(name, value) | 279 value = param.convert(value) 280 except Exception, e: 281 msg = "%s\nError setting param %s.%s to %s\n" % \ 282 (e, cls.__name__, name, value) 283 e.args = (msg, ) 284 raise 285 cls._values[name] = value 286 # if param value is a SimObject, make it a child too, so that 287 # it gets cloned properly when the class is instantiated 288 if isSimObjectOrVector(value) and not value.has_parent(): 289 cls._add_cls_child(name, value) |
290 # update human-readable values of the param if it has a literal 291 # value and is not an object or proxy. 292 if not (isSimObjectOrVector(value) or\ 293 isinstance(value, m5.proxy.BaseProxy)): 294 cls._hr_values[name] = hr_value |
|
287 288 def _add_cls_child(cls, name, child): 289 # It's a little funky to have a class as a parent, but these 290 # objects should never be instantiated (only cloned, which 291 # clears the parent pointer), and this makes it clear that the 292 # object is not an orphan and can provide better error 293 # messages. 294 child.set_parent(cls, name) --- 285 unchanged lines hidden (view full) --- 580# SimObject class definition to the MetaSimObject methods (in 581# particular _set_param, which gets called for parameters with default 582# values defined on the SimObject class itself). It will get 583# overridden by the permanent definition (which requires that 584# SimObject be defined) lower in this file. 585def isSimObjectOrVector(value): 586 return False 587 | 295 296 def _add_cls_child(cls, name, child): 297 # It's a little funky to have a class as a parent, but these 298 # objects should never be instantiated (only cloned, which 299 # clears the parent pointer), and this makes it clear that the 300 # object is not an orphan and can provide better error 301 # messages. 302 child.set_parent(cls, name) --- 285 unchanged lines hidden (view full) --- 588# SimObject class definition to the MetaSimObject methods (in 589# particular _set_param, which gets called for parameters with default 590# values defined on the SimObject class itself). It will get 591# overridden by the permanent definition (which requires that 592# SimObject be defined) lower in this file. 593def isSimObjectOrVector(value): 594 return False 595 |
596# This class holds information about each simobject parameter 597# that should be displayed on the command line for use in the 598# configuration system. 599class ParamInfo(object): 600 def __init__(self, type, desc, type_str, example, default_val, access_str): 601 self.type = type 602 self.desc = desc 603 self.type_str = type_str 604 self.example_str = example 605 self.default_val = default_val 606 # The string representation used to access this param through python. 607 # The method to access this parameter presented on the command line may 608 # be different, so this needs to be stored for later use. 609 self.access_str = access_str 610 self.created = True 611 612 # Make it so we can only set attributes at initialization time 613 # and effectively make this a const object. 614 def __setattr__(self, name, value): 615 if not "created" in self.__dict__: 616 self.__dict__[name] = value 617 |
|
588# The SimObject class is the root of the special hierarchy. Most of 589# the code in this class deals with the configuration hierarchy itself 590# (parent/child node relationships). 591class SimObject(object): 592 # Specify metaclass. Any class inheriting from SimObject will 593 # get this metaclass. 594 __metaclass__ = MetaSimObject 595 type = 'SimObject' --- 20 unchanged lines hidden (view full) --- 616 void initState(); 617 void regStats(); 618 void resetStats(); 619 void regProbePoints(); 620 void regProbeListeners(); 621 void startup(); 622''') 623 | 618# The SimObject class is the root of the special hierarchy. Most of 619# the code in this class deals with the configuration hierarchy itself 620# (parent/child node relationships). 621class SimObject(object): 622 # Specify metaclass. Any class inheriting from SimObject will 623 # get this metaclass. 624 __metaclass__ = MetaSimObject 625 type = 'SimObject' --- 20 unchanged lines hidden (view full) --- 646 void initState(); 647 void regStats(); 648 void resetStats(); 649 void regProbePoints(); 650 void regProbeListeners(); 651 void startup(); 652''') 653 |
654 # Returns a dict of all the option strings that can be 655 # generated as command line options for this simobject instance 656 # by tracing all reachable params in the top level instance and 657 # any children it contains. 658 def enumerateParams(self, flags_dict = {}, 659 cmd_line_str = "", access_str = ""): 660 if hasattr(self, "_paramEnumed"): 661 print "Cycle detected enumerating params" 662 else: 663 self._paramEnumed = True 664 # Scan the children first to pick up all the objects in this SimObj 665 for keys in self._children: 666 child = self._children[keys] 667 next_cmdline_str = cmd_line_str + keys 668 next_access_str = access_str + keys 669 if not isSimObjectVector(child): 670 next_cmdline_str = next_cmdline_str + "." 671 next_access_str = next_access_str + "." 672 flags_dict = child.enumerateParams(flags_dict, 673 next_cmdline_str, 674 next_access_str) 675 676 # Go through the simple params in the simobject in this level 677 # of the simobject hierarchy and save information about the 678 # parameter to be used for generating and processing command line 679 # options to the simulator to set these parameters. 680 for keys,values in self._params.items(): 681 if values.isCmdLineSettable(): 682 type_str = '' 683 ex_str = values.example_str() 684 ptype = None 685 if isinstance(values, VectorParamDesc): 686 type_str = 'Vector_%s' % values.ptype_str 687 ptype = values 688 else: 689 type_str = '%s' % values.ptype_str 690 ptype = values.ptype 691 692 if keys in self._hr_values\ 693 and keys in self._values\ 694 and not isinstance(self._values[keys], m5.proxy.BaseProxy): 695 cmd_str = cmd_line_str + keys 696 acc_str = access_str + keys 697 flags_dict[cmd_str] = ParamInfo(ptype, 698 self._params[keys].desc, type_str, ex_str, 699 values.pretty_print(self._hr_values[keys]), 700 acc_str) 701 elif not keys in self._hr_values\ 702 and not keys in self._values: 703 # Empty param 704 cmd_str = cmd_line_str + keys 705 acc_str = access_str + keys 706 flags_dict[cmd_str] = ParamInfo(ptype, 707 self._params[keys].desc, 708 type_str, ex_str, '', acc_str) 709 710 return flags_dict 711 |
|
624 # Initialize new instance. For objects with SimObject-valued 625 # children, we need to recursively clone the classes represented 626 # by those param values as well in a consistent "deep copy"-style 627 # fashion. That is, we want to make sure that each instance is 628 # cloned only once, and that if there are multiple references to 629 # the same original object, we end up with the corresponding 630 # cloned references all pointing to the same cloned instance. 631 def __init__(self, **kwargs): --- 24 unchanged lines hidden (view full) --- 656 self._children = {} 657 for key,val in ancestor._children.iteritems(): 658 self.add_child(key, val(_memo=memo_dict)) 659 660 # Inherit parameter values from class using multidict so 661 # individual value settings can be overridden but we still 662 # inherit late changes to non-overridden class values. 663 self._values = multidict(ancestor._values) | 712 # Initialize new instance. For objects with SimObject-valued 713 # children, we need to recursively clone the classes represented 714 # by those param values as well in a consistent "deep copy"-style 715 # fashion. That is, we want to make sure that each instance is 716 # cloned only once, and that if there are multiple references to 717 # the same original object, we end up with the corresponding 718 # cloned references all pointing to the same cloned instance. 719 def __init__(self, **kwargs): --- 24 unchanged lines hidden (view full) --- 744 self._children = {} 745 for key,val in ancestor._children.iteritems(): 746 self.add_child(key, val(_memo=memo_dict)) 747 748 # Inherit parameter values from class using multidict so 749 # individual value settings can be overridden but we still 750 # inherit late changes to non-overridden class values. 751 self._values = multidict(ancestor._values) |
752 self._hr_values = multidict(ancestor._hr_values) |
|
664 # clone SimObject-valued parameters 665 for key,val in ancestor._values.iteritems(): 666 val = tryAsSimObjectOrVector(val) 667 if val is not None: 668 self._values[key] = val(_memo=memo_dict) 669 670 # clone port references. no need to use a multidict here 671 # since we will be creating new references for all ports. --- 74 unchanged lines hidden (view full) --- 746 if self._ports.has_key(attr): 747 # set up port connection 748 self._get_port_ref(attr).connect(value) 749 return 750 751 param = self._params.get(attr) 752 if param: 753 try: | 753 # clone SimObject-valued parameters 754 for key,val in ancestor._values.iteritems(): 755 val = tryAsSimObjectOrVector(val) 756 if val is not None: 757 self._values[key] = val(_memo=memo_dict) 758 759 # clone port references. no need to use a multidict here 760 # since we will be creating new references for all ports. --- 74 unchanged lines hidden (view full) --- 835 if self._ports.has_key(attr): 836 # set up port connection 837 self._get_port_ref(attr).connect(value) 838 return 839 840 param = self._params.get(attr) 841 if param: 842 try: |
843 hr_value = value |
|
754 value = param.convert(value) 755 except Exception, e: 756 msg = "%s\nError setting param %s.%s to %s\n" % \ 757 (e, self.__class__.__name__, attr, value) 758 e.args = (msg, ) 759 raise 760 self._values[attr] = value 761 # implicitly parent unparented objects assigned as params 762 if isSimObjectOrVector(value) and not value.has_parent(): 763 self.add_child(attr, value) | 844 value = param.convert(value) 845 except Exception, e: 846 msg = "%s\nError setting param %s.%s to %s\n" % \ 847 (e, self.__class__.__name__, attr, value) 848 e.args = (msg, ) 849 raise 850 self._values[attr] = value 851 # implicitly parent unparented objects assigned as params 852 if isSimObjectOrVector(value) and not value.has_parent(): 853 self.add_child(attr, value) |
854 # set the human-readable value dict if this is a param 855 # with a literal value and is not being set as an object 856 # or proxy. 857 if not (isSimObjectOrVector(value) or\ 858 isinstance(value, m5.proxy.BaseProxy)): 859 self._hr_values[attr] = hr_value 860 |
|
764 return 765 766 # if RHS is a SimObject, it's an implicit child assignment 767 if isSimObjectOrSequence(value): 768 self.add_child(attr, value) 769 return 770 771 # no valid assignment... raise exception 772 raise AttributeError, "Class %s has no parameter %s" \ 773 % (self.__class__.__name__, attr) 774 775 776 # this hack allows tacking a '[0]' onto parameters that may or may 777 # not be vectors, and always getting the first element (e.g. cpus) 778 def __getitem__(self, key): 779 if key == 0: 780 return self | 861 return 862 863 # if RHS is a SimObject, it's an implicit child assignment 864 if isSimObjectOrSequence(value): 865 self.add_child(attr, value) 866 return 867 868 # no valid assignment... raise exception 869 raise AttributeError, "Class %s has no parameter %s" \ 870 % (self.__class__.__name__, attr) 871 872 873 # this hack allows tacking a '[0]' onto parameters that may or may 874 # not be vectors, and always getting the first element (e.g. cpus) 875 def __getitem__(self, key): 876 if key == 0: 877 return self |
781 raise TypeError, "Non-zero index '%s' to SimObject" % key | 878 raise IndexError, "Non-zero index '%s' to SimObject" % key |
782 | 879 |
880 # this hack allows us to iterate over a SimObject that may 881 # not be a vector, so we can call a loop over it and get just one 882 # element. 883 def __len__(self): 884 return 1 885 |
|
783 # Also implemented by SimObjectVector 784 def clear_parent(self, old_parent): 785 assert self._parent is old_parent 786 self._parent = None 787 788 # Also implemented by SimObjectVector 789 def set_parent(self, parent, name): 790 self._parent = parent --- 258 unchanged lines hidden (view full) --- 1049 def getCCObject(self): 1050 if not self._ccObject: 1051 # Make sure this object is in the configuration hierarchy 1052 if not self._parent and not isRoot(self): 1053 raise RuntimeError, "Attempt to instantiate orphan node" 1054 # Cycles in the configuration hierarchy are not supported. This 1055 # will catch the resulting recursion and stop. 1056 self._ccObject = -1 | 886 # Also implemented by SimObjectVector 887 def clear_parent(self, old_parent): 888 assert self._parent is old_parent 889 self._parent = None 890 891 # Also implemented by SimObjectVector 892 def set_parent(self, parent, name): 893 self._parent = parent --- 258 unchanged lines hidden (view full) --- 1152 def getCCObject(self): 1153 if not self._ccObject: 1154 # Make sure this object is in the configuration hierarchy 1155 if not self._parent and not isRoot(self): 1156 raise RuntimeError, "Attempt to instantiate orphan node" 1157 # Cycles in the configuration hierarchy are not supported. This 1158 # will catch the resulting recursion and stop. 1159 self._ccObject = -1 |
1057 params = self.getCCParams() 1058 self._ccObject = params.create() | 1160 if not self.abstract: 1161 params = self.getCCParams() 1162 self._ccObject = params.create() |
1059 elif self._ccObject == -1: 1060 raise RuntimeError, "%s: Cycle found in configuration hierarchy." \ 1061 % self.path() 1062 return self._ccObject 1063 1064 def descendants(self): 1065 yield self 1066 for child in self._children.itervalues(): --- 78 unchanged lines hidden --- | 1163 elif self._ccObject == -1: 1164 raise RuntimeError, "%s: Cycle found in configuration hierarchy." \ 1165 % self.path() 1166 return self._ccObject 1167 1168 def descendants(self): 1169 yield self 1170 for child in self._children.itervalues(): --- 78 unchanged lines hidden --- |