1、Processes 进程
SystemC simulation processes are simply C++ functions designated by the programmer to be used as processes. You simply tell the simulation kernel which functions are to be used as simulation processes. The action is known as process registration(进程注册). The simulation kernel then schedules and calls each of these functions as needed.
---- SC_METHOD(a_method);
Execute its body from the beginning to the end. Invoked multiple times, Can not be suspended.
---- SC_THREAD(b_method);
Invoked only once, can be suspended using wait(). Systemc thread simulation processes typically begin execution at the start of simulation and continue in an endless loop until the simulation ends.
Thread processes are started once; if they terminate, they cannot be restarted.
Thread processes are required to periodically return control to (释放控制权给仿真内核)the simulation kernel, allowing other processes to run.
A thread process returns control to the simulation kernel by executing a wait() method call specifying an event or a time-out. Each time a thread returns control to the simulation kernel, its execution state is saved, which lets the process be resumed when the wait() returns.
---- SC_THREAD has a few restrictions:
>> It can be used only within a SystemC module, hence the function must be a member function (成员函数) of the module class.
>> It must be used only during the elaboration stage, and placing SC_THREAD in the module's constructor meets this requirement.
>> The member function must exist and the function can take no arguments and return no values.(无参数,无返回值)
---- Processes must voluntarily(自愿的) yield control. Yielding control may take one of two forms:
>> Simulation processes yield control by executing a return. For the processes registered with SC_THREAD, executing return is uninteresting (无趣的,无意义的) because it means the process has ended permanently(永久的).
>> The other form is calling SystemC's wait() function. The wait() function suspends the process temporarily while SystemC proceeds to execute other processes, and then the function resumes by returning.
2、Events and Notification:triggering events 时间触发和通知
---- Event-driven simulator
---- Happens at a specific instant in time 特定时间点
---- Has no value and no duration 没有持续时间,没有值
====================================================
---- Immediate notification
sc_event a_event;
a_event.notify();
---- Delayed notification: next cycle
sc_event b_event;
b_event.notify(SC_ZERO_TIME);
---- Timed notification
sc_event c_event;
c_event.notify(10,SC_NS);
c_event.notify(5,SC_NS);
====================================================
----- Event queue: Multiple events
---- sc_event_queue action; no immediate notification
----- Sensitivity:敏感列表,Catching events for processes
---- Static Sensitivity
//must follow process registration
sensitive << event1 [<< event2]...;
---- Dynamic Sensitivity
SC_METHOD():next_trigger()
SC_THREAD():wait()
next_trigger(time); //经过多少时间再次触发
next_trigger(event1); //event1事件发生时触发
next_trigger(event1 & event2); //event1事件和event2事件都发生时触发
wait(10,SC_NS); //can suspend,10ns后继续执行
3、Examples 1
#include <systemc.h>
SC_MODULE(turn_of_event){
SC_CTOR(turn_of_event){
SC_THREAD(turn_knob_thread); //steering dirction
SC_THREAD(turn_signal_on_thread);//signal light on
SC_THREAD(turn_signal_off_thread);//signal light off
SC_THREAD(turn_signal_right_thread);//signal light right
SC_THREAD(turn_signal_left_thread);//signal light left
signal = false;
}
sc_core::sc_event signal_on,signal_off,signal_right,signal_left;
sc_core::sc_event knob_right,knob_left;
void turn_knob_thread(void);
void turn_signal_on_thread(void);
void turn_signal_off_thread(void);
void turn_signal_right_thread(void);
void turn_signal_left_thread(void);
bool signal;
};
turn_of_event.cpp
#include "turn_of_event.h"
#include <iostream>
using namespace sc_core;
using namespace std;
//多个线程不可改同一个全局变量,除非用volatile
void turn_of_event::turn_knob_thread(){
enum cmds {right = 'R',left = 'L'};
char cmd;
wait(SC_ZERO_TIME);
for(;;){
std::cout<<"turn knob cmds['R'/'L']\n";
cin >> cmd;
switch(cmd){
case 'R':
{
if(!signal)
{
signal = true;
signal_on.notify();
}
knob_right.notify(SC_ZERO_TIME);
wait(signal_right);
cout<<"the right light is blinking!\n";
break;
}
case 'L':
{
if(!signal){
signal = true;
signal_on.notify();
}
knob_left.notify(SC_ZERO_TIME);
wait(signal_left);
cout<<"the left light is blinking!\n";
break;
}
default:
if(signal)
signal_off.notify();
else
cout<<"signal already off!"<<endl;
wait(SC_ZERO_TIME);
signal = false;
break;
}
}
}
void turn_of_event::turn_signal_on_thread(void){
while(1){
wait(signal_on);
cout<<"signal oning!!\n";
}
}
void turn_of_event::turn_signal_off_thread(void){
while(1)
{
wait(signal_off);
cout<<"signal offing!!\n";
}
}
void turn_of_event::turn_signal_right_thread(void){
while(1){
wait(knob_right);
cout<<"knob right event is triggered!"<<endl;
signal_right.notify(SC_ZERO_TIME);
}
}
void turn_of_event::turn_signal_left_thread(void){
while(1){
wait(knob_left);
cout<<"knob left event is triggered!"<<endl;
signal_left.notify(SC_ZERO_TIME);
}
}
int sc_main(int sc_argc,char * argv[])
{
turn_of_event turn_event("");
sc_start(60,SC_NS);
system("pause");
return 0;
}
运行后结果:
4、Examples 2
turn_of_event.h volatile可有,可无
#include <systemc.h>
SC_MODULE(turn_of_event){
SC_CTOR(turn_of_event){
SC_THREAD(turn_knob_thread); //steering dirction
SC_THREAD(turn_signal_on_thread);//signal light on
SC_THREAD(turn_signal_off_thread);//signal light off
SC_THREAD(turn_signal_right_thread);//signal light right
SC_THREAD(turn_signal_left_thread);//signal light left
signal = false;
}
sc_core::sc_event signal_on,signal_off,signal_right,signal_left;
sc_core::sc_event knob_right,knob_left;
void turn_knob_thread(void);
void turn_signal_on_thread(void);
void turn_signal_off_thread(void);
void turn_signal_right_thread(void);
void turn_signal_left_thread(void);
volatile bool signal;//this variable is volatile,so read from memory
};
turn_of_event.cpp
#include "turn_of_event.h"
#include <iostream>
using namespace sc_core;
using namespace std;
//多个线程不可改同一个全局变量
void turn_of_event::turn_knob_thread(){
enum cmds {right = 'R',left = 'L'};
char cmd;
wait(SC_ZERO_TIME);
for(;;){
std::cout<<"turn knob cmds['R'/'L']\n";
cin >> cmd;
switch(cmd){
case 'R':
{
if(!signal)
{
signal_on.notify();
}
wait(SC_ZERO_TIME);
while(!signal);
knob_right.notify(SC_ZERO_TIME);
wait(signal_right);
cout<<"the right light is blinking!\n";
break;
}
case 'L':
{
if(!signal){
signal_on.notify();
}
wait(SC_ZERO_TIME);
while(!signal);
knob_left.notify(SC_ZERO_TIME);
wait(signal_left);
cout<<"the left light is blinking!\n";
break;
}
default:
if(signal)
signal_off.notify();
else
cout<<"signal already off!"<<endl;
wait(SC_ZERO_TIME);
while(signal);
break;
}
}
}
void turn_of_event::turn_signal_on_thread(void){
while(1){
wait(signal_on);
signal = true;
cout<<"signal oning!!\n";
}
}
void turn_of_event::turn_signal_off_thread(void){
while(1)
{
wait(signal_off);
signal = false;
cout<<"signal offing!!\n";
}
}
void turn_of_event::turn_signal_right_thread(void){
while(1){
wait(knob_right);
cout<<"knob right event is triggered!"<<endl;
signal_right.notify(SC_ZERO_TIME);
}
}
void turn_of_event::turn_signal_left_thread(void){
while(1){
wait(knob_left);
cout<<"knob left event is triggered!"<<endl;
signal_left.notify(SC_ZERO_TIME);
}
}
int sc_main(int sc_argc,char * argv[])
{
turn_of_event turn_event("");
sc_start(60,SC_NS);
system("pause");
return 0;
}
运行后: