0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Verilog Testbench怎么写 Verilog Testbench文件的编写要点

FPGA之家 来源:FPGA之家 2023-08-01 12:44 次阅读

之前在使用VerilogFPGA项目中、以及其他一些不同的场合下,零散的写过一些练手性质的testbench文件,开始几次写的时候,每次都会因为一些基本的东西没记住、写的很不熟练,后面写的时候稍微熟练了一点、但是整体编写下来比较零碎不成体系,所以在这里简要记录一下一般情况下、针对小型的verilog模块进行测试时所需要使用到的testbench文件的编写要点。

本文主要参考了在网上找到的Lattice公司的“A Verilog HDL Test Bench Primer”手册中的有关内容。谢谢!

模块实例化、reg&wire声明、initial和always块的使用

需要测试的模块(Verilog-module)被称为DUT(Design Under Test),在testbench中需要对一个或者多个DUT进行实例化。

Testbench中的顶层module不需要定义输入和输出。

Testbench中连接到DUT instance的输入的为reg类型、连接到DUT instance的输出的为wire类型。

对于DUT的inout类型变量,在testbench中需要分别使用reg、wire类型的变量进行调用。

例如,对于下面这样一个待测试module:

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_writet);

assign datat = (read_writet == 1) ? data_in : 2'bZ;
assign data_out = (read_writet == 0) ? datat : 2'bZ;

initial begin
read_writet = 1;
data_in = 11;
#50 read_writet = 0;
end

endmodule

和普通的Verilog模块中一样、使用assign对wire类型的变量进行赋值。

需要留意的一点是:对于没有在代码中赋初始值的变量,wire类型变量被初始化为Z、reg类型变量被初始化为X。

always和initial是两种对reg变量进行操作的串行控制块。每个initial和always块都会在仿真开始时同时开始运行。

常见的,可以利用它们生成模块所需的时钟和复位信号,如下:

‘timescale 1 ns / 100 ps

reg clk_50, rst_l;

initial
begin
$display($time, " << Starting the Simulation >>");
clk_50 = 1’b0; // at time 0
rst_l = 0; // reset is active
#20 rst_l = 1’b1; // at time 20 release reset
end

always
#10 clk_50 = ~clk_50; // every ten nanoseconds invert

首行定义了时间单位/时间精度。时间单位为1ns,这样生成的clk_50时钟周期就是20ns、也就是频率为50MHz。

复位信号rst_l在初始为0复位态、在20ns之后为1解除复位。

仿真中的停止、变量监视和输出

有两种仿真控制函数:$finish和$stop。其中,$finish任务用于终止仿真并跳出仿真器;$stop任务则用于中止仿真。在Modelsim中,$stop任务则是返回到交互模式。

如果需要监视仿真中某个变量的变化情况,可以使用$monitor函数:

$monitor($time, " clk_50=%b, rst_l=%b, enable_l=%b, load_l=%b, count_in=%h, cnt_out=%h, oe_l=%b, count_tri=%h", clk_50, rst_l, enable_l, load_l, count_in, cnt_out, oe_l, count_tri);

每当变量列表中的任一变量发生变化,就会产生输出。

如果需要在仿真控制台屏幕打印输出,可以使用$display函数:

$display($time, "<< count = %d - Turning OFF count enable >>",cnt_out);

任务Task的用法

可以将一组重复性的或者相关的命令组合到一起构成一个任务。

任务通常可以在initial或者always块中被调用。

一个任务可以拥有输入、输出、以及inouts,也可以包含计时或延时元素。

以一个在FPGA上实现的简单SPI接口为例。外部设备为主、FPGA为从,命令一共32bit,构成为“1位读写命令字(1读0写)+14位地址+1位NO CARE+16位数据”,片选信号拉低之后通信开始,时序如下图:

a96c99fc-3006-11ee-9e74-dac502259ad0.png

数据流由外设到FPGA时(FPGA为接收),外设在SCLK的下降沿更新MOSI;FPGA在SCLK的上升沿将MOSI上的值抓取到移位寄存器

当FPGA为发送方时,FPGA在SCLK的下降沿更新MISO线上的输出,外设在SCLK的上升沿将MISO上的值抓取过来。

外设可以通过该SPI接口访问FPGA内部生成的寄存器。

当对FPGA上的spi模块进行读测试时,外设发给FPGA的读指令为:

{1'b1,address,1'b0,data(读取到的16bit数据)}

为此编写的任务spi_read可以是:

