xiaobaibai

testbench文件构架

0
阅读(1973)
  1. DUT(design under test)

    激励信号--输入->待测模块--输出—>波形数据输出->波形的验证->验证结果

                                 预期输出时序波形

 2.Testench代码设计风格

    a)Testbench文件头编写规范

        与VerilogHDL完全一样

    b)Module列表编写规范

`timescale 1ns/1ns
module Testbench_tb;
wire [7:0] led_data;
endmodule

    Testbench不同于Verilog HDl的地方是没有输入输出类的信号定义,每个激励都是在当前文件中生成的,唯一与外界通信的wire是直连到需要测试的Module上的。而Testbench中的Module信号列表是当前文件需要输出的信号。此处顶层文件定义了led_data为输出信号,便于在modelsim中添加并且观察波形。另外:

    (1)Module前必须写时间尺度;

    (2)Module后紧跟Testbench需要输出的信号(当模块多时,紧跟当前Module);

    (3)相关信号必须写在一起,并注释。

备注:虽然不添加wire信号也无所谓,可以直接在波形中添加待测试Module的信号,但是wire后,设计测试脚本更加清晰。

    c)时钟发生器编写规范

//---------------------------
//clock generate module
reg clk;
reg rst_n;
localparam PERIOD=20; //50mhz
initial
begin
    clk=0;
    forever #(PERIOD/2)
    clk=~clk;
end

task task_reset;
begin
    rst_n=0;
    repeat(2) @(negedge clk)
    rst_n=1;
end
endtask

    理解Testbench可以完全按照c语言的思路,Testbench完全是线程的设计,当然也可以实现always类的并行设计,但是任务的调用必须是线程的。Testbench通过任务的调用来实现激励。规范如下:

      (1)该模块放在Testbench的Module之后,必须有且仅有一次定义;

      (2)时钟可以通过PERIOD的宏定义修改;

      (3)类似时钟的生成可以参考此部分clk设计。

    d)模块的例化编写规范

    这部分与verilog HDl设计规范完全相同,直接调用需要测试的模块,通过例化完成线路的连接,作为Modelsim分析的目标电路,如:

//------------------------
//the target component instantiation
reg spi_cs;
reg spi_sck;
reg spi_mosi;
//--------------------
//SPI data receive from MCU
wire rxd_flag;
wire [7:0] rxd_data;
spi_receiver u_spi_receiver
(
    //global clock
    .clk                  (clk_ref),
    .rst_n                (sys_rst_n),
    
    //mcu spi interface
    .spi_cs               (spi_cs),
    .spi_sck              (spi_sck),
    .spi_mosi             (spi_mosi),
    //.spi_miso            (spi_miso),
    
    //user interface
    .rxd_flag             (rxd_flag),
    .rxd_data             (rxd_flag)
)

    e).系统的初始化编写规范

    考虑到电路上电都有一个初始化阶段,Testbench为了实现完整的激励,也有必要生成一个系统的初始化模块,该模块如下:

//--------------------------
//system initialiation
task task_sysinit;
begin
    spi_cs=1;
    spi_sck=1;
    spi_mosi=0;
end
endtask

该模块简洁明了,唯一的规范便是保证所有输出信号都需要初始化,否则不能正常仿真。

  f).生成系统的测试激励

    Testbench可以通过设计Task功能来实现任务的模块化编写及调用,而这些部分的目的就是为了在最后生成待测试文件的测试激励,如下:

//------------------------------------
//testbench of the RTL
initial
begin
    task_sysinit;
    task_reset;
    
    repeat(5)@(posedge);
    task_mcu_spi_txd(8'h95);
end

   在测试激励生成的代码编写规范中,需遵循以下几点:

(1)采用initial设计,生成现成的激励;

(2)必须先进行系统初始化,接着进行复位,然后才能进行其他的激励;

(3)为了代码的可读性及可移植性,激励都通过task去编写及调用,保证代码清晰,便于修改;

(4)同一功能的激励规划在一起,并且需要必要的注释。


//来自FPGA设计技巧与案例开发详解