《Verilog testbench总结.docx》由会员分享,可在线阅读,更多相关《Verilog testbench总结.docx(10页珍藏版)》请在第一文库网上搜索。
1、Veri1ogtestbench总结1.激励的产生对于testbench而言,端口应当和被测试的modu1e一一对应。端口分为input,output和inout类型产生激励信号的时候,input对应的端口应当中明为reg,OUtPUt对应的端口中明为Wire,inou1端口比较特殊,下面专门讲解。1)直接赋值。般用ini&a1块给信号赋初值,initia1块执行次,a1ways或者feVer表示由事件激发反复执行。举例,一个modu1emodu1eexam();regrstn;rege1k;regdata;initia1beginc1k=bO;rst=b1;#10rst=bO;#500rst
2、=b1;enda1waysbegin#10c1k=1k;end大家应该注意到有个#符号,该符号的意思是指延迟相应的时间单位。该时间单位由timsca1e决定.般在testbench的开头定义时间单位和仙直精度,比如timesca1e1ns1ps,前面一个是代表时间单位,后面一个代表仿真时间精度。以上面的例子而言,一个时钟周期是20个单位,也就是20ns。而仿真时间精度的概念就是,你能看到1OOInS时对应的信号值,而假如timesca1e1ns1ns,1.001ns时候的值就无法看到。对于一个设计而言,时间刻度应该统一,如果设计文件和testbench里面的时间刻度不一致,仿真器默认以test
3、bench为准。一个较好的办法是写一个g1oba1.v文件,然后用inc1ude的办法,可以防止这个问题。对于反复执行的操作,可写成Iask,然后调用,比如task1oadcount;input3:01oad_va1ue;begin(negedgec1k_50);Sdisp1ay($time,1oadingthecounterwith%h”,1oad_va1ue);1oad_1=1,b;count.in=1oadva1ue;(negedgec1k_50);1oad_1:1b1;endendtask/of1oad_countinitia1begin1oad_count(4,hA);/调用task
4、end2)文件输入有时候,需要大量的数据输入,到寄存器中,需要时取出即可。以包含输入激励和输出期望值)其他像forever,for,function等等语句用法类似,虽然不一定都能综合,但是用在testbench里面很方便,大家可以自行查阅参考文档直接赋值的话比较繁琐,可以先生成数据,再将数据读入用$readmemb系统任务从文本文件中读取二进制向量(可OSreadmemh用于读取十六进制文件。例如:reg7:0mem1:256/a8-bit,256-word定义存储器meminitia1Sreadmemh(yzEiZreadhexZmem.dat*,mem)/将.dat文件读入寄存器Inen
5、I中initia1$readmemh(E:/readhex/mem.datz,mem,128,1)/参数为寄存器加载数据的地址始终2 .查看仿真结果对于简单的modu1e来说,要在mode1篁色的仿真窗口里面看波形,就用addwave.命令比如,testbench的顶层InOdU1e名叫tb,要看时钟信号,就用addwavetb.e1k要查看所有信号的时候,就用addwave*当然,也可以在WOrkSP型e下的Sin1窗口里面右键单击instance来添加波形对于复杂的仿真,免不了要记录波形和数据到文件里面去。1)波形文件记录常见的波形文件一般有两种,VCd和1b,debussy是个很好的工具
6、,支持fsdb,所以最好是mode1sim+debussy的组合默认情况下,InOdeISin1不认识fsdb,所以需要先装debussy,再生成fsdb文件。$dumpfi1e和$(1UnIPVar是VCriIog语言中的两个系统任务,可以调用这两个系统任务来创建和将指定信息导入VCD文件.对于fsdb文件来说,对应的命令是fSdbDumpfi1e,dumpfsdbvars(什么是VCD文件?答:VCD文件是在对设计进行的仿真过程中,记录各种信号取值变化情况的信息记录文件,,EDA工具通过读取VCD格式的文件,显示图形化的仿真波形,所以,可以把VCD文件简单地视为波形记录文件.)下面分别描述
7、它们的用法并举例说明之。Sdumpfi1e系统任务:为所要创建的VCD文件指定文件名。举例(/”符号后的内容为注释文字):initia1Sdumpfi1eCmyfi1e.dump*);/指定VCD文件的名字为myfi1e.dump,仿真信息将记录到此文件$dumpvar系统任务:指定需要记录到VCD文件中的信号,可以指定某模块层次上的所有信号,也可以单独指定某一个信号。典型语法为$dumpvar(1eve1,modu1e_name);参数IeveI为一个整数,用于指定层次数,参数modu1e则指定要记录的模块。好句的意思就是,对于指定的模块,包括其下各个层次(层次数由IeVeI指定)的信号,都
8、需要记录到VCD文件中去。举例:initia1.Sdumpvar(0,top);指定层次数为0,则IoP模块及其下面各层次的所有信号将被记录initia1Sdumpvar(1,top);记录模块实例top以下一层的信号层次数为1即记录top模块这一层次的信号对于top模块中调用的更深层次的模块实例,则不记录其信号变化initia1$dUnIPvar(2,top);记录模块实例top以下两层的信号即t。P模块及其下一层的信号将被记录假设模块top中包含有子模块modu1e1,而我们希望记录top.modu1e1模块以下两层的信号,则语法举例如下:initia1$dUmPvar(2,top.mod
9、u1e1);模块实例top.modu1e1及其下一层的信号将被记录假设模块top包含信号Signa11和SignaI2(注意是变量而不是子模块),如我们希望只记录这两个信号,则语法举例如下:initia1Sdumpvar(0,top.signai1,top.signa12);虽然指定了层次数,但层次数是不影响单独指定的信号的即指定层次数和单独指定的信号无关我们甚至可以在同一j$dumpvar的调用中,同时指定某些层次上的所有信号和某个单独的信号,假设模块top包含信号Signa11,同时包含有子模块modu1e1,如果我们不但希望记录Signa11这个独立的信号,而且还希望记录子模块InodU
10、Ie1以下三层的所有信号,则语法举例如下:initia1$dUn1PVar(3,top.signa11,top.modu1e1);指定层次数和单独指定的信号无关所以层次数3只作用于模块top.modu1e,而与信号top.signa11无关上面这个例子和下面的语句是等效的:initia1beginSdumpvar(0,top.signa11);Sdumpvar(3,top.modu1e1);endSc1unipvar的特别用法(不带任何参数):initia1$dumpvar;无参数,表示设计中的所有信号都将被记录最后,我们将$dumpfi1e和$加1丫r这两个系统任务的使用方法在下面的例子中综
11、合说明,假设我们有一个设计实例,名为design,此设计中包含模块modu1e1,模块modu1e1下面还有很多层次,我们希望对这个设计进行仿真,并将仿真过程中模块modu1e1及其以下所有层次中所有信号的变化情况,记录存储到名为mydesign.dump的VCD文件中去,则例示如下:initia1beginJdumpfi1e(mydesign.dump);/指定VCD文件名为mydesign.dump$dumpvar(0,i_design.modu1e1);记录i_design.modu1e1模块及其下面层次中所有模块的所有信号end对于生成fsdb文件而言,也是类似的initia1begi
12、nSfsdbDumpfiIe(z,tb_xxx.fsdb);SfsdbDumpvars(0,tbxxx);end2)文件输出结果integerout_fi1e;/out_fi1e是一个文件描述,需要定义为integer类型outfi1e=$fopen(cpu.data);cpu.data是需要打开的文件,也就是最终的输出文本设计中的信号值可以通过$fmoni1or,Sfdisp1ay,Sfwrite其中$fmonitor只要有变化就一宜记录,$fdisp1ay和$1近需要触发条件才记录例子:initia1beginSfmonitor(fi1e_id,:%tin1=%do1=%h”,ini,o1
13、);enda1ways(aorb)beginSfwrite(fi1e_id,z,Attime%ta=%bb=%b*$rea1time,a,b);end3 testbench的技巧1) .如果激励中有一些重复的项目,可以考虑将这些语句编写成一个task,这样会给书写和仿真带来很大方便。例如,-个存储器的testbench的激励可以包含Write,read等tasko2) .如果DUT中包含双向信号(inout),在编写testbench时要注意。需要一个reg变量来表示其输入,还需要一个Wire变量表示其输出。3) .如果initia1块语句过于复杂,可以考虑将其分为互补相干的几个部分,用数个i
14、nitia1块来描述。在仿真时,这些initia1块会并发运行。这样方便阅读和修改。4) .每个testbench都最好包含$StOP语句,用以指明仿真何时结束。5) .加载测试向量时,避免在时钟的上下沿变化,比如数据最好在时钟上升沿之前变化,这也符合建立时间的要求。4 .一个简单的例子modu1ecounter(e1k,reset,enab1e,count);inpute1k,reset,enab1e;output3:0count;reg3:0count;a1ways(posedgee1k)if(reset=b1)begincount=0;ende1seif(enab1e=1,b1)begi
15、ncount=count+1;endendmodu1etestbenchmodu1ecountertb;rege1k,reset,enab1e;wire3:0count;counterUO(.e1k(e1k),.reset(reset),.enab1e(enab1e),.count(count);initia1begine1k=0;reset=0;enab1e=0;enda1ways#5e1k=!e1k;initia1beginSdumpfi1e(counter.VCd);$dumpvars;endinitia1begin$disp1ay(*time,e1k,reset,enab1e,count);Smonitor(,/%od,%ob,%ob,%ob,%od”,$1ime,e1k,reset,enab1e,count);endinitia1#100$finish;/Restoftestbenchcodeafterthis1ineendmodu1e5 双向端口