#ifndef __BLUESIM_KERNEL_H__ #define __BLUESIM_KERNEL_H__ #include "bluesim_types.h" /* * Declarations of all functions in the Bluesim kernel API. * All functions have C linkage. */ #if __cplusplus extern "C" { #endif /* * Kernel resource management routines. */ /* This must be called before calling any other Bluesim * kernel API functions. * When master is non-zero, it indicates that the model * is its own master. * * Returns a handle to the simulation state, which is needed * as an argument to the other Bluesim kernel API functions. */ tSimStateHdl bk_init(tModel model, tBool master); /* This should be called at the end of simulation * to free resources controlled by the simulation kernel. * After bk_shutdown() is called, no other Bluesim kernel * API functions may be called unless bk_init() has been * called first. */ void bk_shutdown(tSimStateHdl simHdl); /* Get version information about the Bluesim model */ void bk_version(tSimStateHdl simHdl, tBluesimVersionInfo* version); /* * Kernel clock definition */ /* Define a 2-phase clock waveform to be generated by the * Bluesim kernel. * * name - the name associated with the clock domain * initial_value - the value of the clock before the first edge * has_initial_value - whether the clock gets the initial value or X * first_edge - the delay until the first edge * low_duration - the duration the clock remains CLK_LOW * high_duration - the duration the clock remains CLK_HIGH * * Returns the handle for the newly generated clock. * * Note: the total clock period is (low_duration + high_duration), * and a 50% duty-cycle is obtained when low_duration = high_duration. * * Note: when the total period is 0, it indicates that the clock is * to be managed explicitly by calling bk_trigger_clock_edge(). */ tClock bk_define_clock(tSimStateHdl simHdl, const char* name, tClockValue initial_value, tBool has_initial_value, tTime first_edge, tTime low_duration, tTime high_duration); /* Allow a clock definition to be altered (overridden from the UI, etc.) * * Returns BK_ERROR on error, BK_SUCCESS on success. */ tStatus bk_alter_clock(tSimStateHdl simHdl, tClock handle, tClockValue initial_value, tBool has_initial_value, tTime first_edge, tTime high_duration, tTime low_duration); /* Associate a callback function with an event type for a particular * clock. * * handle - the handle of the clock * on_edge_callback - the function to call when the edge event occurs * after_edge_callback - the function to call after the edge event * dir - direction of the clock edge * * Returns BK_ERROR on error, BK_SUCCESS on success. */ tStatus bk_set_clock_event_fn(tSimStateHdl simHdl, tClock handle, tScheduleFn on_edge_callback, tScheduleFn after_edge_callback, tEdgeDirection dir); /* Trigger a clock edge at a given simulation time. * This function is for use with clocks that have no defined * waveform (ie. high_duration == low_duration == 0). * * Returns BK_ERROR on error, or the number of events scheduled * for the clock edge on success. */ tStatus bk_trigger_clock_edge(tSimStateHdl simHdl, tClock handle, tEdgeDirection dir, tTime at); /* Enqueue an initial clock edge (at time 0). * This function is for use with clocks that have no defined * waveform (ie. high_duration == low_duration == 0). * * Returns BK_ERROR on error, or the number of events scheduled for the * clock edge on success. */ tStatus bk_enqueue_initial_clock_edge(tSimStateHdl simHdl, tClock handle, tEdgeDirection dir); /* Get the clock handle associated with a clock domain name. * * Returns the clock handle for the domain, or BAD_CLOCK_HANDLE * if there is no clock domain with the given name. */ tClock bk_get_clock_by_name(tSimStateHdl simHdl, const char* name); /* If there is already a clock domain with the given name, * return the handle for it. If there is no clock domain with * this name yet, then create one and return the handle of the * new domain. The domain characteristics can be set with * a subsequent call to bk_alter_clock(). */ tClock bk_get_or_define_clock(tSimStateHdl simHdl, const char* name); /* Get the number of clocks defined in the kernel */ tUInt32 bk_num_clocks(tSimStateHdl simHdl); /* Get the clock handle for the nth clock. * * Returns the clock handle on success or BAD_CLOCK_HANDLE on error. */ tClock bk_get_nth_clock(tSimStateHdl simHdl, tUInt32 n); /* Get various information for a clock */ const char* bk_clock_name(tSimStateHdl simHdl, tClock handle); tClockValue bk_clock_initial_value(tSimStateHdl simHdl, tClock handle); tTime bk_clock_first_edge(tSimStateHdl simHdl, tClock handle); tTime bk_clock_duration(tSimStateHdl simHdl, tClock handle, tClockValue value); tClockValue bk_clock_val(tSimStateHdl simHdl, tClock handle); tUInt64 bk_clock_cycle_count(tSimStateHdl simHdl, tClock handle); tUInt64 bk_clock_edge_count(tSimStateHdl simHdl, tClock handle, tEdgeDirection dir); tUInt32 bk_clock_vcd_num(tSimStateHdl simHdl, tClock handle); /* * Setup a default reset waveform (asserted at time 0, deasserted at time 2). * This should be called before the first bk_advance() call. */ void bk_use_default_reset(tSimStateHdl simHdl); /* * Simulation control */ /* Get the current simulation time */ tTime bk_now(tSimStateHdl simHdl); /* Set simulation timescale - reporting scale factor and time unit for VCDs. * * Returns BK_ERROR on error, BK_SUCCESS on success. * * Errors include passing an invalid timescale unit and setting the timescale * after the beginning of the simulation. */ tStatus bk_set_timescale(tSimStateHdl simHdl, const char* scale_unit, tTime scale_factor); /* Test if a given simulation time is still ongoing. * WARNING: This is a specialized function for use by * Bluesim primitives to facilitate connections to * event-driven simulation. FOR EXPERT USE ONLY! */ tBool bk_is_same_time(tSimStateHdl simHdl, tTime t); /* Test if we are currently executing within a combinational * schedule. FOR EXPERT USE ONLY! */ tBool bk_is_combo_sched(tSimStateHdl simHdl); /* Get information on the clock event queue */ tTime bk_clock_last_edge(tSimStateHdl simHdl, tClock handle); tTime bk_clock_combinational_time(tSimStateHdl simHdl, tClock handle); /* Quit simulation at the end of the current time slice. */ void bk_quit_at(tSimStateHdl simHdl, tTime t); /* Quit simulation at the end of the given time slice. * * Returns BK_ERROR on error and BK_SUCCESS on success. */ tStatus bk_quit_after_edge(tSimStateHdl simHdl, tClock handle, tEdgeDirection dir, tUInt64 cycle); /* Execute simulation events until none remain, simulation is * interrupted, or a stopping condition (time limit, etc.) is * encountered. * * When called with an argument of 0, it will not return until * the simulation has completed. When called with a non-zero * argument it will return immediately, and bk_sync() and * bk_is_running() should be used to synchronize with the simulation * thread. * * Returns BK_ERROR on error and BK_SUCCESS on success. */ tStatus bk_advance(tSimStateHdl simHdl, tBool async); /* Test if the simulation thread is still running. * * Returns 0 if the thread is not running and non-zero if * the thread is running. */ tBool bk_is_running(tSimStateHdl simHdl); /* Wait for a simulation started using bk_advance in async mode * to complete. * * Returns the simulation time at which execution stopped. */ tTime bk_sync(tSimStateHdl simHdl); /* Schedule a UI callback for the end of a given timeslice, * unless there is already one scheduled at that time. * * Returns BK_ERROR on error or BK_SUCCESS on success. */ tStatus bk_schedule_ui_event(tSimStateHdl simHdl, tTime at); /* Remove a UI callback previously scheduled at the end of a given timeslice. * * Returns BK_ERROR on error or BK_SUCCESS on success. */ tStatus bk_remove_ui_event(tSimStateHdl simHdl, tTime at); /* * Routines to control debugging functionality. */ void bk_enable_state_dumping(tSimStateHdl simHdl); void bk_disable_state_dumping(tSimStateHdl simHdl); tBool bk_is_state_dumping_enabled(tSimStateHdl simHdl); void bk_dump_state(tSimStateHdl simHdl, const char* label); void bk_enable_cycle_dumping(tSimStateHdl simHdl); void bk_disable_cycle_dumping(tSimStateHdl simHdl); tBool bk_is_cycle_dumping_enabled(tSimStateHdl simHdl); void bk_dump_cycle_counts(tSimStateHdl simHdl, const char* label, tClock handle); tBool bk_enable_VCD_dumping(tSimStateHdl simHdl); void bk_disable_VCD_dumping(tSimStateHdl simHdl); tBool bk_is_VCD_dumping_enabled(tSimStateHdl simHdl); void bk_VCD_combo_update(tSimStateHdl simHdl, tTime t); /* VCD control routines */ tStatus bk_set_VCD_file(tSimStateHdl simHdl, const char* name); const char* bk_get_VCD_file_name(tSimStateHdl simHdl); void bk_set_VCD_depth(tSimStateHdl simHdl, tUInt32 depth); tStatus bk_VCD_checkpoint(tSimStateHdl simHdl); void bk_set_VCD_filesize_limit(tSimStateHdl simHdl, tUInt64 bytes); void bk_flush_VCD_output(tSimStateHdl simHdl); /* Call to enable clock edges without logic (for interactive stepping) */ void bk_set_interactive(tSimStateHdl simHdl); /* * Callbacks to stop simulation within a schedule or model. */ /* Pause the simulation and return to the UI at the end of this * simulation cycle. The status value is made available to * callers of bk_exit_status(). */ void bk_stop_now(tSimStateHdl simHdl, tSInt32 status); /* Abort the simulation and return to the UI at the end of this * simulation cycle. The status value is made available to * callers of bk_exit_status(). */ void bk_finish_now(tSimStateHdl simHdl, tSInt32 status); /* Test if $stop was called. */ tBool bk_stopped(tSimStateHdl simHdl); /* Test if $finish was called. */ tBool bk_finished(tSimStateHdl simHdl); /* Retrieve the status value of the last call to bk_stop_now() * or bk_finish_now(). */ tSInt32 bk_exit_status(tSimStateHdl simHdl); /* * Callbacks to stop simulation from outside a schedule or model. */ /* Abort the simulation and return to the UI at the end of the * current simulation cycle. */ void bk_abort_now(tSimStateHdl simHdl); /* Test if bk_abort_now() was called. */ tBool bk_aborted(tSimStateHdl simHdl); /* * Routines for setting and testing arguments (eg., plusargs). */ /* Add an argument string */ void bk_append_argument(tSimStateHdl simHdl, const char* arg); /* Retrieve the trailing portion of the first matching argument */ const char* bk_match_argument(tSimStateHdl simHdl, const char* name); /* Routine which provides direct access to the top-level model. This * should only be used by callers that know exactly what they are doing. */ void* bk_get_model_instance(tSimStateHdl simHdl); /* * API routines for finding and working with symbols */ /* Get the symbol for the top module. */ tSymbol bk_top_symbol(tSimStateHdl simHdl); /* Lookup a symbol by name. Returns BAD_SYMBOL if the named * symbol is not found. */ tSymbol bk_lookup_symbol(tSymbol root, const char* name); /* Get the key for a symbol */ const char* bk_get_key(tSymbol sym); /* Test if a symbol represents a module */ tBool bk_is_module(tSymbol sym); /* Test if a symbol represents a rule */ tBool bk_is_rule(tSymbol sym); /* Test if a symbol represents a value */ tBool bk_is_single_value(tSymbol sym); /* Test if a symbol represents a range of values */ tBool bk_is_value_range(tSymbol sym); /* Get the size for a symbol (for value and value range symbols) */ tUInt32 bk_get_size(tSymbol sym); /* Get the value for a symbol (as a void*) */ void* bk_get_ptr(tSymbol sym); /* Get a pointer to the value for a value symbol. * Returns NULL for other symbol types. */ const unsigned int* bk_peek_symbol_value(tSymbol sym); /* Get the minimum address for a value range. * Returns NULL for other symbol types. */ tUInt64 bk_get_range_min_addr(tSymbol sym); /* Get the maximum address for a value range. * Returns NULL for other symbol types. */ tUInt64 bk_get_range_max_addr(tSymbol sym); /* Get a pointer to a value selected from a range. * Returns NULL for other symbol types, or if the address is out of bounds. */ const unsigned int* bk_peek_range_value(tSymbol sym, tUInt64 addr); /* Get the number of sub-symbols of a module. * Returns 0 for other symbol types. */ tUInt32 bk_num_symbols(tSymbol sym); /* Get the Nth sub-symbol of a module (starting at 0). * Returns BAD_SYMBOL for other symbol types. */ tSymbol bk_get_nth_symbol(tSymbol sym, tUInt32 n); #if __cplusplus } /* extern "C" */ #endif #endif /* __BLUESIM_KERNEL_H__ */