cpu_memory_query cycle_control
API Reference Manual  /  5 Model-to-Simulator Interfaces  / 

cycle

Description
Interface Methods
The cycle interface is typically implemented by processors, but can be implemented by other objects as well. Its purpose is to handle events based on time. The cycle queue has a cycle as the smallest time unit. The cycle queue also has an associated frequency which makes it possible to define events based on seconds or picoseconds.

The get_frequency function returns the frequency in Hertz for the queue. Most objects implementing cycle also have a notification mechanism for frequency changes through the simple_dispatcher interface in the cpu_frequency port. It is recommended that such a notification mechanism is used to get updates rather than polling with get_frequency.

The current number of cycles executed by the queue is returned by get_cycle_count. Time elapsed since the queue was created is returned by get_time (in seconds) and get_time_in_ps (in picoseconds); this will be equal to the value returned by get_cycle_count divided by the value returned by get_frequency if the frequency has been constant since time zero.

The cycles_delta function returns the highest number of cycles obj can run before it passes the absolute local time when, assuming no frequency change occurs in the meantime. Note that cycles_delta can raise an exception if when was too far ahead in the future. The cycles_delta_from_ps function performs the same function, for an absolute local time expressed in picoseconds.

The post_cycle function will schedule an event that will occur after cycles counted from local current time at queue. The post_time function is similar but takes seconds as argument, while post_time_in_ps takes a number of picoseconds. The arguments cycles, seconds and picoseconds must be nonnegative.

An event previously posted can be removed by calling cancel. The cancel function takes a function pred as argument which is called when a matching event is found. The event is only removed if pred returns 1.

The find_next_cycle, find_next_time and find_next_time_as_ps functions take the same arguments as cancel but only return the number of cycles, seconds or picoseconds before the event occur. The evclass is the event class, obj is the object posting the event, and user_data is pointer to data used as a parameter when calling the callback function defined in the evclass. If no matching event was found, find_next_cycle and find_next_time return −1; find_next_time_as_ps returns ILLEGAL_DURATION.

The events method returns a list of all pending events in expiration order. Each element is a four-element list containing the event object, the event class name, the expiration time counted in cycles as an integer and the event description as given by the event class describe method, or NIL for events whose event class does not define that method.

What happens to already posted events when a frequency change occurs is implementation dependent. Simics processors will scale the cycle queue to keep the time left before triggering events equal across the frequency change. Note that the new times will be rounded to entire cycles during the scaling, so approximations may occur when switching between high and low frequencies.

Implementation
It is implementation dependent how the queue is implemented, whether cycles or seconds are used as underlying time unit, and what happens when the frequency is changed.

Objects implementing the cycle interface are usually meant to be scheduled by Simics itself. For this to happen, a number of conditions must be fulfilled:

  • Each schedulable object implementing the cycle interface must be controlled by an object implementing the execute interface. It can be the same object that implements the execute interface. The object implementing the execute interface points to the object implementing the cycle interface via its queue attribute.
  • Any schedulable object implementing the cycle interface must inform Simics about changes in frequency by calling the VT_clock_frequency_change function. That also applies to the initial frequency set when the object is created.
  • For schedulable objects, the cycle interface must be registered with SIM_register_clock, which will also add some Simics specific attributes to the corresponding class. Beyond those, the implementor of the cycle can use any checkpoint representation. The name field in the event class data structure is unique, and the attribute setter function for checkpoint restore can use VT_get_event_class to get the event class structure corresponding to an event class name.

SIM_INTERFACE(cycle) {

        cycles_t (*get_cycle_count)(conf_object_t *queue);
        double (*get_time)(conf_object_t *queue);
        cycles_t (*cycles_delta)(conf_object_t *NOTNULL clock,
                                 double when);

        uint64 (*get_frequency)(conf_object_t *queue);

        void (*post_cycle)(
                conf_object_t *NOTNULL queue,
                event_class_t *NOTNULL evclass,
                conf_object_t *NOTNULL obj,
                cycles_t cycles,
                lang_void *user_data);
        void (*post_time)(
                conf_object_t *NOTNULL queue,
                event_class_t *NOTNULL evclass,
                conf_object_t *NOTNULL obj,
                double seconds,
                lang_void *user_data);

        void (*cancel)(
                conf_object_t *NOTNULL queue,
                event_class_t *NOTNULL evclass,
                conf_object_t *NOTNULL obj,
                int (*pred)(lang_void *data, lang_void *match_data),
                lang_void *match_data);

        cycles_t (*find_next_cycle)(
                conf_object_t *NOTNULL queue,
                event_class_t *NOTNULL evclass,
                conf_object_t *NOTNULL obj,
                int (*pred)(lang_void *data, lang_void *match_data),
                lang_void *match_data);

        double (*find_next_time)(
                conf_object_t *NOTNULL queue,
                event_class_t *NOTNULL evclass,
                conf_object_t *NOTNULL obj,
                int (*pred)(lang_void *data, lang_void *match_data),
                lang_void *match_data);

        attr_value_t (*events)(conf_object_t *NOTNULL obj);

        /* new picoseconds based functions */
        local_time_t (*get_time_in_ps)(conf_object_t *queue);
        cycles_t (*cycles_delta_from_ps)(conf_object_t *NOTNULL clock,
                                         local_time_t when);
        void (*post_time_in_ps)(
                conf_object_t *NOTNULL queue,
                event_class_t *NOTNULL evclass,
                conf_object_t *NOTNULL obj,
                duration_t picoseconds,
                lang_void *user_data);

        duration_t (*find_next_time_in_ps)(
                conf_object_t *NOTNULL queue,
                event_class_t *NOTNULL evclass,
                conf_object_t *NOTNULL obj,
                int (*pred)(lang_void *data, lang_void *match_data),
                lang_void *match_data);
};

#define CYCLE_INTERFACE "cycle"

Execution Context
Cell Context for all methods.

cpu_memory_query cycle_control