#include #include "utils.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 { SC_HAS_PROCESS(mod_method); 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 { SC_HAS_PROCESS(mod_thread); 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; }