35 Notifiers 37 Transactions
Model Builder User's Guide  /  VI Simics API  / 

36 Extension Classes

An extension class is a Simics class which is never instantiated on its own, but instead is used in the construction of other classes to augment them with functionality defined by the extension class.

36.1 Usage Example

The following example defines the my_clock class, which functions just like the standard clock, although with restricted configurability. The extension class clock-extension provides most of the functionality that the my_clock class needs:

import pyobj, simics

class my_clock(pyobj.ConfObject):
    class execute(pyobj.Interface):
        def run(self):
            self.stop = False
            while not simics.VT_async_events_pending() and not self.stop:
                # advance time to the next pending event and dispatch it
                self._up.obj.vtime.iface.event_handler.handle_event()
        def stop(self):
            self.stop = True

    class frequency(pyobj.Interface):
        def get(self):
            return 1E6

simics.SIM_extend_class("my_clock", "clock-extension")

The clock-extension extension class basically provides the following: a port object vtime which is used to dispatch pending events and drive the cycle queues; port objects vtime.cycles and vtime.ps which contain the cycle queue and the pico seconds queue respectively; a cycle interface which interfaces the vtime.cycles object; and a cell attribute which determines which cell the clock belongs to. In short, the clock-extension class defines the event queues and other functionality needed by Simics for an object to be scheduled.

The my_clock class provides the frequency the cycle clock should use by implementing the frequency interface; this interface is used by the vtime object.

When the myclass object gets scheduled, then the run method of the execute interface will be invoked, and in this simple example, the time is forwarded to the next pending event by simply invoking the handle_event method.

36.2 Defining an Extension Class

An extension class is defined just like a regular class. The only difference is that the class kind should be Sim_Class_Kind_Extension. The following example defines an extension class which just extends classes with a single attribute called test:

typedef struct {
        int test;
} test_extension_t;

static conf_class_t *test_cls;

static void *
init(conf_object_t *obj)
{
        return MM_ZALLOC(1, test_extension_t);
}

static void
dealloc(conf_object_t *obj)
{
        test_extension_t *p = SIM_extension_data(obj, test_cls);
        MM_FREE(p);
}

static set_error_t
set_test_attr(conf_object_t *obj, attr_value_t *v)
{
        test_extension_t *p = SIM_extension_data(obj, test_cls);
        p->test = SIM_attr_integer(*v);
        return Sim_Set_OK;
}

static attr_value_t
get_test_attr(conf_object_t *obj)
{
        test_extension_t *p = SIM_extension_data(obj, test_cls);
        return SIM_make_attr_int64(p->test);
}

void
register_test_extension_class(void)
{
    class_info_t class_info = {
        .init = init,
        .dealloc = dealloc,
        .kind = Sim_Class_Kind_Extension,
    };
    cls = SIM_create_class("test_extension", &class_methods);
    SIM_register_attribute(
        cls, "test",
        get_test_attr, set_test_attr,
        "i", "sample test attribute");

    test_cls = cls;
}

The main point to note is that the object data associated with the extension is created by the init method and retrieved by calling SIM_extension_data with the extension class itself as an argument besides the object.

36.3 Defining an Extension Class in Python

The following example uses the pyobj framework to extend the class trivial with the extension class test_extension which provides the attribute test:

import pyobj, simics

class test_extension(pyobj.ClassExtension):
    class test(pyobj.SimpleAttribute(0, 'i')): pass

class trivial(pyobj.ConfObject):
    pass

simics.SIM_extend_class("trivial", "test_extension")

An instance of the trivial class now has the test attribute defined by the extension class:

simics> @SIM_create_object('trivial', 'trivial')
simics> trivial->test = 22
35 Notifiers 37 Transactions