systemc 模块等待来自外部/异步线程的事件
实现systemc模块等待来自外部/异步线程的事件
即:systemc模块等待外部指令,保持活动状态,并在需要时完成指令。
这是例子:
#include <systemc.h>
#include <pthread.h>
#include <unistd.h>
using namespace std;
class ThreadSafeEventIf : public sc_interface {
virtual void notify(sc_time delay = SC_ZERO_TIME) = 0;
virtual const sc_event &default_event(void) const = 0;
protected:
virtual void update(void) = 0;
};
class ThreadSafeEvent : public sc_prim_channel, public ThreadSafeEventIf {
public:
ThreadSafeEvent(const char *name = ""): event(name) {}
void notify(sc_time delay = SC_ZERO_TIME) {
this->delay = delay;
async_request_update();
}
const sc_event &default_event(void) const {
return event;
}
protected:
virtual void update(void) {
event.notify(delay);
}
sc_event event;
sc_time delay;
};
sc_event GenScEvent;
sc_event workingFinishEvent; // finish event
int workingFlag = 0; // maybe dnot need a lock
SC_MODULE(Foo) {
public:
SC_CTOR(Foo) {
SC_THREAD(main);
SC_METHOD(eventTriggered);
sensitive << threadSafeEvent;
dont_initialize();
}
private:
void main() { //extra forever thread to avoid simulation exit
while (1) {
usleep(1*1000*1000); // check if there is any instruction every one sec.
wait(SC_ZERO_TIME);
if(workingFlag){ // check working
wait(workingFinishEvent); // wait the working finish
}
usleep(1*1000*1000);
}
}
void eventTriggered() {
// printf("Foo: Got event from pthread \n");
GenScEvent.notify();
}
public:
ThreadSafeEvent threadSafeEvent;
};
void* PollingThread(void* arg) {
int cnt = 0;
while (1) {
cnt++;
printf("[POLL]: %d: Before generating event from PollingThread \n", cnt);
usleep(3*1000*1000);
Foo *foo = (Foo*)(arg);
foo->threadSafeEvent.notify();
printf("[POLL]: %d: Event notified from PollingThread \n", cnt);
}
};
class sc_top : public sc_module {
private:
SC_HAS_PROCESS(sc_top);
public:
sc_top(sc_module_name name="SCTOP"): sc_module(name) {
SC_THREAD(processing_thread);
}
void processing_thread();
};
void sc_top::processing_thread() {
int cnt =0;
while (1) {
printf("[PROC]: processing_thread called \n");
cout << "[PROC]: Wait GenScEvent time: " << sc_time_stamp();
wait(GenScEvent);
workingFlag = 1;
cnt++;
wait(10, SC_SEC); // advance simulation time
cout << "[PROC]: Got and Finish "<<cnt << " GenScEvent time: " << sc_time_stamp();
workingFinishEvent.notify();
workingFlag = 0;
}
}
int sc_main(int argc, char *argv[]) {
Foo foo("foo");
sc_top u_sc_top("u_sc_top");
pthread_t thread;
pthread_create(&thread, NULL, PollingThread, &foo);
sc_start();
return 0;
}