systemc 中的事件生成

Event generation in 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 中的更改为 >

SC_THREAD(p2);
 SC_THREAD(p1);

那么输出是>

ev1 is activated at 0 s
ev1-2 is activated at 0 s

请问注册顺序对事件生成有何影响?

您的代码由两个SystemC进程(SystemC线程或方法称为进程)组成,它们都是SystemC线程:p1p2。它们都将在模拟的第一个增量循环期间执行。但是,SystemC 标准无法保证同一增量循环中进程的 运行 顺序。

  • 如果先执行p1,它会对事件ev1做一个不定时的通知。参见 IEEE Std 1666-2011.

    的 5.10.6 部分

    A call to member function notify with an empty argument list shall create an immediate notification. Any and all process instances sensitive to the event shall be made runnable before control is returned from function notify, with the exception of the currently executing process instance, which shall not be made runnable due to an immediate notification regardless of its static or dynamic sensitivity

    然而,没有什么是等待事件的。通知什么都不做。 然后 p1 做一个定时通知。在这种情况下,行为是 不同:

    A call to function notify with an argument that represents a non-zero time shall create a timed notification at the given time, expressed relative to the simulation time when function notify is called. In other words, the value of the time argument is added to the current simulation time to determine the time at which the event will be notified. The time argument shall not be negative. NOTE—In the case of a delta notification, all processes that are sensitive to the event in the delta notification phase will be made runnable in the subsequent evaluation phase. In the case of a timed notification, all processes sensitive to the event at the time the event occurs will be made runnable at the time, which will be a future simulation time.

    最后,进程p1结束并执行p2。第一个 wait 将暂停进程。然后传播事件的未决通知并将解锁进程 p2。然后,进程p2将执行第二个wait并再次挂起。由于没有任何事件通知,模拟将结束。

  • 如果先执行p2,会在第一个wait处挂起。然后,p1 将被执行。它会做第一个通知。由于 p2 正在等待通知,p1 将被暂停(立即通知)并且 p2 将继续并继续前进直到第二个 waitp2 已暂停。然后,p1继续。它执行定时通知并且流程结束。由于 p2 正在等待通知并且它发生了,p2 执行继续并且进程结束。模拟也结束了

最后,在您的两种情况下,使用您使用的 SystemC 实现,p1 总是在 p2 之后执行。对于 SystemC 的另一个实现,情况可能相反。您应该考虑它们是在同一模拟时间并行执行的。在那种情况下,两个命令都是正确的。

最后,这意味着您的代码可能会导致非确定性行为。

您可以在下面的代码中添加打印:

  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 说:“当一个方法过程被触发时,关联的函数从头到尾执行,然后 returns 控制内核。"

如果先触发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 在 0 NS 后通知 ev1-2 is activated at 0 s:

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