SystemC 05 Simulation Process
A simulation process
- is a member function of a
sc_module
class, and - has no input argument and returns no value, and
- is registered with the simulation kernel
How to register a simulation process
-
SC_METHOD(func)
: does not have its own thread of execution, consumes no simulated time, cannot be suspended, and cannot call code that calls wait() -
SC_THREAD(func)
: has its own thread of execution, may consume simulated time, can be suspended, and can call code that calls wait() -
SC_CTHREAD(func, event)
: a special form ofSC_THREAD
that can only have a static sensitivity of a clock edge event
When can registration happen
- in the body of the constructor,
- in the before_end_of_elaboration or end_of_elaboration callbacks of a module,
- or in a member function called from the constructor or callback
Restrictions on the process registration
- registration can only be performed on member functions of the same module.
-
SC_CTHREAD
shall not be invoked from the end_of_elaboration callback.
SC_THREAD vs SC_CTHREAD vs SC_METHOD
-
SC_THREAD
can do everything thatSC_METHOD
orSC_CTHREAD
does. I’ll mostly use this process in the examples. - In order for an
SC_THREAD
orSC_CTHREAD
process to be called again, there shall be a while loop making sure it never exits. - An
SC_METHOD
process doesn’t require a while loop. It is invoked again bynext_trigger()
- simulated time in systemC is not the actual time a program runs. It’s a counter managed by the simulation kernel. To be explained later
Top level SC_MODULE structure and its implementation
Code
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
// Learn with Examples, 2020, MIT license
#include <systemc>
using namespace sc_core;
SC_MODULE(PROCESS) {
sc_clock clk; // declares a clock
SC_CTOR(PROCESS) : clk("clk", 1, SC_SEC) { // instantiate a clock with 1sec periodicity
SC_METHOD(method); // register a method
SC_THREAD(thread); // register a thread
SC_CTHREAD(cthread, clk); // register a clocked thread
}
void method(void) { // define the method member function
// no while loop here
std::cout << "method triggered @ " << sc_time_stamp() << std::endl;
next_trigger(sc_time(1, SC_SEC)); // trigger after 1 sec
}
void thread() { // define the thread member function
while (true) { // infinite loop make sure it never exits
std::cout << "thread triggered @ " << sc_time_stamp() << std::endl;
wait(1, SC_SEC); // wait 1 sec before execute again
}
}
void cthread() { // define the cthread member function
while (true) { // infinite loop
std::cout << "cthread triggered @ " << sc_time_stamp() << std::endl;
wait(); // wait for next clk event, which comes after 1 sec
}
}
};
int sc_main(int, char*[]) {
PROCESS process("process"); // init module
std::cout << "execution phase begins @ " << sc_time_stamp() << std::endl;
sc_start(2, SC_SEC); // run simulation for 2 second
std::cout << "execution phase ends @ " << sc_time_stamp() << std::endl;
return 0;
}
// Result
//module instantiation finished
execution phase begins @ 0 s
//all processes are triggered once
method triggered @ 0 s
thread triggered @ 0 s
cthread triggered @ 0 s
//all processes are triggered again after 1 sec, using different methods
method triggered @ 1 s
thread triggered @ 1 s
cthread triggered @ 1 s
//simulation ends after 2 seconds
execution phase ends @ 2 s