task spi_read;
input[13:0]    address;
output[15:0]    data;
reg [31:0] output_register;
reg [15:0]input_register;
integer i;
    begin
       $display("time:%t----------------task spi_read",$time );
            #100;
            spi_clk = 1'b0;
            spi_csn = 1'b1;
            spi_mosi =1'b0;
            output_register = {1'b1,address,1'b0,16'd0};
            
            $display("time:%t,testbench read output_register: %h,",$time,output_register );
            $display("time:%t,testbench read address: %h",$time,address );
            
            spi_csn = 1'b1;
            for(i = 0 ; i < 16 ; i=i+1)
                begin
                    spi_csn = 1'b0;
                    spi_clk = 1'b0;
                    spi_mosi = output_register[31-i];
                    #100;
                    spi_clk = 1'b1;
                    #100;
                end
                
            for(i = 0 ; i < 16 ; i=i+1)
                begin
                    spi_csn = 1'b0;
                    spi_clk = 1'b0;
                    #100;
                    spi_clk = 1'b1;
                    input_register[15-i] = spi_miso;
                    #100;
                end
            spi_csn = 1'b1;
            
            
            data = input_register;
            $display("time:%t,testbench spi_read read data: %h,",$time,input_register );
            
            $display("time:%t----------------",$time );
            #100;
    end

endtask

(其中仿真的时间单位为1ns,spi时钟频率为10MHz)

示例及汇总

根据前述内容,自我总结一般简单的testbench文件的结构形式可以是如下:

`timescale 1 ns / 1 ns

module testbench_module_top;
reg 
reg
……
wire
wire
……

//reset and clock definition
initial begin …end
initial begin …end

//actual testing flows
initial 
begin 
//variables initialization
a = 
b = 
…

task_1(var_1… var_N)
…
task_N(var_1… var_N)
$stop;
…end


//dut module instance
module_top U1
(
.var1(),
.var2(),
…
.varN()
)

//necessary control logic for testbench module test flow
always@(...)

//tasks definition
task task_1;
input …;
output …;
……
//action flow
……
endtask

……

task task_N;
……
endtask

endmodule

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1602

    文章

    21320

    浏览量

    593194
  • 模块
    +关注

    关注

    7

    文章

    2484

    浏览量

    46530
  • Verilog
    +关注

    关注

    28

    文章

    1326

    浏览量

    109302
  • HDL
    HDL
    +关注

    关注

    8

    文章

    323

    浏览量

    47101
  • DUT
    DUT
    +关注

    关注

    0

    文章

    180

    浏览量

    11997

原文标题:Testbench文件编写纪要(Verilog)

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    怎样在Verilogtestbench测试VHDL模块??

    怎样在Verilogtestbench测试VHDL模块??一个vhdl的工程模块,怎么用verilog
    发表于 08-01 22:54

    Verilog

    各位大神们,我是刚开始学Verilog的菜鸟,最近testbench总是出错,还请大家能告诉我测试模块到底是有个怎样的规则呢,比如下面这个四位全加器代码的
    发表于 10-18 14:59

    testbench设置的问题

    本帖最后由 平漂流 于 2017-5-21 11:09 编辑 如图,看Verilog仿真视频教程里面,在testbench设置时候,直接复制“blocking_vlg_tst”到top
    发表于 05-21 11:04

    请问如何使用ISE verilogtestbench代码测量程序的准确功率?

    嗨,大家好,现在我正在努力测量程序的功能,我已经有了verilog代码和testbench,有谁知道如何从中获取功率值?或任何相关信息? :)
    发表于 04-24 09:45

    verilog每日一练】testbench编写基本结构

    根据如下模块,编写对应的testbench文件
    发表于 09-08 10:35

    testbench编写基本结构

    testbench编写基本结构
    发表于 09-28 17:43

    编写高效率的testbench

    编写高效率的testbench,学习编写测试文件的小伙伴们。
    发表于 05-11 16:40 16次下载

    testbench_book

    verilog Testbench
    发表于 12-13 22:20 3次下载

    如何使用VHDL实现testbench编写

    大多数硬件设计人员对 verilogtestbench 比较熟悉,那是因为 verilog 被设计出来的目的就是为了用于测试使用,也正是因为这样 verilog 的语法规则才被设
    发表于 12-14 08:00 17次下载

    使用matlab产生待滤波信号并编写testbench进行仿真分析

    本讲使用matlab产生待滤波信号,并编写testbench进行仿真分析,在Vivado中调用FIR滤波器的IP核进行滤波测试,下一讲使用两个DDS产生待滤波的信号,第五讲或第六讲开始编写ve
    的头像 发表于 04-27 18:18 3980次阅读
    使用matlab产生待滤波信号并<b class='flag-5'>编写</b><b class='flag-5'>testbench</b>进行仿真分析

    VHDL与Verilog硬件描述语言如何用TestBench来进行仿真

    小的设计中,用TestBench来进行仿真是一个很不错的选择。 VHDL与Verilog语言的语法规则不同,它们的TestBench的具体写法也不同,但是应包含的基本结构大体相似,在VHDL的仿真
    的头像 发表于 08-04 14:16 3370次阅读

    使用Matlab和Verilog实现fibonacci序列包括源代码和testbench

    使用Matlab和Verilog实现fibonacci序列包括源代码和testbench(电源技术论坛app)-使用Matlab和Verilog实现fibonacci序列,包括源代码和test
    发表于 09-16 14:41 13次下载
    使用Matlab和<b class='flag-5'>Verilog</b>实现fibonacci序列包括源代码和<b class='flag-5'>testbench</b>

    Verilog testbench总结

    对于testbench而言,端口应当和被测试的module一一对应。端口分为input,output和inout类型产生激励信号的时候,input对应的端口应当申明为reg, output对应的端口申明为wire,inout端口比较特殊,下面专门讲解。
    发表于 07-07 15:23 4458次阅读

    testbench是什么? testbench测试的机制是什么?

    废话不多说直接上干货,testbench就是对写的FPGA文件进行测试的文件,可以是verilog也可以是VHDL。
    的头像 发表于 06-28 16:44 2255次阅读
    <b class='flag-5'>testbench</b>是什么? <b class='flag-5'>testbench</b>测试的机制是什么?

    VHDL与Verilog硬件描述语言TestBench编写

    小的设计中,用TestBench来进行仿真是一个很不错的选择。VHDL与Verilog语言的语法规则不同,它们的TestBench的具体写法也不同,但是应包含的基本结构大体相似,在VHDL的仿真
    的头像 发表于 09-09 10:16 888次阅读
    VHDL与<b class='flag-5'>Verilog</b>硬件描述语言<b class='flag-5'>TestBench</b>的<b class='flag-5'>编写</b>