简述
波形在Simulation/Emulation中地位十分重要,尤其是在研发初期,只能通过波形来查看软件hang住的位置。
对于TLM来说,查看波形一般是指查看pvbus上的transaction,而对于SystemC本身来说,查看波形就是使用Gtkwave或其他EDA工具,查看Module的input/output的时序输入/输出,其本质和硬件设计的Verilog/VHDL的波形基本一样。
工具准备
我在MacOS下使用的是GtkWave来查看生成的波形,systemc里一般使用vcd文件来记录波形。
GtkWave在MacOS下的安装非常简单,直接brew即可:
brew install gtkwave
测试代码
代码准备
下面代码的主体实际是gpt生成的,主要修改了一些编译的bug。
整个代码逻辑非常简单,就是一个timer模块,输入是1ns周期的clk,输出是根据clk,每15ns为一个周期,高电平输出5ns,低电平输出15ns。
具体的代码含义已经在注释中,不再赘述。
sc_create_vcd_trace_file是用于抓取信号vcd波形的接口。
#include <systemc.h>
SC_MODULE(timer)
{
sc_in_clk clk; // 输入时钟信号
sc_out<bool> pulse; // 输出脉冲信号
SC_CTOR(timer)
{
// 在时钟上升沿触发的进程
SC_THREAD(process);
sensitive << clk.pos();
}
// 进程定义
void process()
{
while(true) {
pulse.write(true); // 输出高电平
wait(5, SC_NS); // 等待5ns(即1个clk周期)
pulse.write(false); // 输出低电平
wait(10, SC_NS); // 等待10ns(即1个clk周期)
}
}
};
int sc_main(int argc, char *argv[])
{
sc_clock clk("clk", 1, SC_NS); // 创建1ns周期的时钟信号
timer t("timer"); // 创建timer模块实例
sc_buffer<bool> pulse_out;
// 将时钟信号连接到timer模块
t.clk(clk);
// 将pulse_out信号连接到timer模块
t.pulse(pulse_out);
// 输出脉冲信号绑定到名为"pulse"的终端
sc_trace_file *tf = sc_create_vcd_trace_file("timer");
sc_trace(tf, t.clk, "clk");
sc_trace(tf, t.pulse, "pulse");
// 开始仿真
sc_start(50 * 10, SC_NS); // 仿真50*10个clk周期
// 关闭波形文件
sc_close_vcd_trace_file(tf);
return 0;
}
编译执行
如下,按照正常的编译执行:
执行完.x文件后,目录下生成了一个vcd文件。
查看波形
用gtkwave打开vcd文件,选取clk和pulse信号,查看其输出,发现和代码设计一致,说明我们代码写的没问题 😃
btw: GtkWave在Windows下速度超级拉胯,在MacOS下速度竟然很流畅,有点意外。。。。可能GtkWave原本是为Unix系统设计的??