Verilog测试:TestBench结构 您所在的位置:网站首页 verilog项目只能有一个tb吗 Verilog测试:TestBench结构

Verilog测试:TestBench结构

2024-06-12 00:57| 来源: 网络整理| 查看: 265

目录

1. 完整的TESTBENCH文件结构

2.时钟激励产生

3.复位信号设计

4.双向信号设计

5. 特殊信号设计

6.仿真控制语句以及系统任务描述

7.加法器的仿真测试文件编写

  

Verilog功能模块HDL设计完成后,并不代表设计工作的结束,还需要对设计进行进一步的仿真验证。掌握验证的方法,即如何调试自己的程序非常重要。在RTL逻辑设计中,要学会根据硬件逻辑来写测试程序即写Testbench。Verilog测试平台是一个例化的待测(MUT)模块,重要的是给它施加激励并观测其输出。逻辑块与其对应的测试平台共同组成仿真模型,应用这个模型就可以测试该模块能否符合自己的设计要求。

  编写TESTBENCH的目的就是为了测试使用HDL设计的电路,对其进行仿真验证、测试设计电路的功能、性能与设计的 预期是否相符。通常,编写测试文件的过程如下:

       产生模拟激励(波形)      将产生的激励加入到被测试模块中并观察其响应;      将输出响应与期望值比较。 1. 完整的TESTBENCH文件结构

 

module Test_bench()//一般简单的测试文件无输入输出 信号或变量声明定义 逻辑设计中输入信号在这里对应reg型变量 逻辑设计中的输出信号在这里对应wire型 使用initial或always语句块产生激励 例化猜测是模块UT 监控和比较输出响应 endmodule 2.时钟激励产生

 下面列举一些常用的生成时钟激励的方法:

方法一: forever

//*======================================================== 50%占空比时钟 ==========================================================*// parameter ClockPeriod = 10 ; initial beign clk_i = 0; forever # (ClockPeriod/2) clk_i = ~clk_i ; end

方法2: always块

//========================================================= 50%时钟占空比 ==============================================================*/ Parameter ClockPeriod = 10 ; initial begin clk_i =0 ; always #(ClockPeriod/2) clk_i =~clk_i ; end

方法3:产生固定数量的时钟脉冲

parameter CloclPeriod = 10 ; initial begin clk_i = 0 ; repeat(6) #(ClockPeriod/2) clk_i =~ clk_i; end

方法4:产生占空比非 50%的时钟

parameter ClockPeriod = 10 ; initial begin clk_i = 0 ; forever begin #((ClockPeriod/2)-2) clk_i = 0 ; #((ClockPeriod/2)+2) clk_i = 1; end end 3.复位信号设计

方法1:异步复位

initial begin rst_n_i = 1 ; #100 ; rst_n_i = 0 ; #100 ; rst_n_i = 1; end

方法2:同步复位

initial begin rst_n_i = 1; @(negedge clk_i) rst_n_i = 0; #100 ; //这里给的是固定时间复位 repeat(10) @(negedge clk_i) ; //这里可以设置 固定数量的时钟周期 @(negedge clk_i) rst_n_i = 1; end

方法3:对复位进行任务封装

task reset ; input[31:0] reset_timer ; //将复位的时间作为输入,达到复位时间可调的目的 RST_ING = 0 ;//复位的方式可调,低电平有效或高电平有效 begin rst_n = RST_ING ; //复位中 #reset_time //设置的复位时间 rst_n_i = ~ RST_ING ; end endtask 4.双向信号设计

双向信号的描述方式并不唯一,常用的方法如下:

描述方式1: inout在testbench中定义为wire型变量

//为双向端口设置中间变量inout_reg作为intou的输出寄存,其中inout变量定义为wire型,使用输出使能控制 //传输的方向 //inout bir_port; wire birport ; //将双向接口变量定义为wire型 reg bir_port_reg ; //定义一个reg型的中间变量,作为双向口的输出寄存 reg bi_port_oe ; //定义输出使能,用于控制传输的方向 assign birport = (bir_port_oe)?bir_port_reg:1'bz;

描述方式2:强制force

