" There are many ways " to code a test case, it all depens on the creativity ot the Testbench designer.Testbench代码设计技巧 11. Clock logic设计技巧 12. Asynchronous reset设计技巧 13. System task之打印数据 24. System task之生成.vcd文件 35. System task之生成vec(vector file)档 31. Clock logic为方便对时钟进行修改,已经后续代码中的应用,定义为parameter或者`define更为方便,如下所示://-------------------------------//clock unitsparameter PERIOD = 20; //20ns,50MHzalways#(PERIOD/2) clk = !clk;2. Asynchronous reset意在设计一个异步复位的信号,故可在clk下降沿复位,同时也在clk下降沿释放。因此在testbench中我们要设计一段“释放→复位→释放”的代码。“event”是在testbench中能被触发,同时也能被监视的事件,过程如下:1) 释放2) 在某一时刻reset_trigger 触发事件3) 等待clk下降沿,复位4) 等待下一个下降沿,释放5) 触发reset_done_trigger事件(可在其他testbench中应用)代码如下所示://-------------------------------//asynchronous reset event(low valid)event reset_trigger;event reset_done_trigger;initialbeginforeverbegin@(reset_trigger);@(negedge clk);rst_n = 0;@(negedge clk);rst_n = 1;-> reset_done_trigger;endend//-------------------------------//asynchronous resetinitial#50 -> reset_trigger;如上代码所示50ns后启动异步复位信号,波形如下所示。可见输出数据都为三态,知道复位开始有效。 注:在时序严谨的工程中,asynchronous reset必须同步化,言外之音,此处画龙点睛介绍此方法! 1) 设计verilog代码,用触发器对异步复位信号同步化2) 整合例化3) 编译,仿真调试4) 在Instance中选择sync_ctrl下的sys_rst_n信号进行观察 代码和波形如下所示:`timescale 1ns / 1nsmodule sync_ctrl(input clk,input rst_n,output sys_rst_n);//--------------------------------------//asynchronous rst_n synchronismreg rst_nr1, rst_nr2;always @(posedge clk or negedge rst_n)beginif(!rst_n)beginrst_nr1 <= 1'b0;rst_nr2 <= 1'b0;endelsebeginrst_nr1 <= 1'b1;rst_nr2 <= rst_nr1;endendassign sys_rst_n = rst_nr2;Endmodule 3. Asynchronous enable雷同以上异步reset信号,用event来完成对enable的仿真。此处异步enable信号在异步reset完成后,维持10clk,之后释放。在是能有效的时候addout自增,代码和波形如下所示://-------------------------------//asynchronous reset & enableinitialbegin#10 -> reset_trigger; //asynchronous reset@(reset_done_trigger); //reset done@(negedge clk); //asynchronous enableenable = 1;repeat(10) //hold 10 cyclesbegin@(negedge clk);enable = 0; //asynchronous releaseendend 此处4. Reset & enable random自然是随机的,因此极端情况下,我们也可以把异步复位和使能信号设置为随机信号,如下所示://------------------------------//asynchronous reset & enable with randominitialbegin#10 -> reset_trigger;@(reset_done_trigger);forkrepeat(10)begin@(negedge clk)enable = $random;endrepeat(10)begin@(negedge clk)#100 rst_n = $random;endjoinEnd 5. Simulation Terminate以上可见到,其实异步enable信号的initial到10个clk以后,test case没完,但是simulate 已经终止了。但如果有到个test case,每个case simulate完都进入terminate_sim,进行某些操作,会很方便。可在代码中稍作修改,写成terminate_sim的event,代码如下://-------------------------------//asynchronous reset & enableevent terminate_sim;initialbegin#10 -> reset_trigger; //asynchronous reset@(reset_done_trigger); //reset done@(negedge clk); //asynchronous enableenable = 1;repeat(10) //hold 10 cycles@(negedge clk);enable = 0; //asynchronous release#10 -> terminate_sim;end//------------------------------//terminate stateinitialbegin@(terminate_sim);$display("Terminating Simulation!");#10 $finish;end6. Task任务模块对于需要多次操作或者循环的任务,可以用task封装,方便调用。此处只做简单的介绍://-------------------------------//stimulate random drivetask din_task;begin//for()din1 = $random % 256;din2 = $random % 256;endendtaskalways@(negedge clk)datain_task; 7. System task之自检Error在系统模拟验证中,采用比较模拟验证法代替波形观察法,以提高效率.无非是复制verilog中的内容,再写一遍,结果是不是一样,没有什么需要提的.8. System task之打印数据//-------------------------------//print the value to screeninitial begin$display("\t\ttime,\tdout");$monitor("%d,\t4'h%x,",$time,dout);endDisplay: 正如C语言中的printfMonitor: 比print个稍微强大点,实时监测数据变化,变化的时候输出数据如下图所示,数据打印到screen如下(monitor检测的数据输出不能顶格很郁闷) 9. System task之生成vcd文件Vcd文件即为value change dump,用固定格式保存波形数据。//-------------------------------//save the warmforminitial begin$dumpfile("wave_test.vcd" );$dumpvars;End当本次仿真结束的时候,将波形数据保存到wave_test.vcd中,一边以后用warmform viewer查看。如下所示(不知道怎么看~~~~(>_<)~~~~ ): 10. System task之生成vec文件Vec文件即为vector file矢量数据文件,用于Modelsim中保存数据的文件,在仿真测试中,相关数据测试,在必要的情况下有很大的好处。相关testbench代码如下所示,保存了仿真400ns过程中addout的变化://-------------------------------//generate vector fileinteger openfile;initialbegin//output to "wave_test.vec" and standard displayopenfile = $fopen("wave_test.vec");//generate header file of vector file$fdisplay(openfile,"/*------------------------------------------------------------------------");$fdisplay(openfile,"This confidential and proprietary software may be only used as authorized");$fdisplay(openfile,"by a licensing agreement from CrazyBingo.");$fdisplay(openfile,"(C) COPYRIGHT 2012 CrazyBingo. ALL RIGHTS RESERVED");$fdisplay(openfile,"This is the wave_test.vec vector file");$fdisplay(openfile,"-------------------------------------------------------------------------*/");$fdisplay(openfile,"\t\t\t\ttime,\taddout");//output all the information of node transition in the vector file$fmonitor(openfile,"%d,\t4'h%x",$time,addout);end生成的文件信息如下所示: 11. Others$display,$fdisplay,$monitor,$strobe,$fopen,$fclose,$dump,$finish,$time,$write,$stop$random1) fork...join:并行任务2) integer i;for(i=0,i<256,i++) 循环3) $readmemb(“File_Name”, Test_Vector); 从文件中读取二进制输入激励码向量4) $readmemh(“File_Name”, Test_Vector); 从文件中读取二进制输入激励码向量5) reg [7:0] stim_array[0:15] 数组的运用来源:http://blog.csdn.net/ywhfdl/article/details/7393378 |