我试图了解systemc中的事件生成。我发现它取决于构造函数中线程注册的顺序。
#include <systemc.h>
SC_MODULE(EventTest){
sc_event ev1;
void p1(){
ev1.notify();
ev1.notify(0, SC_NS);
}
void p2(){
wait(ev1);
cout<<"ev1 is activated at "<<sc_time_stamp()<<endl;
wait(ev1);
cout<<"ev1-2 is activated at "<<sc_time_stamp()<<endl;
}
SC_CTOR(EventTest){
SC_THREAD(p1);
SC_THREAD(p2);
}
};
int sc_main(int argc, char *argv[]){
EventTest d("d");
sc_start();
return 1;
}
输出:ev1 is activated at 0 s
如果我将SC_CTOR
更改为&gt;
SC_THREAD(p2);
SC_THREAD(p1);
然后输出是&gt;
ev1 is activated at 0 s
ev1-2 is activated at 0 s
请有人告诉注册顺序如何影响事件生成?
答案 0 :(得分:2)
您的代码由两个SystemC进程(SystemC线程或方法称为进程)组成,它们都是SystemC线程:p1
和p2
。它们将在模拟的第一个增量循环期间执行。但是,SystemC标准无法保证同一增量周期中进程的运行顺序。
如果先执行p1
,则会对事件ev1
执行不定时通知。见IEEE Std 1666-2011的5.10.6部分。
使用空参数列表调用成员函数notify应立即创建通知。在从函数notify返回控制之前,对事件敏感的任何和所有流程实例都应该是可运行的,但当前正在执行的流程实例除外,由于无论其静态或动态灵敏度如何立即通知,该流程实例都不能运行。 / p>
然而,没有什么可以等待这个事件。通知什么都不做。
然后p1
执行定时通知。在那种情况下,行为是
不同:
使用表示非零时间的参数调用函数notify将在给定时间创建定时通知,相对于调用函数通知时的模拟时间表示。换句话说,时间参数的值被添加到当前模拟时间以确定将通知事件的时间。时间论证不应是否定的。 注 - 在增量通知的情况下,在增量通知阶段对事件敏感的所有进程将在后续评估阶段运行。在定时通知的情况下,在事件发生时对事件敏感的所有过程将在此时运行,这将是未来的模拟时间。
最后,流程p1
结束,p2
被执行。第一个wait
将暂停该过程。然后传播该事件的待处理通知,并将解锁进程p2
。然后,流程p2
将执行第二个wait
并再次暂停。由于没有任何东西可以通知事件,模拟将结束。
如果先执行p2
,它将暂停在第一个wait
上。然后,p1
将被执行。它会做第一次通知。当p2
正在等待通知时,p1
将被暂停(立即通知),p2
将继续并继续前进至第二个wait
。 p2
被暂停。然后,p1
继续。它执行定时通知,并且过程结束。当p2
正在等待通知并且它发生时,p2
执行继续并且该过程结束。模拟也结束了。
最后,在您的两种情况下,p1
始终在p2
之后执行您使用的SystemC实现。使用SystemC的另一个实现,可能是相反的。您应该考虑在相同的模拟时间并行执行它们。在这种情况下,两个订单都是正确的。
最后,这意味着您的代码可能会导致非确定性行为。
答案 1 :(得分:0)
您可以添加到下面的代码打印:
6 void p1(){
7 cout << "P1 is run" << endl;
8 ev1.notify();
9 ev1.notify(0, SC_NS);
10 cout << "P1 is end" << endl;
11 }
12
13 void p2(){
14 cout << "P2 is run" << endl;
15 wait(ev1);
16 cout<<"ev1 is activated at "<<sc_time_stamp()<<endl;
17 wait(ev1);
18 cout<<"ev1-2 is activated at "<<sc_time_stamp()<<endl;
19 cout << "P2 is end" << endl;
20 }
IEEE Standard for Standard SystemC® Language Reference Manual 说:“当一个方法进程被触发时,相关的函数会从头到尾执行,然后 将控制权返回给内核。”
如果先触发 p1,则立即通知 ev1
没有结果,然后在 0 NS 后通知 ev1
。然后触发 p2 仅产生 ev1 is activated at 0 s
:
P1 is run
P1 is end
P2 is run
ev1 is activated at 0 s
如果先触发p2,则等待ev1
,然后触发p1。立即通知 ev1
结果为 ev1 is activated at 0 s
。 ev1
在导致 ev1-2 is activated at 0 s
的 0 NS 后收到通知:
P2 is run
P1 is run
P1 is end
ev1 is activated at 0 s
ev1-2 is activated at 0 s
P2 is end