ModelSim下用SystemC做设计验证方法与示例
2012-06-02

最近用SystemC做验证做上瘾了,写一个小文吧。

如何在ModelSim下编译和仿真SystemC的设计?

如何在ModelSim下用SystemC的做验证?

SystemC作为一种系统级设计与验证语言,非常适合做复杂IC的验证,而不是用于RTL描述。很多人问我如何将SystemC综合和编译为可以下载的CPLD/FPGA的比特文件或者综合为ASIC网表,我的回答是用SystemC做RTL设计还为时过早。可以想象将来可能将SystemC的行为级的描述综合为网表,即所谓高层次综合,这是一个很美好的未来,但未来不是现在。Verilog/SystemVerilog依然是最好的RTL设计语言。未来的RTL设计属于SystemVerilog。关于SystemC和SystemVerilog在设计中的地位问题,我认为在验证方面,SystemC有明显的优势。如果你设计纯粹的ASIC,那么用SystemVerilog可能就足够了。但是在很多场合,软硬件同时存在,SystemC的代码很多部分可以之间用于设计软件,这个是很明显的优势。大家同时也可以看到,现在在ModelSim等仿真软件中,SystemC使用起来跟Verilog/VHDL一样,非常方便。举一个例子,我们假如想做DVB-S2的LDPC,我们一定会先用C++(M atlab也可以)写仿真程序,验证算法的正确性。然后假设我们已经确定了目标ASIC的架构,打算用Verilog做RTL设计。现在既然C++代码的验证部分可以几乎不加改变的用于基于SystemC的验证模块的设计,我们为什么还要费力的用SystemVerilog重新写一遍验证代码呢?

下面步入正题,讲一讲如何在ModelSim下编译和仿真SystemC的设计。我们设计一个一位移位寄存器模块(Verilog代码):

1.shifter.v

`timescale 1ns/100ps

module shifter(clk,nrst,din,dout);

input clk,nrst;

input din;

output reg dout;

always(posedge clk or negedge nrst) begin:shifter_with_nreset

if(~nrst) dout<=1'b0;

else dout<=din;

end

endmodule

顶层设计为验证模块加shifter模块的例化:

2.tb.v

`timescale 1ns/100ps

module tb;

wire clk,nrst,data,data_fd_bk;

shifter_test tester(.clk(clk),.nrst(nrst),.data(data),.data_fd_bk(data_fd_bk));

shifter uut(.clk(clk),.nrst(nrst),.din(data),.dout(data_fd_bk));

endmodule

其中shifter_test用SystemC描述。这个例子实际上不能显示SystemC的好处。

下面是SystemC的代码:

3.Shifter_test.h

#ifndef __shifter_test_h

#define __shifter_test_h

#include

#include

SC_MODULE(shifter_test)

{

public:

// Module ports

sc_out clk,nrst;

sc_out data;

sc_in data_fd_bk;

bool data_reg;

bool err;

sc_clock internal_clk;

void st_behaviour()

{

nrst=0;

data=0;

wait(5);

data=1;

wait(2);

nrst=1;

wait(2);

while(1)

{

data=0;

wait(2);

data=1;

wait(3);

data=0;

wait(4);

if(err) printf("Test failed");

else printf("Test passed\n");

}

}

void gen_clk(){clk=internal_clk.read();}

void disp_data(){

printf("nrst=%d,data input=%d,data output=%d\n",nrst.read(),data_reg,data_fd_bk.read());

if((nrst.read()==1) && (data_reg!=data.read()))

{

err=1;

assert(false);

}

data_reg=data.read();

}

SC_CTOR(shifter_test)

:clk("clk"),nrst("nrst"),data("data"),data_fd_bk("data_fd_bk"),internal_clk("internal_clk",1000,0.5,SC_NS)

{

SC_METHOD(gen_clk);

sensitive<

dont_initialize();

SC_CTHREAD(st_behaviour, clk.pos());

SC_METHOD(disp_data);

sensitive<

err=0;

}

};

#endif

4.shifter_test.cpp

#include "shift_test.h"

SC_MODULE_EXPORT(shifter_test);

只有两行代码。注意这里SC_MODULE_EXPORT的作用是将systemc的模块对其它语言可见。

将以上4个文件加入到ModelSim的Project中,之后输入编译命令如下:

sccom –g *.cpp sccom –link vlog *.v vsim tb

就可以根据需要看一些信号的仿真波形了。

这里只有 sccom –g *.cpp sccom –link 与SystemC有关。 在ModelSim中选择Compile all之后,再执行sccom –link,其效果等价于sccom –g *.cpp;vlog *.v;sccom –link。

大家可以看到,在ModelSim中使用SystemC是如此简单。很多人比较熟悉VC,而不熟悉gcc,可能对于gcc的编译错误信息不是十分理解,这是在ModelSim中使用SystemC的一个大障碍。有两个问题需要提醒。

一是好像ModelSim对于sc_clock的参数理解有些问题。 比如 sc_clock internal_clk("internal_clk",1000,0.5,SC_NS) 的仿真波形显示的周期是100ns,我将Verilog的`timescale 设置为1ns/1ns仍然是100ns,不知道是不是Bug.

二是sc_clock必须初始化,否则在vsim tb时就会出现类似下面的错误

vsim tb # Loading work.tb # Loading work.shifter # Loading work/systemc.so # Loading work.shifter_test # ** Error: (vsim-6504) sc_clock low time is zero: increase the period or decrease the duty cycle Also check the simulator resolution and time-unit settings in the modelsim.ini file. The default simulator resolution and time-unit used by ModelSim is 1ns.: clock 'tester/internal_clk' # ** Fatal: Fatal SystemC error detected, exiting... # Time: 0 ps Iteration: 0 Instance: /tb/tester/internal_clk file: C:\Modeltech_6.0c\include\systemc\sc_clock.h # FATAL ERROR while loading design

好像有人问过类似问题。

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号