TestBench基本写法与语法详解
一、TestBench简介
一个完整的设计,除了好的功能描述代码,对于程序的仿真验证是必不可少的。学会如何去验证自己所写的程序,即如何调试自己的程序是一件非常重要的事情。而 RTL 逻辑设计中,学会根据硬件逻辑来写测试程序,即Testbench 是尤其重要的。 Verilog 测试平台是一个例化的待测(MUT) 模块,重要的是给它施加激励并观测其输出。逻辑模块与其对应的测试平台共同组成仿真模型,应用这个模型可以测试该模块能否符合自己的设计要求。
编写 TESTBENCH 的目的是为了对使用硬件描述语言设计的电路进行仿真验证,测试设计电路的功能、性能与设计的预期是否相符。通常,编写测试文件的过程如下:
• 产生模拟激励(波形);
• 将产生的激励加入到被测试模块中并观察其响应;
• 将输出响应与期望值相比较。
二、完整的 Test bench文件结构
通常,一个完整的测试文件其结构为
`timescale 仿真单位/仿真精度module Test_bench();//通常无输入无输出信号或变量声明定义
逻辑设计中输入对应 reg 型
逻辑设计中输出对应 wire 型
使用 initial 或 always 语句产生激励
例化待测试模块
监控和比较输出响应endmodule
声明仿真的单位和精度
三、时钟激励设计
下面列举出一些常用的封装子程序,这些是常用的写法,在很多应用中都能用到。
/*----------------------------------------------------------------
时钟激励产生方法一: 50%占空比时钟
----------------------------------------------------------------*/
parameter ClockPeriod=10;
initialbeginclk_i=0;forever#(ClockPeriod/2) clk_i=~clk_i;end
/*----------------------------------------------------------------
时钟激励产生方法二: 50%占空比时钟
----------------------------------------------------------------*/
initialbeginclk_i=0;always #(ClockPeriod/2) clk_i=~clk_i;end
/*----------------------------------------------------------------
时钟激励产生方法四:产生固定数量的时钟脉冲
----------------------------------------------------------------*/
initialbeginclk_i=0;repeat(6)#(ClockPeriod/2) clk_i=~clk_i;end
/*----------------------------------------------------------------
时钟激励产生方法五:产生非占空比为 50%的时钟
----------------------------------------------------------------*/
initialbeginclk_i=0;foreverbegin#((ClockPeriod/2)-2) clk_i=0;#((ClockPeriod/2)+2) clk_i=1;endend
四、复位信号设计
/*----------------------------------------------------------------
复位信号产生方法一:异步复位
----------------------------------------------------------------*/
initialbeginrst_n_i=1;#100;rst_n_i=0;#100;rst_n_i=1;end
/*----------------------------------------------------------------
复位信号产生方法二:同步复位
----------------------------------------------------------------*/
initialbeginrst_n_i=1;@(negedge clk_i)rst_n_i=0;#100; //固定时间复位repeat(10) @(negedge clk_i); //固定周期数复位@(negedge clk_i)rst_n_i=1;end
/*----------------------------------------------------------------
复位信号产生方法三:复位任务封装
----------------------------------------------------------------*/
task reset;input [31:0] reset_time; //复位时间可调,输入复位时间RST_ING=0; //复位方式可调,低电平或高电平beginrst_n=RST_ING; //复位中#reset_time; //复位时间rst_n_i=~RST_ING; //撤销复位,复位结束end
endtask
五、双向信号设计
/*----------------------------------------------------------------
双向信号描述一: inout 在 testbench 中定义为 wire 型变量
----------------------------------------------------------------*///为双向端口设置中间变量 inout_reg 作为 inout 的输出寄存,其中 inout 变
//量定义为 wire 型,使用输出使能控制传输方向//inout bir_port;
wire bir_port;
reg bir_port_reg;
reg bi_port_oe;
assign bi_port=bi_port_oe ? bir_port_reg : 1'bz;/*----------------------------------------------------------------
双向信号描述二:强制 force
----------------------------------------------------------------*///当双向端口作为输出口时,不需要对其进行初始化,而只需开通三态门
//当双向端口作为输入时,只需要对其初始化并关闭三态门,初始化赋值需
//使用 wire 型数据,通过 force 命令来对双向端口进行输入赋值
//assign dinout=(!en) din :16'hz; 完成双向赋值initialbeginforce dinout=20;#200force dinout=dinout-1;end
六、 特殊信号设计
/*----------------------------------------------------------------
特殊激励信号产生描述一:输入信号任务封装
----------------------------------------------------------------*/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//调用方法: i_data(8'hXX);
/*----------------------------------------------------------------
特殊激励信号产生描述二:多输入信号任务封装
----------------------------------------------------------------*/task more_input;input [7:0] a;input [7:0] b;input [31:0] times;output [8:0] c;beginrepeat(times) //等待 times 个时钟上升沿@(posedge clk_i)c=a+b; //时钟上升沿 a, b 相加end
endtask//调用方法: more_input(x,y,t,z); //按声明顺序
/*----------------------------------------------------------------
特殊激励信号产生描述三:输入信号产生,一次 SRAM 写信号产生
----------------------------------------------------------------*/initialbegincs_n=1; //片选无效wr_n=1; //写使能无效rd_n=1; //读使能无效addr=8'hxx; //地址无效data=8'hzz; //数据无效#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'hzz;end/*----------------------------------------------------------------
Testbench 中@与 wait
----------------------------------------------------------------*///@使用沿触发
//wait 语句都是使用电平触发
initialbeginstart=1'b1;wait(en=1'b1);#10;start=1'b0;end
七、repeat ,wait函数
//==========================================
//== repeat重复执行
//==========================================
initial beginstart = 1;repeat(5) @(posedge clk) //等待5个时钟上升沿start = 0;
endinitial beginrepeat(10)begin...//执行10次end
end//===========================================
//== wait为电平触发
//==========================================
initial beginstart = 1;wait(en); //等待en==1start = 0;
end
八、随机数的产生
$random //产生随机数
$random % n //产生范围 {-n,n} 的随机数
{$random} % n //产生范围 { 0,n} 的随机数
九、文本输入输出
reg [a:0] data_mem [0:b]; //定义位宽为(a+1)深度为(b+1)的存储器
$readmemb/$readmemh("<读入文件名>",<存储器名>);
$readmemb/$readmemh("<读入文件名>",<存储器名>,<起始地址>);
$readmemb/$readmemh("<读入文件名>",<存储器名>,<起始地址>,<结束地址>);$readmemb
/*------------------------------------------------------------------------*\读取二进制数据,读取文件内容只能包含:空白位置,注释行,二进制数数据中不能包含位宽说明和格式说明,每个数字必须是二进制数字。
\*------------------------------------------------------------------------*/$readmemh
/*------------------------------------------------------------------------*\读取十六进制数据,读取文件内容只能包含:空白位置,注释行,十六进制数数据中不能包含位宽说明和格式说明,每个数字必须是十六进制数字.
\*------------------------------------------------------------------------*/
//==========================================================================
//== 输出txt文件
//==========================================================================
integer fp_write; //定义initial beginbeginfp_write = $fopen("output.txt"); //打开输出文件begin$fwrite(fp_write, "\n%h", output_data); //写入数据16进制#(`clk_period);endend$fclose(fp_write); //关闭文件,不可少
end
十、打印信息
$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 位整型时间$realtime //实行实时模拟时间
十、testbench总体代码结构
`timescale 1ns/1ps //时间精度
`define clk_perilod 20 //时钟周期可变module test_file_tb;//==================<端口>==================================================
reg clk ; //时钟,50Mhz
reg rst_n ; //复位,低电平有效
reg [XX:0] in ; //
wire [XX:0] out ; ////--------------------------------------------------------------------------
//-- 模块例化
//--------------------------------------------------------------------------
my_design u_my_design
(.clk (clk ),.rst_n (rst_n ),.in (in ),.out (out )
);//----------------------------------------------------------------------
//-- 时钟信号和复位信号
//----------------------------------------------------------------------
initial beginclk = 0;forever#(`Clock/2) clk = ~clk;
endinitial beginrst_n = 0; #(`Clock*20+1);rst_n = 1;
end//----------------------------------------------------------------------
//-- 设计输入信号
//----------------------------------------------------------------------
initial beginin = 0;#(`Clock*20+2); //初始化完成$stop;
endendmodule在这里插入代码片
TestBench基本写法与语法详解相关推荐
- Velocity魔法堂系列二:VTL语法详解
一.前言 Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页模板引擎,而且可以作为普通文本的模板引擎来增强服务端程序文本处理能力.而且Velocity被移植到不 ...
- js 正则中冒号代表什么_javascript中正则表达式语法详解
好久都没有写博客了,主要是太懒了,尤其是在阳春三月,风和日丽的日子,太阳暖暖的照在身上,真想美美的睡上一觉.就导致了这篇博客拖到现在才开始动笔,javascript的正则这一块也不是什么新的东西,主要 ...
- MarkDown语法详解(Typora编辑器)
MarkDown语法详解(Typora编辑器) 即使再小的帆也能远航~ 目录 Mrakdown简介 Markdown标题 Markdown字体 各种线 引用 图片 超链接 列表 表格 代码 锚(mao ...
- Spring Data JPA 之 @Query 语法详解及其应用
5 Spring Data JPA 之 @Query 语法详解及其应用 5.1 快速体验 @Query 的方法 沿⽤我们之前的例⼦,新增⼀个 @Query 的⽅法: // 通过 query 注解根据 ...
- SpringBoot yaml语法详解
SpringBoot yaml语法详解 1.yaml基本语法 2.yaml给属性赋值 3.JSR303校验 4.SpringBoot的多环境配置 1.yaml基本语法 通常情况下,Spring Boo ...
- MySQL常用操作之创建存储过程语法详解
MySQL常用操作之创建存储过程语法详解 前言 简介 语法 创建结构 变量结构 入参变量和出参变量 流程控制 判断(IF 语句) 判断(CASE 语句) 循环(LOOP 语句) 循环(WHILE 语句 ...
- Go 语言快速开发入门(基础语法详解,第一节)
Go 语言快速开发入门(基础语法详解,第一节) 一.基础语法详解,第一节 1.HelloWorld 1.1.代码编写和解释 1.2.go语言注意事项 2.Go 语言的转义字符&&Go ...
- Android.mk语法详解
前言 目前 Android 工程可以通过 .mk.或者 .cmake 的形式构建 NDK 工程,较新的 Android 工程一般采用的是 .cmake 构建 NDK 源码,而相对创建时间久的工程则大多 ...
- Python的Xpath介绍和语法详解
1.简介 XPath是一门在XML和HTML文档中查找信息的语言,可以用来在XML和HTML文档中对元素和属性进行遍历 XPath的安装 Chrome插件XPath Helper 点Chrome浏览器 ...
- FreeMarker基本语法详解及模板文件的组成(二)
海浪上次给大家分享了FreeMarker基本语法详解及模板文件的组成(一)海浪今天继续分享FreeMarker基本语法详解及模板文件的组成(二) 3.2 输出变量值<?xml:namespace ...
最新文章
- Nginx源码安装及应用
- JavaScript语言基础9
- sql升级重启计算机失败win10,win10一直提示重启安装更新失败如何处理
- 大数据新手的0基础学习路线,从菜鸟到高手的成长之路
- 记一次EF Core连接MySql、Oracle
- 【最全最详细】publiccmsCSS和JS引入无效的解决方法
- 图解SQL的inner join、left join、right join、full outer join、union、union all的区别
- haproxy开启日志功能
- 互联网公司招聘奇葩黑历史:不要学日语,不要信中医,不要黄泛区……
- 使用web.xml控制Web应用的行为
- MySQL(11)-----多表创建及描述表关系(多对多的分析和实现)
- 关闭Linux 内存地址随机化机制
- 学习笔记︱Nvidia DIGITS网页版深度学习框架——深度学习版SPSS
- FX DocuPrint M268 dw打印机硒鼓清零
- 根据两点坐标计算两点距离
- 【Wifi密码破解】安卓手机、电脑如何破解Wifi密码
- ES6 isFinite()
- ​华为回应出售手机业务传闻:假消息;微软将ChatGPT整合到更多工具中:不用写代码就能开发应用;苹果更新Mac产品线|极客头条...
- libjpeg与turbo libjpeg的使用
- 2022-2027年中国冷冻果汁行业发展监测及投资战略研究报告
热门文章
- linux 命令:chmod详解
- 一位全减器逻辑电路图_全减器(全减器逻辑电路图)
- html+css制作一个浪漫爱心表白网页 表白网页在线制作 最浪漫的表白网页
- java 表头固定_固定表头在快逸报表中的设定
- 天锐绿盾加密软件如何制作外发文件
- 使用R语言进行时间序列分析
- 关于semantic-ui的cdn失效问题(怎样通过本地引用semantic-ui)
- Win10自定义开始菜单磁贴背景颜色及图标
- 题目:身份证录入系统 一、语言和环境 a)实现语言Java, 使用Android开发环境实现《身份证录入系统》APP。
- 51单片机蜂鸣器实现歌曲《起风了》代码