aboutsummaryrefslogtreecommitdiff
path: root/src/event.cc
blob: 96750bc850a8a496033707b052a2109ea3540bee (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <systemc>
#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;
}