作者:赵云集, 庄乾起
一、什么是仿真文件
仿真文件(testbench)是模拟实际环境的输入激励和输出校验的一种“虚拟平台”;是一种验证手段,就是用testbench可以对实际信号的输入输出进行一些模拟,再通过观察波形图或规格化输入、输出的方式来检验输入与响应是否符合我们的设计要求。仿真文件可以由Verilog HDL 书写,也可以由VHDL或 System Verilog HDL编写。目前多数的编译及仿真工具都支持混合语言编程方式,即用Verilog HDL编写的testbench文件可以用来仿真Verilog设计,也可以用来仿真VHDL语言及System Verilog的设计文件,反之亦然。下面就以Verilog HDL为例编写的testbench文件tb.v为例进行介绍。
二、如何使用仿真文件
1、仿真文件的特殊性
仿真文件与正常的设计文件有很大区别,具体表现在如下几个方面:
- Testbench 文件中没有输入、输出等接口,该部分内容是空的,因为只是用来测试底层实体模块,对输入、输出没有需求。如:
|
1 2 3 |
module tb ( ); |
实际上新版本的仿真工具对testbench的module要求更低,甚至直接写成“module tb;”也可以,不需要在module之后加“()”。
而实体(entity)文件中module接口部分是不能空的,其实实体module中可以没有输入,但不能没有输出或双向接口,如:
|
1 2 3 4 5 6 7 8 9 10 |
module max ( input [7:0] a, input [7:0] b, output [7:0] c ); assign c = (a > b) ? a : b; endmodule |
仿真程序如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
`timescale 1ns / 1ps module tb; // act as Inputs reg [3:0] a; reg [3:0] b; // observe Outputs from instantiations wire [7:0] c; reg clk; initial begin clk = 0; a = 0; b = 0; end always #5 clk = ~clk; always @(posedge clk) begin if(a == 9) begin a = 0; if(b == 9)begin b = 0; $stop; end else b = b + 1; end else a = a + 1; end initial begin $monitor("t=%3d a=%d, b=%d, c=2'b%2b \n", $time, a, b, c ); end // Instantiate the Unit Under Test (UUT) max max_inst ( .a(a), .b(b), .c(c) ); endmodule |
Testbench文件由于没有输入、输出接口,因此在仿真系统中是最顶层文件,因此该module 不能再例化被其它module调用。但testbench文件可以使用其它的module的例化。
- 仿真文件不能参与综合。主要原因也是因为没有输入、输出接口,不能形成实体电路模块。
- 仿真文件由于不需要参与综合,因此所有Verilog中支持的语法都可以在该文件中使用。如:延迟语句,forever循环等,这些一般在实体 module不被综合的语句都可以使用。
- Verilog 仿真语法提供了许多专用函数和任务,如:$display,$monitor,$stop,文件操作等专门用来对FPGA或IC设计代码进行验证的工具集。
2.QuartusII下仿真文件编译
-
- testbench文件的编译。在Quartus II 下Verilog 文件的编译原则如下:
- 所有使用到的文件应汇集到工程管理下,可以在菜单Assignment–>settings… ,在Setting对话框中选中Files查看,如图1:
- testbench文件的编译。在Quartus II 下Verilog 文件的编译原则如下:
图1
如果图1中没有包含所有工程文件,可以在这里添加。
-
- Quartus II 编译是按照顶层文件开始并按照层次展开,把所有各层次例化的module, function, task等文件进行编译,编译时遵循依赖关系,非常类似于C语言。
- testbench 文件的编译,如果想利用Quartus II检查Testbench文件的语法错误,点击工具栏start Analysis & Elaboration进行分析和评估(因为testbench文件是不可综合的)。如果有语法错误可以根据提示修改和纠正。
- Testbench文件在Analysis&Elaboration 最后会报出如图2错误,这说明评估到了最后阶段,testbench 及其它实体文件没有语法错误。
图2
图2中报出的错误是比较常见的错误,而且许多Quartus II 的初学者对这个问题一头雾水,不知道如何解决。首先在Quartus II系统中有如下三个名词: 顶层文件(top-level file),顶层设计实体(top-level design entity),顶层模块(top-level module).
(1)顶层模块(top-level module): 是可综合的最顶层模块
(2)顶层设计实体(top-level design entity):实际上工程中选定的最顶层实体,也可以说是最顶层模块,是告诉编译器哪个文件,哪个模块将作为顶层实体文件。
(3)顶层文件(top-level file):实际上顶层模块存储后的文件。
图3
从图3的对比可以看出,顶层设计实体为stimulus, 而顶层模块名(module)为tb, 文件名为stimulus.v, 三者出现了不一致造成的。那么如何解决呢?当然三者要一致。解决办法如下:
(1)将module的名称改为stimulus,即“ module stimulus;”, 存储为stimulus.v 即可解决。
(2)将文件存储为tb.v,保留顶层实体设计名称不变(stimulus),即顶层文件与顶层模块名一致是否能解决呢?可以试一下,
图4
编译结果如图4,出现了令人费解的错误信息,“module “tb” cannot be declared more than once”
(3)在(2)的基础上修改顶层设计实体的名称,将stimulus 改成tb.
点击主菜单 Project–>Revisions…
图5
在图5中,双击<<new revision>>, 输入tb,此时工程的顶层实体文件修改tb, 点击OK. 并将tb.v设为顶层文件,此时工程浏览器显示如图6
图6
此时编译的结果显示如图7:
图7
图7显示依然有错误,其原因是把仿真文件设为顶层文件了,修改顶层文件设置,将max.v设为顶层文件,再重新编译就可以了。
3.仿真工具链接口
- 在project navigator中右键点击芯片选择settings,如图8

图8
- 在simulation界面中选择compile test bench->点击test benches按钮,如图9,

图9
- 在跳出的对话框中点击new按钮,选择为本工程编写的Testbench文件(tb.v),如图10

图10
- 在file name上选中写好的tb文件,点击Open按钮,如图11

图11
- 图11中右边的设置框有两个选项:Run simulation until all vector stimuli are used 与End simulation at :
当仿真程序提供的激励是有限项是,一般选择Run simulation until all vector stimuli are used,即跑完所有激励就停止。当仿真程序激励无限循环时,可以选择End simulation at ,并在输入框中提供合适的时间值(与`timescale宏相关)。
- 点击ADD添加,并将testbench name, Top level module test bench的名称都和仿真文件的名称一致(如tb),如图12,

