#include <systemc>
#include "utils/log.h"
using sc_core::sc_event;
using sc_core::sc_module;
using sc_core::sc_module_name;
using sc_core::SC_NS;
using sc_core::sc_start;
using sc_core::sc_time;
using sc_core::SC_ZERO_TIME;
// -- MOD_METHOD ---------------------------------------------------------------
struct mod_method : public sc_module {
explicit mod_method(sc_module_name nm) : sc_module(nm) {
SC_METHOD(ev_method);
// STATIC sensitivity for ev_method, the METHOD will become RUNNABLE when
// the event is notified.
sensitive << m_method_event;
// DONT run method initially at time 0s, only after it is triggered.
// By default SC_METHODs are made RUNNABLE at time 0s.
dont_initialize();
// Helper to drive the method example.
SC_THREAD(run_method);
}
private:
sc_event m_method_event;
void ev_method() {
// No calls to wait() in METHODS.
// Methods are triggered by static sensitivity or dynamic sensitivity.
CLOGM(GREEN, "triggered by_static_event_not_next_trigger=%d timed_out=%d",
m_method_event.triggered(), timed_out());
if (m_method_event.triggered()) {
// Create DYNAMIC sensitivity list, either by time or event.
// The DYNAMIC sensitivity OVERRIDES the STATIC sensitivity, therefore if
// the event is not listed here, the method will only be triggered by the
// TIME value no matter if the EVENT (static sensitivity) is triggered.
next_trigger(5000, SC_NS, m_method_event);
}
}
void run_method() {
// Notify event in the future.
CLOGM(YELLOW, "TIMED NOTIFY");
m_method_event.notify(100, SC_NS);
wait(200, SC_NS);
// Notify event in the next delta cycle.
CLOGM(YELLOW, "DELTA NOTIFY");
m_method_event.notify(SC_ZERO_TIME);
wait(200, SC_NS);
// Notify event in the current delta cycle.
CLOGM(YELLOW, "IMMEDIATE NOTIFY");
m_method_event.notify();
wait(200, SC_NS);
}
};
// -- MOD_THREAD ---------------------------------------------------------------
struct mod_thread : public sc_module {
explicit mod_thread(sc_module_name nm) : sc_module(nm) {
SC_THREAD(ev_thread);
// STATIC sensitivity for ev_thread.
sensitive << m_thread_event;
// Helper to drive the example and drive the simulator.
SC_THREAD(run_thread);
}
private:
sc_event m_thread_event;
void ev_thread() {
// WAIT on STATIC sensitivity event.
wait();
while (true) {
CLOGM(CYAN, "WAIT TIMED or EVENT");
// Create DYNAMIC sensitivity list, WAIT on either TIMEOUT or EVENT.
wait(sc_time(2000, SC_NS), m_thread_event);
CLOGM(CYAN, "done by_event_not_time=%d timed_out=%d",
m_thread_event.triggered(), timed_out());
CLOGM(CYAN, "WAIT STATIC SENSITIVITY");
// WAIT on static sensitivity trigger.
wait();
CLOGM(CYAN, "done");
}
}
void run_thread() {
// Some initial wait, to run at different time than the method example.
wait(10000, SC_NS);
m_thread_event.notify(SC_ZERO_TIME);
CLOGM(MAGENTA, "big TIMED WAIT -> should timeout thread");
wait(10000, SC_NS);
CLOGM(MAGENTA, "TIMED NOTIFY");
m_thread_event.notify(100, SC_NS);
wait(1000, SC_NS);
CLOGM(MAGENTA, "TIMED NOTIFY");
m_thread_event.notify(200, SC_NS);
wait(1000, SC_NS);
CLOGM(MAGENTA, "DELTA NOTIFY");
m_thread_event.notify(SC_ZERO_TIME);
}
};
// -- SC_MAIN ------------------------------------------------------------------
extern "C" int sc_main(int, char*[]) {
// timed_out() is deprecated, but it is just used for visualization here.
sc_core::sc_report_handler::set_actions("/IEEE_Std_1666/deprecated",
sc_core::SC_DO_NOTHING);
mod_method method("method");
mod_thread thread("thread");
sc_start();
return 0;
}