原文参考:http://www.cnblogs.com/jyaray/archive/2011/05/11/2043091.html
参数化的全局定义
全局定义会给书写和仿真带来很大方便,在编写testbench过程中,如果激励中有一些重复的事件,可以考虑将这些语句编写成一个task。比如:
1.Register相关位及其数值可以全局宏定义在reg_define.v中。
2.相关路径可以全局宏定义在define_board.v中。
3.系统重要变量的显示信息可以定义在display.v中。
4.与Register相关的比较任务和报错任务可以编写成task定义在reg_cmp.v中。
5.时钟周期参数的定义,一般局部定义,用parameter定义。
存取波形及相应变量的数据,使用`ifdef为全局定义使用
1.波形源头文件是VCD波形,但过于庞大,可用来做功耗分析。
1 $dumpfile(“wave.vcd”); //打开数据库 2 $dumpvars(1, top.u1); //scope = top.u1, depth = 1 3 //第一个参数表示深度, 为0时记录所有深度; 第二个参数表示scope,省略时表当前的scope. 4 $dumpvars; //depth = all scope = all 5 $dumpvars(0); //depth = all scope = current 6 $dumpvars(1, top.u1); //depth = 1 scope = top.u1 7 $dump0ff;//暂停记录数据改变,信号变化不写入库文件中 8 $dumpflush;//重新恢复记录
2.SHM波形是Cadence的,可以用simvision打开。
1 $shm_open("waves.shm"); //打开波形数据库 2 $shm_probe(top, "AS"); //set probe on "top" 3 //A -- signals of the specific scrope 4 //S -- Ports of the specified scope and below, excluding library cells 5 //C -- Ports of the specified scope and below, including library cells 6 //AS -- Signals of the specified scope and below, excluding library cells 7 //AC -- Signals of the specified scope and below, including library cells 8 //还有一个 M ,表示当前scope的memories, 可以跟上面的结合使用, 如"AM" "AMS" "AMC"。什么都不加表示当前scope的ports。 9 $shm_close //关闭数据库
3.FSDB波形是Novas的,可以用nwave打开。
1 $fsdbDumpfile(“wave.fsdb”); //打开数据库 2 $fsdbDumpvars(0, top.u1); //scope = top.u1, depth = 0
4.VPD波形是Synopsys的,可以用dve打开。
1 $vcdplusfile(“wave.vpd”); //打开数据库 2 $vcdpluson(1, top.u1); //scope = top.u1, depth = 1
5.变量的存取,使用文件I/O来操作。
(1).打开文件
1 integer file_id; 2 file_id = fopen("file_path/file_name");
(2).写入文件
1 //$fmonitor只要有变化就一直记录 2 $fmonitor(file_id, "%format_char", parameter); 3 4 //$fwrite需要触发条件才记录 5 $fwrite(file_id, "%format_char", parameter); 6 7 //$fdisplay需要触发条件才记录 8 $fdisplay(file_id, "%format_char", parameter);
(3).读取文件
1 integer file_id; 2 file_id = $fread("file_path/file_name", "r");
(4).关闭文件
$fclose(fjile_id);
(5).由文件设定存储器初值
1 $readmemh("file_name", memory_name"); //初始化数据为十六进制 2 $readmemb("file_name", memory_name"); //初始化数据为二进制
(6).还可以使用宏来选择变量的存取和存取时间使用
1 `ifdef SAVE_LROUT 2 start_save = 1’b1; 3 #(10e6) stop_save = 1’b1; 4 `endif 5 xxx = $fopen(“xxx”, “w”); 6 if (start_save && !stop_save) 7 $fwrite(xxx, “%f\n”, x); 8 $fclose;
系统激励
1. 用MATLAB产生归一化的数据,使用readmemb/readmemh读入Verilog仿真。同样可以将仿真后的数据读入到MATLAB中,以分析相关特性。
2. Testbench的时钟和复位应该在全局层次上模仿。用非阻塞赋值初始化testbench的时钟和复位,用阻塞赋值更新它们。
1 `timescale 1ns/1ns 2 `define PERIOD 5 //100MHz clock 3 initial begin 4 clk <= 0; 5 forever #(`PERIOD) clk = ~clk; 6 end 7 initial begin 8 rst_n <= 0; 9 @(negedge clk) rst_n = 1; 10 end
3. 时间刻度`timescale:根据仿真精度和运行时间平衡来选择。
4. 总线功能模型BFM:为仿真模型中定义的接口提供手段。也就是说,设计者没有仿真整个器件的低层次模型,就可以对一组时序或协议的要就进行校验。