文章目录
概要
FPGA学习过程——如何写TestBench
由于在准备FPGA竞赛,因此打算恶补一下verilog的相关知识。本篇文章记录学习TestBench的心得,假如有错误的地方希望得到大佬指正。
编写 TestBench 是为了对设计的模块进行仿真验证,测试设计电路的功能、性能与设计的预期是否相符
如何编写TestBench
1.准备好待仿真的模块
以时序电路为例
module led_twinkle(
input sys_clk , //系统时钟
input sys_rst_n, //系统复位,低电平有效
output [1:0] led //LED 灯
);
...... //省略功能部分
endmodule
2.编写Testbench
TestBench文件结构
注意注释,都是易错点
~timescale 1ns / 1ps //测试时间基本单位为1ns,精度为1ps
module tb_led_twinkle(); //通常起名格式为 tb_被测试模块名
//输入
reg sys_clk;
reg sys_rst_n;
//输出
wire [1:0] led;
//信号初始化,必须有这一步,容易被忽略
initial begin
sys_clk = 1'b0; //系统时钟
sys_rst_n = 1'b0; // 系统复位
#200 //延时200ns
sys_rst_n = 1'b1;
end
//生成时钟,模拟实际的周期时序
always #10 sys_clk = ~sys_clk; //每10ns,sys_clk进行翻转,周期为20ns
//例化待测模块
led_twinkle u_led_twinkle(
.sys_clk (sys_clk), //注意语句后面为逗号
.sys_rst_n (sys_rst_n),
.led (led) //最后一步无逗号
);
endmodule
名词解释
1.仿真的单位和精度
声明通常的格式为
timescale 仿真单位/仿真精度
注意:不要以分号结尾
,/
前为仿真单位,如1ns ,/
之后为仿真的精度,如1ns。当代码中出现#10
时,代表延时10ns,与仿真单位有关。而仿真的精度就与最低延时精度有关。如此时最低的延时精度为1ns。
2.模块名
通常在待仿真的模块名后加“_tb” ,也可以在前面加,通常testbench不需要定义输入和输出
3.变量的定义
通常定义为reg或wire型。在initial或always中定义为reg型,在assign或者用于连接被例化的信号定义为wire型
4.激励波形的产生
使用initial和always产生激励
如上述TestBench文件结构中的
//生成时钟,模拟实际的周期时序
always #10 sys_clk = ~sys_clk; //每10ns,sys_clk进行翻转,周期为20ns
当需要生成其他占空比的时钟时,可以采用以下代码
//生成时钟,模拟实际的周期时序
always begin
#7 sys_clk = 0;
#3 sys_clk = 1;
end
一定要初始化
,always只设定了一个周期波形的形状,还需要设置初始值,因此用initial来进行初始化。
//信号初始化,必须有这一步,容易被忽略
initial begin
sys_clk = 1'b0; //系统时钟
sys_rst_n = 1'b0; // 系统复位
#200 //延时200ns
sys_rst_n = 1'b1;
end
例化待仿真模块
这个很好理解,就直接贴代码了。
//例化待测模块
led_twinkle u_led_twinkle(
.sys_clk (sys_clk), //注意语句后面为逗号
.sys_rst_n (sys_rst_n),
.led (led) //最后一步无逗号
);
左侧带“.”
的信号为待测试模块led_twinkle定义的端口信号,右侧括号内为激励模块中定义的信号。通常名称一致,便于理解和书写,当然也可以不一致。
在vivado中如何编写testbench
在Vivado软件中,在左侧的 Flow Navigator 窗口点击 Add Source, 选择 Add or create simulation sources,点击 Next,点击 Create File, 给测试文件命名,通常格式为 “tb_被测试模块名”,点击OK,点击Finish。
在 Source 栏中的 Simulation Sources 中双击生成的 “tb_被测试模块名” 文件,进行编写。
参考文献
本篇学习笔记参考自两篇文章