之前的博客中有提到过,SC_METHOD在同一拍只能被执行一次,其实这句话成立需要加一个前提,就是在没有Next_trigger参与的情况下。有next_trigger参与的情况下,SC_METHOD是可以在同一拍被执行两次的,且只能是被静态敏感事件触发一次,被动态敏感事件触发一次。
Next_trigger 只能在SC_METHOD函数中使用,不能在SC_THREAD和SC_CTHREAD中使用。
Next_trigger(sc_event &)用于添加动态敏感事件,表示这个method下一次被执行必须是由这个next trigger的 event来触发,静态敏感列表中的事件 暂时被被掩盖。
执行Next_trigger(sc_event & )语句,不会跳出本次method的执行,也就是会继续执行本语句之后的命令。
Next_trigger(sc_event & )添加动态敏感事件 只对下一次method触发有影响,动态敏感事件在成功触发执行一次method之后就失效了,同时静态敏感列表的事件被重新激活。
Next_trigger的参数除了sc_event,还可以是sc_time、sc_event_list,以下形式都是可以的。
next_trigger(sc_time(5,SC_NS));// 5ns之后执行method
next_trigger(sc_time(5,SC_NS), sc_event ); // 5ns之后 或者 事件被触发,都会去执行method,执行一次之后,这个next_trigger就完成使命,即使另一个条件满足也不会再次去执行一次method。
next_trigger(sc_event_1 | sc_event_2 ); //同sc_event_list,任意事件触发,都会去执行method。同上,执行一次之后,这个next_trigger就完成使命。
一次method的执行过程中,如果遇到多次next_trigger,以最后一次的next_trigger语句为准,前面的next_trigger语句作废。
Next_trigger如果不加参数,表示cancle掉下一次的所有动态敏感事件,下一次method执行需要 静态事件来触发。
以下源代码主要展示以上叙述中的其中4个注意点,编译时,需要增加-D TEST_NEXT_TRIGGER_NOTE_1或_2 或_3 的宏定义,如果想看note4的效果,删除宏开关。
/*
Original 2020-03-31
README:
This is a example can teach you how to use next_trigger in SC_METHOD
execute:
g++ -g -Wall -D TEST_NEXT_TRIGGER_NOTE_1 (or others macro)
-lsystemc -m64 -pthread main.cpp -L/$(your systemc path)/lib-linux64
-I/$(your systemc path)/include -I/$(your systemc path)/src/tlm_utils -o sim
NOTE :
1. a SC_METHOD process can execute two times in one T,
only triggered by static sensitive event one time, and by dynamic sensitive event one time
2. if next_trigger have two or more dynamic sensitive event,
each one of them will trigger the SC_METHOD process, and then the others will lose effect after
SC_METHO execute
3. if there are two or more next_trigger() when SC_METHOD execute,
the new one will override all the old event
4. if next_trigger() have no parameter, will cancle the dynamic sensitive event
*/
#include <iostream>
#include <fstream>
#include "systemc.h"
using namespace std;
class TestPlatform
: public sc_module
{
public:
SC_HAS_PROCESS(TestPlatform);
TestPlatform(const sc_module_name& name)
: sc_module(name)
,m_period (sc_time(1000,SC_PS))
,m_method_execute_cnt(0)
{
SC_METHOD(TestMethod);
sensitive << m_event ; // static sensitive event
dont_initialize();
#ifdef TEST_NEXT_TRIGGER_NOTE_1
SC_METHOD(TestMethod2);
sensitive << m_event_2 ;
dont_initialize();
#else
SC_THREAD(NotifyNxtEvtThread);
#endif
SC_THREAD(StartNotifyEvtThread);
};
public:
void TestMethod();
void TestMethod2();
void StartNotifyEvtThread();
void NotifyNxtEvtThread();
~TestPlatform(){;}
public:
sc_time m_period;
sc_event m_event;
sc_event m_event_2;
sc_event m_next_event;
sc_event m_next_event_4;
int m_method_execute_cnt;
};
void TestPlatform::TestMethod()
{
#ifdef TEST_NEXT_TRIGGER_NOTE_1
m_method_execute_cnt ++;
m_event_2.notify(SC_ZERO_TIME);
if(m_method_execute_cnt % 2 == 0)
{
cout<<" ["<<sc_time_stamp()<<" ] method execute one time, "
<< "add dynamic sensitive next_event "
<<endl;
next_trigger(m_next_event); // dynamic sensitive event
}
else
{
cout<<" ["<<sc_time_stamp()<<" ] method execute one time, "
<< "no dynamic sensitive "
<<endl;
}
#elif TEST_NEXT_TRIGGER_NOTE_2
cout<<" ["<<sc_time_stamp()<<" ] method execute one time (note 2)"<<endl;
next_trigger(3*m_period, m_next_event_4 );
#elif TEST_NEXT_TRIGGER_NOTE_3
cout<<" ["<<sc_time_stamp()<<" ] method execute one time (note 3)"<<endl;
next_trigger(3*m_period);
next_trigger( m_next_event_4);
#else
cout<<" ["<<sc_time_stamp()<<" ] method execute one time (note 4)"<<endl;
next_trigger(3*m_period, m_next_event_4);
next_trigger();
#endif
}
void TestPlatform::TestMethod2()
{
cout<<" ["<<sc_time_stamp()<<" ]"
<< " method 2, notify next_event "
<<endl;
m_next_event.notify();
}
void TestPlatform::StartNotifyEvtThread()
{
while(1)
{
wait(10 *m_period);
m_event.notify();
cout<<" ["<<sc_time_stamp()<<" ]"<< " notify event "<<endl;
}
}
void TestPlatform::NotifyNxtEvtThread()
{
wait(12,SC_NS);
cout<<" ["<<sc_time_stamp()<<" ]"<< " notify m_next_event_4 "<<endl;
m_next_event_4.notify();
wait(4 * m_period);
m_next_event_4.notify();
cout<<" ["<<sc_time_stamp()<<" ]"<< " notify m_next_event_4 "<<endl;
}
int main(int argc, char** argv)
{
TestPlatform * m_platform;
m_platform = new TestPlatform("TestPlatform");
sc_start(40,SC_NS);
return 0;
}
note 1的显示结果
note 2的显示结果
note 3的显示结果
note 4的显示结果