systemc: next_trigger在SC_METHOD中的用法

之前的博客中有提到过,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的显示结果
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

123axj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值