图12
- 全部点击OK按钮
- 点击分析和评估(start Analysis & Elaboration),如图13,

图13
4.启动Modelsim仿真
- 在Tools下的Run Simulation Tool下选择RTL Simulation,如图14

图14
- 分析信号
- 刚打开的波形还在运行,点击STOP停止运行,即出现波形,如图15

图15
- 在sim-default中选择文件,在objects中选择想观察的信号拖拽到wave-default中,如图16

图16
- 选择运行时间后点击全运行(run all)后点击STOP停止运行观察波形,如图17

图17
三、常见错误及解决办法
1、综合时报错Error (12007): Top-level design entity “tb” is undefined(文件未定义)
主要是把仿真文件设为顶层的原因。由于仿真文件本身没有输入输出信号,所以仿真文件不能被综合,因此仿真文件在Quartus II下不能作为顶层文件参与编译,可以使用临时设为顶层文件进行Analysis & Elaboration,便于语法检查,直到报出该错误,在将顶层文件切换回原来的顶层文件。顶层文件的切换步骤如下:
- 在Project navigator中选择files,如图18

图18
- 找到设计的顶层文件->选中右键->设为顶层,重新综合,如图19

图19
- modelsim中的波形界面中信号和波形显示

图20
- 可能是没有在modelsim中没有正确设置仿真的顶层文件,检查Quartus II Simulation各项,可以根据第二大条第一项添加。
- 可能是testbench文件存在语法错误,如图21

图21
根据报错去文件相应位置修改就可以了。
- 弹出Nativelink error对话框

图22
原因是之前已经开了一个modelsim没有关闭。此时再从Quatus中启动 Run RTL Simulation就会报如图22的错误。
如果在仿真时只需要验证一些Verilog语法或行为算法,不需要实体顶层文件,编译不能通过,如何处理?
可以设计或添加一个简单的顶层文件,并与顶层设计实体名称 ,模块名称一致,在testbench里不需要例化,就可以使用testbench文件进行仿真了。例:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
`timescale 1ns / 1ps module tb; // act as Inputs reg [3:0] a; reg [3:0] b; // observe Outputs from instantiations wire [7:0] c; reg clk; initial begin clk = 0; a = 0; b = 0; end always #5 clk = ~clk; always @(posedge clk) begin if(a == 9) begin a = 0; if(b == 9)begin b = 0; $stop; end else b = b + 1; end else a = a + 1; end initial begin $monitor("t=%3d a=%d, b=%d, c=2'b%2b \n", $time, a, b, c ); end // Instantiate the Unit Under Test (UUT) //max max_inst ( // .a(a), // .b(b), // .c(c) // ); endmodule |
项目中max.v依然存在,但仿真文件中并没有例化,此时编译和仿真都没有问题。这么做的主要原因是,一旦编译出错,在点击仿真时会报错如图23,
图23
图23说明,工程没有编译或编译出错(见图7),不能启动仿真。只要将max.v设为顶层文件。重新编译即可。
本文仅仅是最近学习和调试的总结,欢迎各位同学补充和指正。
对应视频:







