测试文件该怎么写?
首先看一个简单代码案例:
`timescale 1ns/10ps //1
module test; //2
intput wire[15:0] a;
output reg[15:0] b;
reg clock;
chip chip(.clock(.clock)); //3
always #5 clock=~clock; //4
initial begin //5
clock=0;
repeat(5) @(nagedge clock);
$display("chip.i = %0d",chip.i);
end
endmodule
1、`timescale 1ns/1ns行
编译指令`timescale包括:时间单位(1ns)和时间精度(10ps),单位表示仿真时间的最小值,精度表示保留到小数点后几位(10ps是后两位)。`timescale的作用范围并不限于指定得模块或文件,再遇到`timescale后,指定的时间单位和精度一直保持到遇到下一条`timescale语句。
System Verilog还可以给时间指定时间单位,可以用下方语句实现:
forever #5ns clock=~clock;
//其中时间值和时间单位之间不能有空格,# 5ns正确,# 5 ns则错误。
在System Verilog中,也允许使用关键字timeunit和timeprecision进一步增强时间单位说明,在使用时要注意必须在其他任何声明或语句之前,紧随模块、接口或程序的声明之后,例子如下:
module adder_tb;
input wire[63:0] a,b;
output reg[63:0] sum;
output reg carry;
timeunit 1ns; //单位1ns
timeprecision 10ps; //精度10ps
...
endmodule
当然,timeunit和timeprecision也可以在编译单元域中使用,使用时要先于其他任何声明,这里就不举例了。
2、module行
module就是一个模块,由描述端口和描述逻辑功能两部分组成。其中描述端口有输出口output,输入口input,输入/输出口inout三种。测试文件中的module作用是相当于顶层文件或对顶层文件添加激励,在module的端口声明中还要包括clock。写法可以如上方2处所示。其中,test是模块的名称,intput为输入端口,output为输出端口,clock为时钟。这里我再对数据的类型简单做一个总结吧。
2.1值的类型
包括:0,1,x,z
2.2线网(net)
包括:wire,wor,wand,tri,triand,trior,trireg等。其中wire最常用,wire和tri在语法和功能上相同,但wire只有一个驱动源,tri可以有多个。trireg用来为能够储存值的电容线性网建立模型,tri0和tri1用来为电源建立模型。
2.3寄存器(var)
包括:reg,integer,time,real等。其中reg最常用,为通用型,默认值x,无符号。integer为整型,用来储存整数,默认位宽为宿主机字的位数。real为实型,存储实数。time为时间寄存器,用来存放仿真时间。
2.4参数
包括:parameter,localparam,defparam。parameter在模块内定义为常数,不能像变量那样赋值,但可在编译阶段被重载。defparam可以改变parameter的参数值。localparam为局部参数,不能被重载也不能通过defparam改变参数值。
其他的如字符串、数组等这里就不介绍了。
3、函数调用和连线
将需要测试的模块导入测试文件,然后进行连线。
4、always语句
always块中,从0时刻开始顺序执行其中的行为语句,当最后一条执行完毕后再次执行第一条语句。通常用来产生时间脉冲。
5、initial块
initial语句内的语句构成了一个initial块,initial块从仿真0时刻开始执行,在整个仿真过程中只执行一次。若测试文件中包括多个initial块,则这些initial块从仿真0时刻开始并发执行,且每个快都各自独立。
clock需要在initial块中初始化。