SIM_cycle_count — read cycle counter
#include <simics/device-api.h> // in C
// always available in DML
cycles_t
SIM_cycle_count(conf_object_t *NOTNULL obj);
import simics
simics.SIM_cycle_count(...)
SIM_cycle_count returns the current simulated clock cycle count at obj.
If obj is a cycle counter implementing either the cycle_event interface or the cycle interface, then the returned count is the number of elapsed cycles according to that object. If obj is not a cycle counter, then the default clock associated with the object is queried for its cycle count.
SIM_cycle_count returns the current time in number of cycles.
Cell Context
SIM_event_cancel_time, SIM_event_cancel_step — cancel an event before expiration
#include <simics/device-api.h> // in C
// always available in DML
void
SIM_event_cancel_time(conf_object_t *NOTNULL clock,
event_class_t *NOTNULL evclass,
conf_object_t *NOTNULL obj,
int (*pred)(lang_void *data, lang_void *match_data),
lang_void *match_data);
void
SIM_event_cancel_step(conf_object_t *NOTNULL clock,
event_class_t *NOTNULL evclass,
conf_object_t *NOTNULL obj,
int (*pred)(lang_void *data, lang_void *match_data),
lang_void *match_data);
import simics
simics.SIM_event_cancel_time(...)
simics.SIM_event_cancel_step(...)
All unexpired evclass events posted for obj on clock for which pred returns nonzero will be cancelled and their destructor methods (if any) called. pred will be called with the data associated with the event and the supplied match_data. If pred is null (None in Python), all evclass events for obj on clock will be cancelled.
There are separate calls for events posted at a point in time (cycle or seconds) and on a specific step.
SimExc_InterfaceNotFound Thrown by SIM_event_cancel_step if the clock object doesn’t implement the step interface.
Cell Context
SIM_event_class_flags — get event class flags
#include <simics/device-api.h> // in C
// always available in DML
event_class_flag_t
SIM_event_class_flags(event_class_t *NOTNULL ec);
import simics
simics.SIM_event_class_flags(...)
Get the event class flags from a registered event class ec.
Cell Context
SIM_event_find_next_cycle, SIM_event_find_next_time, SIM_event_find_next_step — find event expiration time
#include <simics/device-api.h> // in C
// always available in DML
cycles_t
SIM_event_find_next_cycle(conf_object_t *NOTNULL clock,
event_class_t *NOTNULL evclass,
conf_object_t *NOTNULL obj,
int (*pred)(lang_void *data, lang_void *match_data),
lang_void *match_data);
double
SIM_event_find_next_time(conf_object_t *NOTNULL clock,
event_class_t *NOTNULL evclass,
conf_object_t *NOTNULL obj,
int (*pred)(lang_void *data, lang_void *match_data),
lang_void *match_data);
pc_step_t
SIM_event_find_next_step(conf_object_t *NOTNULL clock,
event_class_t *NOTNULL evclass,
conf_object_t *NOTNULL obj,
int (*pred)(lang_void *data, lang_void *match_data),
lang_void *match_data);
import simics
simics.SIM_event_find_next_cycle(...)
simics.SIM_event_find_next_time(...)
simics.SIM_event_find_next_step(...)
Return the number of cycles/seconds/steps to the first event of evclass of obj posted on clock for which pred is true, or -1 if no event matched. pred will be called with the data associated with the event and the supplied match_data. If pred is null (None in Python), the first evclass event for obj on clock will be used.
There are separate calls of events posted at a point in time (cycle or seconds) and on a specific step. Note that the return value of SIM_event_find_next_cycle is only a preliminary estimate; the number of remaining cycles will change if the clock’s frequency changes dynamically. To handle dynamically changing clock frequencies correctly, subscribe to the frequency changes via the clock’s simple_dispatcher interface.
SimExc_InterfaceNotFound Thrown by SIM_event_find_next_step if the clock object doesn’t implement the step interface: Minus one is returned in such a case.
Cell Context
SIM_event_post_time, SIM_event_post_cycle, SIM_event_post_step — post an event
#include <simics/device-api.h> // in C
// always available in DML
void
SIM_event_post_time(conf_object_t *NOTNULL clock,
event_class_t *NOTNULL evclass,
conf_object_t *NOTNULL obj,
double seconds,
lang_void *user_data);
void
SIM_event_post_cycle(conf_object_t *NOTNULL clock,
event_class_t *NOTNULL evclass,
conf_object_t *NOTNULL obj,
cycles_t cycles,
lang_void *user_data);
void
SIM_event_post_step(conf_object_t *NOTNULL clock,
event_class_t *NOTNULL evclass,
conf_object_t *NOTNULL obj,
pc_step_t steps,
lang_void *user_data);
import simics
simics.SIM_event_post_time(...)
simics.SIM_event_post_cycle(...)
simics.SIM_event_post_step(...)
An event of evclass for object obj is posted on clock to occur at a given point in the future. The user_data will be associated with the event.
The clock is the object that should be used for keeping track of time for the event. It can be a processor or an instance of the clock class.
If a configuration class was specified when evclass was registered, then obj must be an instance of that class.
The expiration point can be specified in seconds, cycles or steps by using the appropriate call, and these values are relative to the current state. Events that need to run synchronized (Sim_EC_Machine_Sync) can only be posted in seconds or cycles, not steps, since synchronization can only be perform in virtual time.
Events posted with
SIM_event_post_cycleare posted at a certain point in time based on the clock’s current frequency, not at a certain clock cycle. The difference is significant if the frequency of theclockobject can change dynamically.
SimExc_InterfaceNotFound Thrown by SIM_event_post_step if the clock object doesn’t implement the step interface.
SimExc_General Thrown if the number of steps or time is negative or too far ahead, and, for Sim_EC_Machine_Sync events, if the event is posted less than a time quantum in the future.
Cell Context
SIM_get_event_class — get the event class
#include <simics/device-api.h> // in C
// always available in DML
event_class_t *
SIM_get_event_class(conf_class_t *NOTNULL cl, const char *NOTNULL name);
import simics
simics.SIM_get_event_class(...)
Get an event class registered for a configuration class, as done by the SIM_register_event function. The cl is the configuration class and name is the name of the event class to retrieve.
If the event class cannot be found, nullptr is returned.
Cell Context
SIM_register_event — register an event
#include <simics/device-api.h> // in C
// always available in DML
event_class_t *
SIM_register_event(
const char *NOTNULL name,
conf_class_t *cl,
event_class_flag_t flags,
void (*NOTNULL callback)(conf_object_t *obj, lang_void *data),
void (*destroy)(conf_object_t *obj, lang_void *data),
attr_value_t (*get_value)(conf_object_t *obj, lang_void *data),
lang_void *(*set_value)(conf_object_t *obj, attr_value_t value),
char *(*describe)(conf_object_t *obj, lang_void *data));
import simics
simics.SIM_register_event(...)
Registers events identified by name and to be posted for objects of class cl, and returns the event class to be used in other calls. The supplied methods are:
callbackdestroyget_valueset_valuedescribeprint-event-queue command. If written in C, must return an allocated string (using MM_MALLOC or MM_STRDUP). May be null, in which case the name is used.Null function pointers correspond to the value None when invoked from Python.
The flags are typically either zero or Sim_EC_Notsaved, where Sim_EC_Notsaved indicates that the event should not be saved as part of the configuration. In that case, get_value and set_value must both be null, and cl may also be null.
Additionally, the Sim_EC_No_Serialize flag can be used to specify that the event should not serialize the cell if Multicore Accelerator mode (MCA) is activated. This flag allows the event to run in a threaded context instead of the default cell context. As with all threaded context code, the event callback must protect against threading violations by using SIM_acquire_target and SIM_acquire_object. Setting this flag can significantly speed up the simulation if such events are posted frequently.
The other flag bits defined in event_class_flag_t are reserved for internal use in the Simics platform and some tightly coupled modules. See the event queue sample code for details on their use.
Global Context
SIM_run_unrestricted — run callback after current instruction
#include <simics/device-api.h> // in C
// always available in DML
void
SIM_run_unrestricted(conf_object_t *NOTNULL obj,
void (*NOTNULL func)(conf_object_t *obj,
lang_void *param),
lang_void *user_data);
import simics
simics.SIM_run_unrestricted(...)
The func functions will be called immediately, if Simics is not currently running an instruction, or as soon as the current instruction has completed.
Note that with the introduction of Multicore Accelerator, if an instruction is running when calling SIM_run_unrestricted, other simulation threads may continue for a while until they stop and the callback is serviced. This means that an object using SIM_run_unrestricted may receive calls through for example the io_memory interface after returning from the scope where SIM_run_unrestricted is called but before the func callback function is called. For more information on considerations for Multicore Accelerator, see the Threading Model chapter.
If several functions are registered this way before any of them has had a chance to run, the functions will be run in their order of registration.
This call is mainly useful for actions that for various reasons can not be done while an instruction is being emulated.
The obj is an object that has a clock (as defined by SIM_object_clock). This object and user_data are passed to the callback function.
Since the callback is run in Cell Context, simulation threads for other cells may be running when the callback is executed. Consequently, only objects in the same cell as obj may be accessed from the callback.
All contexts including Threaded Context (call); Cell Context (callback)
SIM_step_count — get step count
#include <simics/device-api.h> // in C
// always available in DML
pc_step_t
SIM_step_count(conf_object_t *NOTNULL obj);
import simics
simics.SIM_step_count(...)
Returns the number of steps executed by the processor obj. A step is a completed instruction, an instruction causing a synchronous exception, or an asynchronous exception (interrupt).
SimExc_InterfaceNotFound Thrown if the obj object doesn’t implement the step interface. Minus one is returned in such a case.
Cell Context
SIM_time — get current simulated time
#include <simics/device-api.h> // in C
// always available in DML
double
SIM_time(conf_object_t *NOTNULL obj);
import simics
simics.SIM_time(...)
SIM_time returns the current time at obj.
The returned time relates to how long the simulation has been running, and is usually not very useful in itself, but it can be used to compare with other times. The time on a specific processor is guaranteed to increase when simulation progresses, even if the clock frequency is changed. When adding a processor, it is assigned a current time to be synchronized with other processors in the simulation, or the time 0.0 if it is the first processor.
The precision of the returned value degrades significantly with simulated time due to its representation as a double. When absolute timestamps are needed for the actual simulation, it is recommended that the
SIM_cycle_countfunction is used instead on the picosecond clock.
Using
SIM_timeon the picosecond clock will currently give the same result asSIM_timeon the default clock. That is, the precision of this API function is limited by the frequency of the default clock.
SIM_time returns the current time in seconds as a floating point value.
Cell Context