当双向端口作为输出端口时,不需要对其进行初始化,而只需开通三态门;当双向接口作为输入时,只需要对其初始化,并关闭三态门,初始化赋值需要使用wire数据,通过force命令来对双向端口进行输入赋值

//assign dinout = (!en)din: 16'hz ; 完成双向赋值 initial begin for dinout = 20 ; #200 force dinout = dinout -1 ; end 5. 特殊信号设计

1.输入信号任务的封装

方便产生激励数据。

task i_data ; input[7:0] dut_data; begin @(posedge data_en) ;send_data = 0; @(posedge data_en) ;send_data = dut_data[0]; @(posedge data_en) ;send_data = dut_data[1]; @(posedge data_en) ;send_data = dut_data[2]; @(posedge data_en) ;send_data = dut_data[3]; @(posedge data_en) ;send_data = dut_data[4]; @(posedge data_en) ;send_data = dut_data[5]; @(posedge data_en) ;send_data = dut_data[6]; @(posedge data_en) ;send_data = dut_data[7]; @(posedge data_en) ;send_data = 1; #100 ; end endtask //调用该task的方法: i_data(8'hXX) ;

2.多输入信号任务封装

task more_input; input [7:0] a; input [7:0] b; input [31:0] times ; output[8:0] c; begin repeat(times) //等待times个时钟上升沿 @(posedge clk_i) c= a+b ;//时钟上升沿, a和b相加 end endtask //调用方法: more_input(x,y,t,z);

3.输入信号产生,一次SRAM写信号产生

initial begin cs_n = 1 ; //片选无效 wr_n = 1 ; //写使能无效 rd_n =1 ; //读使能无效 addr = 8'hxx; //地址无效 data = 8'hxx; //数据无效 #100 ; cs_n = 0 ; wr_n = 0 ; addr = 8'hF1 ; data = 8'h2C ; #100 ; cs_n = 1; wr_n = 1 ; #10 ; addr = 8'hxx; data = 8'hxx; end

Testbench中的 @ 和 wait

//wait都是使用电平触发

intial begin start = 1'b1 ; wait(en = 1'b1) ; #10; start = 1'b0 ; end

 

6.仿真控制语句以及系统任务描述

仿真控制语句以及系统能够任务描述: 

$stop //停止运行仿真,modelsim中可以继续仿真 $stop(n) //带参数系统任务,根据参数0,1,或2不同,输出仿真信息 $finish //结束运行仿真,不可继续仿真 $finish(n) //带参数系统任务,根据参数的不同:0,1或2,输出仿真信息 // 0: 不输出任何信息 // 1: 输出当前仿真时刻和位置 // 2:输出房前仿真时刻、位置和仿真过程中用到的memory以及cpu时间的统计 $random //产生随机数 $random%n //产生范围-n到n之间的随机数 {$random}%n //产生范围0到n之间的随机数

仿真终端显示描述

$monitor //仿真打印输出,打印出仿真过程中的变量,使其终端显示 /* $monitor($time,,,"clk = %d reset = %d out = %d",clk,reset,out); */ $display //终端打印字符串,显示仿真结果等 /* $display("Simulation start !"); $display("At time %t,input is %b %b %b,output is %b",$time,a,b,en,z); */ $time //返回64位整型时间 $stime //返回32位整型时间 $realtiime //实行实型模拟时间

文本输入方式:$readmemb /$readmemh

//激励具有复杂的数据结构 //verilog提供了读入文本的系统函数 $readmemb/$readmemh("",); $readmemb/$readmemh("",,); $readmemb/$readmemh("",,,); $readmemb: /*读取二进制数据,读取文件内容只能包含:空白位置,注释行,二进制数 数据中不能包含位宽说明和格式说明,每个数字必须是二进制数字。*/ $readmemh: /*读取十六进制数据,读取文件内容只能包含:空白位置,注释行,十六进制数数据中不能包含位宽说明和格式说明,每个数字必须是十六进制数字。*/ /*当地址出现在数据文件中,格式为@hh...h,地址与数字之间不允许空白位置, 可出现多个地址*/ module ; reg [7:0] memory[0:3];//声明8个8位存储单元 integer i; initial begin $readmemh("mem.dat",memory);//读取系统文件到存储器中的给定地址 //显示此时存储器内容 for(i=0;i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有