XU.J.P

Verilog testbench总结

0
阅读(3474)


  • 时钟
  • --------------------------------------------------------------------------------
  • parameter ClockPeriod=10;
    initial begin
    forever Clock=#(ClockPeriod/2)~Clock;
    end

  • --------------------------------------------------------------------------------
  • initial
    begin
    always #(ClockPeriod/2)Clock=~Clock;
    end
  • --------------------------------------------------------------------------------
  • 系统复位任务封装
  • --------------------------------------------------------------------------------
  • task reset;
    input [31:0] reset_time;	 //复位时间输入
    begin
    rst_n=RST_ING;	 //复位中
    #reset_time;	 //复位时间
    rst_n=~RST_ING;	 //撤销复位
    end
    endtask
  • --------------------------------------------------------------------------------
  • 激励信号
  • 在测试设计中使用并行激励块提供必要的激励。两种方法被考虑:绝对时间激励和相对时间激励。
  • 绝对时间激励:仿真变量被详细描述为相对于仿真时间零点。
  • 相对时间激励提供初始值,然后再重出发激励前等待一个事件。
  • --------------------------------------------------------------------------------
  • Verilog-absoulute time
  • --------------------------------------------------------------------------------
  • initial begin
    reset=1;
    load=0;
    count_updn=0;
    #100 reset=0;
    #20 load=1;
      #20 count_updn=1;
    end
  • --------------------------------------------------------------------------------
  • Verilog relative time
  • --------------------------------------------------------------------------------
  • always@(posedge clock)
    TB_Count<=TB_Count+1;
    initial begin
    if(TB_Count<5)
    begin
    reset=1;
    load=0; 
    count_updn=0;
    end
    else
    begin
    reset=0;
    load=1;
    count_updn=1;
    end
    end
    initial begin
    if(count==1100)begin
    count_updn<=0;
    $display("Terminal count reached,now counting down."); 
    end
    end
  • --------------------------------------------------------------------------------
  • Verilog HDL testebench终端显示
  • --------------------------------------------------------------------------------
  • initial begin
    $timeformat(-9,1,"ns",12);
    $display("Time clk rst ld shifitreg data sel");
    $monitor("%t%b%b%b%b%b%b%b",$realtime,clk,rst,ld,shiftreg,data,sel);
    end
  • --------------------------------------------------------------------------------
  • Verilog实现设计
  • 源代码
  • --------------------------------------------------------------------------------
  • module shift_reg(clock,reset,load,sel,data,shiftreg);
    input clock;
    input load;
    input load;
    input [1:0] sel;
    input [4:0] data;
    output [4:0] shiftreg;
    reg [4:0] shiftreg;
    always@(posedge clock)
    begin
    if(reset)
    shiftreg=0;
    else if(load)
    shiftreg=data;
    else
    case(sel)
    2'b00:shiftreg=shiftreg;
    2'b01:shiftreg=shiftreg<<1;
    2'b10:shiftreg=shiftreg>>1;
    default:shiftreg=shiftreg;
    endcase
    end
    endmodule


  • --------------------------------------------------------------------------------
  • testbench
  • --------------------------------------------------------------------------------
  • module testbench();
    reg clock;
    reg load;
    reg reset;
    wire [4:0] shiftreg;
    reg [4:0] data;
    reg [1:0] sel;
    shift_reg dut(
    .clock(clock),
    .reset(reset),
    .shiftreg(shiftreg),
    .sel(sel),
    .data(data)
    );
    
    initial beign
    clock=0;
    forever #50 clock=~clock;
    end
    
    initial begin
    reset=1;
    data=5'b00000;
    load=0;
    sel=2'b00;
    #200;
    reset=0;
    load=1;
    #200;
    data=5'b011101;
    #100;
    sel=2'b01;
    load=0;
    #200;
    sel=2'b10;
    #1000;
    $stop;
    end
    
    initial begin
    $timeformat(-9,1,"ns",12);
    $display("Time Clk Rst Ld SftRg Data Sel");
    $monitor("%t%b%b%b%b%b%b%b",$realtime,clock,reset,load,shiftreg,data,sel);
    end
    
    endmodule
  • 区别对待双向信号
  • --------------------------------------------------------------------------------
  • module bidir_infer(DATA,READ_WRITE);
    input READ_WRITE;
    inout [1:0] DATA;
    reg [1:0] LATCH_OUT;
    always@(READ_WRITE or DATA)
    begin
    if(READ_WRITE==1)
    LATCH_OUT<=DATA;
    end
    assign DATA=(READ_WRITE==1)?2'bz:LATCH_OUT;
    endmodule
  • --------------------------------------------------------------------------------
  • testbench
  • --------------------------------------------------------------------------------
  • module test_bidir_ver;
    reg read_writet;
    reg [1:0] data_in;
    wire [1:0] datat,data_out;
    bidir_infer uut(datat,read_wirtet);
    assign datat=(read_wirtet==1)?data_in:2'bZ;
    assign data_out=(read_writet==0)?datat:2'bZ;
    initial begin
    read_writet=1;
    data_in=11;
    #50 read_wirtet=0;
    end
    endmodule
  • --------------------------------------------------------------------------------

  • force/release
  • force/release 语句可以用来跨越进程对一个寄存器或一个电路网络的赋值。这
  • 结结构一般用于强制特定的设计的行为。一旦一个强制值释放,这个信号保持它
  • 的状态直到新的值被进程赋值。用法:
  • module testbench;
    ...
    initial begin
    reset=1;
    force DataOut=101;
    #25 reset=0;
    #25 release DataOut;
    ...
    ...
    end
    endmodule
  • assign/deassign
  • assign/deassign 语句与force/release 相类似,但是assign/deassign 只用于设计中
  • 的寄存器。他们一般用于设置输入值。就象一个force 语句,assign 语句超越进程
  • 语句的赋值。

  • `timescales
  • timescale 指示被用于为测试指定单位时间步。它也影响仿真器的精确度。表示
  • 符号为:‘timescale reference_time/precision Reference_time 是一个用于测量的单位时间。Precision 决定延时应该达到的精
  • 度,为仿真设置单位步距。以下是‘ timescale 的使用方法。

  • 只读存储器初始化文件
  • verilog提供了$readmemb和$readmemh命令来读取ascii文件来初始化存储器的内容。
  • $readmemb("<design.mif>",design_instance);

  • .文件说明
  • .Netlist files:HDL Code经过合成后转出的.v文件。
  • .Stimulus files:HDL变形的testbench.v经过value change dump转成.vcd,.vcd再经过VTRAN转成
  • vector file(.vec) .vec是让软体用来给netlist当input pattern用的。
  • .Configuration file

  • testbench需要注意的点
  • @与wait的区别
  • @使用沿触发。
  • wait语句都是使用电平触发。
  • $sreadmemb(h)与readmemb(h)的区别
  • $sreadmemb(Memory,StartAddr,FinishAddr,String,...):读字符串到Memory。
  • $readmemb("File",Memory [,StartAddr,[FinshAddr]]):读取的第一个数字存储在地址StartAddr直到FinishAddr。

  • .常用系统任务
  • $time 返回64位整形时间。
  • $stime 返回32位整型时间。
  • $realtime 向调用它的模块返回实型模拟时间。

  • 输入激励码产生方式:
  • 用单独的always语句或assign赋值语言产生时钟信号;
  • 用简单的initial语句块产生置/复位信号的激励;
  • 在initial语句块中用循环语句块产生按一定规律变换的信号激励码
  • 用task过程产生特殊信号的输入激励;
  • 用三态buffer产生或监控Bidirectional信号的激励
  • 必要时预估DUT的输出变换情形并加以比较。
  • 用一个或多个initial语句块产生DUT的模拟激励向量。
  • 用task、function定义DUT外部时序接口;

  • task
  • --------------------------------------------------------------------------------
  • task cpu_read;
    begin
    #30;data_valid=1;
    wait(data_read==1);
    #20;cpu_data=data_in;
    wait(data_read==0);
    #20;cpu_data=8'hzz;
    #30;data_valid=0;
    end
    endtask
  • --------------------------------------------------------------------------------