The arguments to SIM_register_attribute is taken from the
class members. The attrattr member is an
attr_attr_t
type and its default value is
Sim_Attr_Optional
. The attrtype member is a string
defining the type of the attribute, default value is 'a'.
The class methods named getter and setter will be used as get_attr and set_attr functions when registering the attribute. The methods are optional. An attribute without a getter can not be read. An attribute without a setter can not be written.
The attribute description is the same as the Python class description.
The _initialize method can be defined if special initialization behavior is required. This can for instance be used to set the default value.
class wee(pyobj.Attribute): """Documentation for the attribute goes here.""" attrattr = simics.Sim_Attr_Pseudo attrtype = 'i' def _initialize(self): self.val = 4711 def getter(self): self.val += 3 return self.val def setter(self, val): self.val = val
The value stored in the class should always be stored in the
attribute named val
. This is to avoid problems when a
class that defines a pyobj.Attribute class is
inherited by more than one class.
The pyobj.ClassAttribute class is very similar to the pyobj.Attribute class. See the documentation for the pyobj.Attribute class for how to use this class.
class wee(pyobj.ClassAttribute): """Documentation for the attribute goes here.""" attrtype = 'i' val = 4711 @classmethod def getter(cls): return cls.val @classmethod def setter(cls, val): cls.val = val
The name of the Simics class is identical to the Python class. The class description is the same as the Python class description.
The class implements the methods _initialize, _finalize, _pre_delete, _info, and _status. All of these methods can be overridden if required.
The _initialize method is called when an object of the class is instantiated. The _finalize method is called when the object is finalized. The _pre_delete method is called right before an object of the class is deleted.
The _info and _status methods provide data for the class's info and status commands; the format of their return value is documented with cli.new_info_command and cli.new_status_command.
If you need to get hold of the Simics conf_object_t
object
associated with a ConfObject instance—for
example, in order to call a Simics API function—you can find
it in the obj member.
The pyobj.ConfObject class can contain inner classes that define attributes, interfaces, etc. See pyobj.Port, pyobj.Attribute, pyobj.ClassAttribute, and pyobj.Interface for more documentation. An inner class has a reference to the class that contains it in its _up member.
By default, a Simics class is registered automatically whenever a
subclass of pyobj.ConfObject is declared. Sometimes
this is not desirable; e.g., the class may be a base class, or you
may want to allow importing the containing Python file without
side-effects. The automatic registration of a Simics class can
then be suppressed by setting the member _do_not_init
to
object()
. That will cause it to not be registered as a
Simics class (but its subclasses will be, unless they too employ
the same trick).
The class method register may be called once on each pyobj.ConfObject subclass, to register the Simics class. For a class that doesn't suppress automatic registration, the method currently does nothing.
In future Simics versions, a Simics class will no longer be registered automatically, and an explicit call to the register method will be required for that.
The _class_kind member tells Simics whether objects of
this class should be saved when a checkpoint is created.
The value is passed to SIM_register_class, as the
kind field of the class_data_t
structure.
The default value is Sim_Class_Kind_Vanilla
.
See the documentation of SIM_register_class for details.
class foo(pyobj.ConfObject): """This is the long-winded documentation for this Simics class. It can be as long as you want.""" _class_desc = 'One-line doc for the class' def _initialize(self): super()._initialize() self.my_val = 4711 def _info(self): return [("Python device info", [("my_val", self.my_val)])] def _status(self): return [("Python device status", [("woot", self.woot.val), ("signal", self.signal.val)])] class woot(pyobj.SimpleAttribute(0, 'i|n')): """A four-letter attribute""" class lost(pyobj.Attribute): """A pseudo attribute""" attrattr = simics.Sim_Attr_Pseudo def getter(self): return self._up.my_val class signal(pyobj.Interface): def signal_raise(self): self.val = True def signal_lower(self): self.val = False def _initialize(self): self.val = False
Events are posted with the post(clock, data, <duration>) method. clock determines which clock the event is posted on, and data is the event data. The duration is the number of seconds, cycles, or steps until the event triggers, specified with the appropriate keyword argument:
ev.post(a_clock, some_data, seconds = 4.711) ev.post(a_clock, some_data, cycles = 4711) ev.post(a_clock, some_data, steps = 4711)
Events can be cancelled before they trigger with either cancel_time(clock, match_fun) or cancel_step(clock, match_fun) (depending on whether the event duration was specified in steps or not). The match_fun argument is optional: if given, it should be a function that accepts an event data parameter, and returns true for the events that should be cancelled; if not given, all events are cancelled.
A subclass may define the following methods:
attr_value_t
value,
and the other way around. If the event carries no data that needs
checkpointing, you may omit these methods.Additionally, it may set the flags parameter to
Sim_EC_Notsaved
, if the event should not be checkpointed.
In this case, neither get_value nor set_value
should be defined.
class foo(pyobj.ConfObject): class ev1(pyobj.Event): def callback(self, data): do_something(data) class ev2(pyobj.Event): def callback(self, data): self.do_something_else(data) def get_value(self, data): return str(data) def set_value(self, val): return int(val) def describe(self, data): return 'ev2 with %s' % data class ev3(pyobj.Event): flags = simics.Sim_EC_Notsaved def callback(self, data): self._up.do_this_third_thing(data)
The _initialize method can be overridden if special initialization behavior is required.
To implement port interfaces instead of regular interfaces, place one or more pyobj.Interface subclasses inside a pyobj.Port class.
class signal(pyobj.Interface): def signal_raise(self): self.val = True def signal_lower(self): self.val = False def _initialize(self): self.val = False
The _initialize method can be overridden if special initialization behavior is required.
class wee(pyobj.Port): class signal(pyobj.Interface): def signal_raise(self): self.val = 2 def signal_lower(self): self.val = 1 def _initialize(self): self.val = 0
The port object will be registered with the name "port.<name>", but this can be changed by defining namespace to something other than "port". One possibility is the empty string.
If classname is set, then the port object will be an instance of this external class rather than defining the class locally. The external class cannot be modified by adding e.g. an interface definition inside the PortObject definition.
class portname(pyobj.PortObject): """Documentation for the port object goes here.""" class signal(pyobj.Interface): def signal_raise(self): self.val = 2 def signal_lower(self): self.val = 1 def _initialize(self): self.val = 0
SimpleAttribute(init, type = 'a', attr = simics.Sim_Attr_Optional)
val
member.
The init argument is the initial value, type is the attribute type string, attr is the attribute type. If init is callable, it will be called, and the return value is the initial value; otherwise, init itself is the initial value.
The attribute value is stored in the val member of the class.
class wee(pyobj.SimpleAttribute(17, 'i')): """Documentation for the attribute goes here."""
A config attribute defines how the component should be configured. Therefore, all config attributes are also arguments to the new- and create- commands that are used to instantiate the component.
Because of this, the config attribute must always be documented
and the default value of the attrattr member is
Sim_Attr_Optional
.
The ConfigAttribute class contains the valid member, which is a list of valid values for the config attribute. The list gives the user a hint about valid values when creating a component. There is no check that the value written to the attribute is a value in the list of valid values. The list of valid value(s) does not need to contain the default initial value for the config attribute, but it usually does. The valid list should at least contain one valid value even if several values are valid.
class foo(ConfigAttribute): """The foo attribute.""" valid = [667, 4711] def _initialize(self): self.val = 4711 def getter(self): return self.val def setter(self, val): self.val = val
SimpleConfigAttribute(init, type, attr = simics.Sim_Attr_Optional, val = [])
A config attribute defines how the component should be configured. Therefore, all config attributes are also arguments to the new- and create- commands that are used to instantiate the component.
The init argument is the initial value for the
attribute. The type of the attribute is defined by the
type string (currently objects 'o' and dictionaries 'D'
are not supported). The attr argument sets the
attribute kind. The default value for attr is
Sim_Attr_Optional
.
The valid value(s) for the
comp.ConfigAttribute class is set by the
val argument. See the documentation for
SIM_register_attribute for more information about
the arguments.
class cpu_frequency(SimpleConfigAttribute( None, 'i', simics.Sim_Attr_Required)): """Processor frequency in MHz."""
The class will automatically register the required component attributes. Any attribute may be overridden; however, overriding the internal attributes is not recommended.
The automatically registered attributes are:
False
.The class will automatically implement the component
interface. The individual methods of this interface are user-overridable.
Components will automatically get new- and create- commands that can be used to create and instantiate the component. It is possible to override this by setting _no_create_command or _no_new_command to object() to avoid to automatically get create- or new- commands.
class my_comp(StandardComponent): """The my_comp component.""" _class_desc = "my_comp" class bar(SimpleConfigAttribute( None, 'i', simics.Sim_Attr_Required)): """My favorite bar.""" class my_comp(StandardComponent): """The my_comp component.""" _class_desc = "my_comp" _no_create_command = object()
add_component(self, slot, cls, attr, name = '')
The slot argument is the slot name concatenated with a nested array string, defining the number of subcomponents to create. Setting slot to foo will create one subcomponent in the slot foo, setting slot to foo[3] will create an array of three subcomponents in the slot foo, setting slot to foo[3][2] will create an array of three arrays of two arrays with subcomponents in the slot foo.
The cls is the component class, attr is arguments to the component, and name is an optional name.
add_connector(self, slot, type, hotpluggable, required, multi, direction)
The slot argument is the slot name concatenated with a nested array string, defining the number of connectors to create. Setting slot to foo will create one connector in the slot foo, setting slot to foo[3] will create an array of three connectors in the slot foo, setting slot to foo[3][2] will create an array of three arrays of two arrays with connectors in the slot foo.
The type is the type of connection as a string,
hotpluggable is True
or False
depending on
whether the connector is hot-pluggable, required is
True
if the connector must be connected before the component
is instantiated, multi is True
if the connector
supports multiple connections, direction is a
connector_direction_t
which is up
, down
,
or any
.
add_pre_obj(self, slot, cls, name = '', **attr)
The slot argument is the slot name concatenated with a nested array string, defining the number of pre objects to create. Setting slot to foo will create one pre object in the slot foo, setting slot to foo[3] will create an array of three pre objects in the slot foo, setting slot to foo[3][2] will create an array of three arrays of two arrays with pre objects in the slot foo. The cls argument is the type of object class to create. The name argument is deprecated. The attr argument is optional attribute values for the object(s).
add_slot(self, slot, val)
connect(self, cnt0, cnt1)
CompException
exception will be raised if the connection failed.copy_connector(self, slot, src)
del_slot(self, slot)
CompException
exception
will be raised if the slot does not exist, the slot contains
non connector conf objects, or the slot contains connectors that
have been copied with the copy_connector
method. Slots with sub components can not be deleted.get_slot(self, slot)
CompException
exception will be raised.component_connector
interface.add_connector(self, slot, cls)
The slot argument is the slot name for the connector.
The cls argument is an instance of a connector class.
SIM_register_class_update(build_id, classname, function)
The function acts on a single object of a given class. It will be called for all matching objects with the current object as argument. It doesn't need to return anything, however it can't create or destroy objects, only change the attributes of the object it got as parameter, except the object name.
SIM_register_generic_update(build_id, function)
When renaming an object, the function is expected to remove the object from the checkpoint set under its old name and to add it again under its new name. The object should be reported in the changed object list.
SIM_register_post_update(function)
all_objects(set, classname)
Return a list of all objects of class classname present in the checkpoint set.
for_all_objects(set, classname, function)
Apply the function function on all objects of class classname present in set. function is defined as:
function(config, object)
where config is the Python dictionary containing all objects, and object is an object of class classname.
remove_attr(obj, name)
Remove the attribute name from the object obj.
remove_class(set, classname)
In the checkpoint set, remove all objects of class classname.
remove_class_attr(set, classname, name)
In the checkpoint set, remove the class attribute name from all objects of class classname.
rename_attr(obj, new_attr, old_attr)
Rename the attribute old_attr to new_attr in the object obj.
OBJ(name)
pre_conf_object(object_name, class_name, build_id = None)
None
, a unique name will be
generated.
The build-id of the object can be specified when using the
pre_conf_object
class during checkpoints update. Refer to
Model Builder User's Guide for more information.
Future configuration attributes are set using normal Python class members:
a = pre_conf_object("test-object", "test-class") a.value = 42
After using a pre_conf_object object to create a
configuration object, the created object can be obtained by passing the
pre_conf_object's name
member to
SIM_get_object().