当前位置:首页 > testbench的学习笔记 - 图文
clk,时钟输入 addr,地址输入 wen,写使能 data,数据输入
然后还有一个dataout的数据输出。
那么你可以写一个文件,给clk,addr,wen,data送入你预想的一些信号,然后观察q的输出,看看ram是否工作正常。那么这个文件从一定意义上可以叫做\。
联想(帮助理解):从quartus里面你仿真,你可能对着那个画图一样的东西画上输入,然后编译以后看他的输出。对吧。那么在modelsim里面,我告诉你,可以不用画图了~,你只需要按照一定规则写一个.v或者.vhd的文件,这个文件可以给你的设计提供你预想的输入。这个就是testbench的文件。然后在modelsim这个特定的软件环境下,这个软件能根据你的代码给你的设计提供输入,又可以把你设计的输出在屏幕上显示出来给你debug。那么这个时候,一个在modelsim上的testbench就完成了。
狭义的总结一下:FPGA的testbench就是一个.v(verilog)或者.vhd(vhdl)的文件。这个文件能给你的设计提供激励,并能在一些专用的软件中提供良好的debug接口。这个就是一个testbench。
==============================================================
=====================高级应用================================
关于testbench的高级应用。
刚才说了初步的testbench。其实testbench是verification(验证)中的一个手段。
验证是什么呢?举例:做鱼了,你往里面加了调料,然后再尝尝味道,这个就是验证的过程。同样你可以分成几个部分,一条鱼,好比你的设计,然后你给他一定的激励,也就是调料啦。然后你再尝一尝,看看鱼是不是达到你想要的味道了。那就是一种验证的手段,如果淡了。那么加点盐,再尝尝,这个就是反复验证。
testbench图解一下比较清楚。
=========================Testbench=============================
| | | |
| | ================== | | | 激励生成 |====》 | | | 输出校验 | | |预想输入 | 设计 |==》 | | | | | | 设计 | |
================================= 输出 ===================
testbench里面包含了三个东西:
1、激励生成。也就是我们刚才初级时候说的所谓的“testbench”。英文么就是simulator,这个只用来生成输出,他自己没有输入,只是按照一定的规律去给你的设计激励,激励通过设计的输入端口送到你的设计中。其余的事情不管。这里的激励,都是预先设想好的,比如根据某个协议,或者某种通信方式传递。
2、你的设计。英文可以叫做DUT:design under testbench或者DUV:design under verification。当然咯。这个是你主要目标。
3、输出校验。校验你的输出。英文叫markerboard,他所管的事情就是,接收你设计的输入,然后通过校验,找出对应的问题。然后报错,或者统计错误。等等。通俗的讲,你设计它就是把你自己解脱出来,让他来帮你找错误。他输出给你的可能就是通过打印啊,通知啊,等等方法了解你设计的正确性。
那么你有可能问了,这个东西用verilog或者VHDL能写么,modelsim里能用么?的确是可以的,有写甚至可以用c的代码通过程序接口来转换到modelsim里面来帮助验证。
========================高级应用结束==========================
最后小说两句:testbench是一个平台,帮助你从软件方面验证的。对于这个概念不需强求,等你自己的验证写多了,自然而然就会了解其中深刻的含义。先开始慢慢的写一些激励,然后再写写校验。到时候你收获的东西自然而然的能帮助你理解testbench和verification 。
标签: Testbench 编写技巧
Testbench编写技巧
测试平台是个没有输入输出端口的模块。仿真在一个模块设计中是很关键的步骤,而testbench是仿真的很好工具。
与待测模块接口
与输入端口相连接的变量定义为reg 与输出端口相连的定义为wire
initial块中初始化变量,必须的。 用$stop或$finish暂停或结束仿真
wait(z==1’b1);//等待变量值改变,变量可以是待测试模块的输出或者内部变量
时钟产生:
always # 10 clk =~clk;产生时钟
initial repeat(13) #5 clk =~clk; //控制只产生13个时钟。
同步数据:
initial forever @ (posedge clk) #3 x = $random;
为了降低多个输入同时翻转的概率,对时序电路的输入一般采用素数作为时间间隔。
同步显示:
? initial $monitor (“%d is changed at %t”,MUT.current,$time);//
一般在 initial中调用,采用$monitor显示模块MUT内部current的值以及发生变化的时间,$monitor是一个后台运行任务函数,多个模块下,任意时间只能有一个$monitor起作用,可用$monitoron $monitoroff来控制。
? always @(z) $display(“Output changed at %t to %b”,$time,z);当z发生变化输出z值
以及变化时间,自动换行。
? always @(z) $strobe(“Output changed at %t to %b”,$time,z);//仿真结束后显示输出,
查看非阻塞赋值变量的值。
随机数据
initial repeat(5) #7 x = $random; a = $random`; //产生-59~59之间随机数 a = {$random}`; //产生0~59之间随机数
产生随机时间间隔
always begin
t= $random; #(t) x = $random; end
数据缓存
initial buffer = 16’b1110_0001_1011_0101;//将测试数据进行初始化
always @ ( posedge clk) #1 {x,buffer} = {buffer,x};//可以在控制的数据下输入信号x
读取数据文件
reg [7:0] mem1[0:1024]; initial begin
$readmemh( “data1.dat” , mem1);
模板:
`timescale 1ns/100ps `include “*.v” module t; 参数定义
输入测试模块的测试信号定义 reg,wire 内部变量定义 initial begin 初始化变量
$monitor (“%d is changed at %t”,MUT.current,$time);//监控数据 forever @ (posedge clk) #3 x = $random;//同步数据 repeat(5) #7 x = $random; end
always @(z) $display(“Output changed at %t to %b”,$time,z); always @(z) $strobe(“Output changed at %t to %b”,$time,z); always # 10 clk =~clk;//产生时钟 always begin//
t= $random; #(t) x = $random;
共分享92篇相关文档