学写简单的Verilog Testbench
我们使用testbench(ISE里又叫Verilog Test Fixture)来验证行为级Verilog HDL模型是否正确,testbench也是一种按照verilog来编写的HDL模型,只不过大量使用不可综合风格的仿真语句,比如延迟、赋值等等。
testbench三个目的: 1. 产生激励 2. 将激励加入被测模块(Unit under Test)并收集响应 3. 响应与期望比较
通常的testbench概览:
//设置时间单位,步长/每步长误差,一般为1ns/1ps
`timescale 1ns/1ps
module module_under_test //without ports declarations
//put reg, wire, integer, parameter… here
reg reg_alpha;
wire wire_beta;
//uut model mapping
unit_module uut (.in_port_a(in_a), .in_port_b(in_b),
.out_port_z(out_z)
);
//initialization, using initial begin-end or fork-join pair
//add stimulus or generate waveform here, always begin-end
//monitor output and compare with expect values
endmodule
今天用一个4位带carry的全加器来体会简单testbench的写法。 全加器adc.v有用的只有一句话,行为描述:{cout,sum}=ain+bin+cin; 本次testbench用ISE调用Modelsim仿真的方式进行,省去了在modelsim里新建project的步骤(这怎样都好吧,modelsim里的project可以用-pl novas.dll参数和debussy结合——如果有的话)
用modelsim产生dump波形在initial中加入:
initial begin |
插嘴:如果是在NC-Verilog跑仿真就这样dump波形
initial begin |
之后初始化输入
initial fork |
给待测模块赋值,决定使用随机值函数$random生成激励:
always begin |
每隔5ns给ain和bin赋4位随机数值,再等待5ns翻转进位cin信号,模拟进位的伪随机输入。初始化部分和激励生成部分有两个问题:
首先是initial块内的fork-join与begin-end块区别,initial与always都应当理解为并行执行的组件,区别仅仅是initial内语句执行一次即关断而always语句会随着之后@触发信号反复执行。initial内有两种嵌套:fork-join内所有的语句并行执行,无分先后,因此本例中对触发器ain,bin,cin初始化在硬件上是同时进行的,begin-end内的语句与计算机程序语言一样逐次顺序执行,可以放入if-else或者for等顺序语句。
第二个问题是设定仿真结束时间。本例使用#600 $stop表示无论信号如何变化,在600ns后仿真停止。问题在于该语句放置的位置,有三类位置:initial与always平级、并行关系;initial的fork-join内、并行关系;initial的begin-end内,顺次执行关系。分别编译仿真后有两种结果,见截图:
失败的激励生成只有一次随机数赋值和一次cin翻转,$stop函数在always begin-end内。而无论是并列关系的initial fork-join还是begin-end,伪随机的测试矢量都正确的赋给了被测单元,进位cin也如同时钟一样周期翻转。因为always块内本应设计用来反复赋值的工作加入了等待-停止的指令,实际也就赋值一次结束。而initial是另一个并行组件仿真器并不干涉initial与always运行的情况,initial初始化之后就静静等待600ns的到来,在此期间always即按照一定频率生成激励输入到adder中。
除了波形观察我们还可以将响应结果用文件保存,类似于C语言的文件操作,只不过“文件指针”类型在这里是integer整形:
//Define file pointer |
- Post title:学写简单的Verilog Testbench
- Post author:suncup
- Create time:2010-07-16 11:21:00
- Post link:https://blog.suncup.info/2010/07/16/学写简单的verilog-testbench/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.