systemc中的事件生成

时间:2017-08-21 09:28:02

标签: systemc

我试图了解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

请有人告诉注册顺序如何影响事件生成?

2 个答案:

答案 0 :(得分:2)

您的代码由两个SystemC进程(SystemC线程或方法称为进程)组成,它们都是SystemC线程:p1p2。它们将在模拟的第一个增量循环期间执行。但是,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将继续并继续前进至第二个waitp2被暂停。然后,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 sev1 在导致 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