原文参考: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:为仿真模型中定义的接口提供手段。也就是说,设计者没有仿真整个器件的低层次模型,就可以对一组时序或协议的要就进行校验。