本文为英文版本翻译,原文地址:Simulation Process
Simulation Process
称为仿真过程,其有以下特性:
A simulation process:
- 是systemc模型类(继承sc_module的类)的成员函数
- 没有输入参数,也没有返回值
- 需要注册到仿真内核
注册仿真过程
使用以下方法注册仿真过程:
- SC_METHOD(func): 没有自己的执行线程,不消耗仿真时间,不能挂起,不能执行wait操作(包括一些内部调用wait的函数等)
- SC_THREAD(func): 有自己的执行线程,可能消耗仿真时间,可以挂起,可以执行wait操作
- SC_CTHREAD(func, event): SC_THREAD的特殊形式,只可以有一个时钟沿静态敏感事件
什么时候注册
When can registration happen:
- 构造函数中
- 在模型类的回调函数
before_end_of_elaboration
或end_of_elaboration
中 - 构造函数中调用的其他成员函数或回调函数中
一些限制
Restrictions:
- 只可以注册当前模型中的成员函数
- 不能在
end_of_elaboration
中使用SC_CTHREAD
其他
SC_THREAD
可以实现SC_METHOD
和SC_CHTEAD
一样的操作。接下来的示例中大多会使用SC_THREAD
SC_THREAD
和SC_CTHREAD
中需要while循环操作,以使其持续执行而不退出SC_METHOD
不需要while循环,它会通过next_trigger
再次执行(注:原文中为SC_THREAD,猜测可能是笔误?)
- systemC中的仿真时间并非程序运行的实际时间,其本质是仿真内核管理的一个计数器(后文进一步介绍)
// Learn with Examples, 2020, MIT license
#include <systemc>
using namespace sc_core;
SC_MODULE(PROCESS) {
sc_clock clk; // 声明一个时钟
SC_CTOR(PROCESS) : clk("clk", 1, SC_SEC) { // 实例化为周期为1秒的时钟
SC_METHOD(method); // 注册method
SC_THREAD(thread); // 注册thread
SC_CTHREAD(cthread, clk); // 注册clocked thread
}
void method(void) { // define the method member function
// no while loop here
std::cout << "method triggered @ " << sc_time_stamp() << std::endl;
next_trigger(sc_time(1, SC_SEC)); // trigger after 1 sec
}
void thread() { // define the thread member function
while (true) { // 无限循环以使其不会退出
std::cout << "thread triggered @ " << sc_time_stamp() << std::endl;
wait(1, SC_SEC); // 等待1秒(注意是仿真时间)
}
}
void cthread() { // define the cthread member function
while (true) { // infinite loop
std::cout << "cthread triggered @ " << sc_time_stamp() << std::endl;
wait(); // 等待下一个时钟事件(前面实例化的时钟,周期1秒)
}
}
};
int sc_main(int, char*[]) {
PROCESS process("process"); // init module
std::cout << "execution phase begins @ " << sc_time_stamp() << std::endl;
sc_start(2, SC_SEC); // 仿真2秒(注意是仿真时间,并非程序需要运行2秒)
std::cout << "execution phase ends @ " << sc_time_stamp() << std::endl;
return 0;
}
运行结果:
execution phase begins @ 0 s
// 模型实例化,所有的仿真过程触发一次
method triggered @ 0 s
thread triggered @ 0 s
cthread triggered @ 0 s
// 1秒后再次触发(分别使用不同的方法:next_trigger,wait(1, SC_SEC),wait())
method triggered @ 1 s
thread triggered @ 1 s
cthread triggered @ 1 s
// 2秒后仿真结束
execution phase ends @ 2 s