Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >FPGA 高手养成记-Test bench文件结构一览无余

FPGA 高手养成记-Test bench文件结构一览无余

作者头像
碎碎思
发布于 2020-06-30 03:25:35
发布于 2020-06-30 03:25:35
97600
代码可运行
举报
文章被收录于专栏:OpenFPGAOpenFPGA
运行总次数:0
代码可运行

文章目录

01. 前言

02. 完成的 Test bench 文件结构

03. 时钟激励设计

  • 时钟激励产生方法一
  • 时钟激励产生方法二
  • 时钟激励产生方法三
  • 时钟激励产生方法四

04. 复位信号设计

  • 复位信号产生方法一
  • 复位信号产生方法二
  • 复位信号产生方法三

05. 双向信号设计

  • 双向信号描述一
  • 双向信号描述二

06. 特殊信号设计

  • 特殊激励信号产生描述一
  • 特殊激励信号产生描述二
  • 特殊激励信号产生描述三

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

  • 仿真控制语句及系统任务描述
  • 仿真终端显示描述
  • 文本输入方式

08. 总结

01,前言

Verilog测试平台是一个例化的待测(MUT)模块,重要的是给它施加激励并观测其输出。逻辑模块与其对应的测试平台共同组成仿真模型,应用这个模型可以测试该模块能否符合自己的设计要求。

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

  • 产生模拟激励(波形);
  • 将产生的激励加入到被测试模块中并观察其响应;
  • 将输出响应与期望值相比较。

02,完成的Test bench文件结构

通常,一个完整的测试文件其结构为

  • module Test_bench();//通常无输入无输出
  • 信号或变量声明定义
  • 逻辑设计中输入对应reg型
  • 逻辑设计中输出对应wire型
  • 使用initial或always语句产生激励
  • 例化待测试模块
  • 监控和比较输出响应
  • endmodule

03,时钟激励设计

下面列举出一些常用的封装子程序, 这些是常用的写法, 在很多应用中都能用到。

3.1,时钟激励产生方法一

50%占空比时钟

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
parameter ClockPeriod=10;

initial

begin

clk_i=0;

forever

#(ClockPeriod/2) clk_i=~clk_i;

end

3.2,时钟激励产生方法二

50%占空比时钟

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
initial

begin

clk_i=0;

always #(ClockPeriod/2) clk_i=~clk_i;

end

3.3,时钟激励产生方法三:

产生固定数量的时钟脉冲

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
initial

begin

clk_i=0;

repeat(6)

#(ClockPeriod/2) clk_i=~clk_i;

end

3.4,时钟激励产生方法四

产生非占空比为50%的时钟

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
initial

begin

clk_i=0;

forever

begin

#((ClockPeriod/2)-2) clk_i=0;

#((ClockPeriod/2)+2) clk_i=1;

end

end

04,复位信号设计

4.1,复位信号产生方法一

异步复位

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

begin

rst_n_i=1;

#100;

rst_n_i=0;

#100;

rst_n_i=1;

end

4.2,复位信号产生方法二

同步复位

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

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

4.3复位信号产生方法三

复位任务封装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

input [31:0] reset_time; //复位时间可调,输入复位时间

RST_ING=0; //复位方式可调,低电平或高电平

begin

rst_n=RST_ING; //复位中

#reset_time; //复位时间

rst_n_i=~RST_ING; //撤销复位,复位结束

end

endtask

05,双向信号设计

5.1,双向信号描述一

inout在testbench中定义为wire型变量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//为双向端口设置中间变量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;

5.2双向信号描述二

强制force

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//当双向端口作为输出口时,不需要对其进行初始化,而只需开通三态门

//当双向端口作为输入时,只需要对其初始化并关闭三态门,初始化赋值需

//使用wire型数据,通过force命令来对双向端口进行输入赋值

//assign dinout=(!en) din :16'hz; 完成双向赋值

initial

begin

force dinout=20;

#200

force dinout=dinout-1;

end

06,特殊信号设计

6.1特殊激励信号产生描述一

输入信号任务封装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);

6.2特殊激励信号产生描述二

多输入信号任务封装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

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);  //按声明顺序

6.3,特殊激励信号产生描述三

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

begin

cs_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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

//wait语句都是使用电平触发

initial

begin

start=1'b1;

wait(en=1'b1);

#10;

start=1'b0;

end

07,仿真控制语句及系统任务描述

7.1,仿真控制语句及系统任务描述

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

$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之间的随机数

7.2,仿真终端显示描述

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

/*

$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 //实行实型模拟时间

7.3文本输入方式

readmemb/readmemh

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//激励具有复杂的数据结构

//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<4;i=i+1)

$display("Memory[%d]=%h",i,memory[i]);

end

endmodule

/*mem.dat文件内容

@001

AB CD

@003

A1

*/

//仿真输出为

Memory[0] = xx;

Memory[1] = AB;

Memory[2] = CD;

Memory[3] = A1;

08,总结

一个完整的设计,除了好的功能描述代码,对于程序的仿真验证是必不可少的。学会如何去验证自己所写的程序,即如何调试自己的程序是一件非常重要的事情。而RTL逻辑设计中,学会根据硬件逻辑来写测试程序,即Testbench是尤其重要的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenFPGA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
verilog经典教程(ps入门教程自学图解)
input关键词,模块的输入信号,比如input Clk,Clk是外面关键输入的时钟信号;
全栈程序员站长
2022/08/01
1.5K0
verilog经典教程(ps入门教程自学图解)
Testbench编写指南(1)基本组成与示例
文章转自:https://blog.csdn.net/FPGADesigner/article/details/82021647
碎碎思
2020/06/30
2.6K0
源码系列:基于FPGA的PS2通信电路设计(附源码)
今天给大侠带来基于FPGA的PS2通信电路设计,附源码,获取源码,请在“FPGA技术江湖”公众号内回复“PS2源码”,可获取源码文件。话不多说,上货。
FPGA技术江湖
2020/12/30
7770
ASIC数字设计:前端设计、验证、后端实现
数字系统设计中有三个重要的设计级别概念:行为级(Behavior Level)、寄存器传输级(Register Transfer Level)和门级(Gate level)。其中,
AsicWonder
2023/09/01
9070
ASIC数字设计:前端设计、验证、后端实现
FPGA综合项目——SDRAM控制器
再者就是通信处理模块,具体的通信设置,发送什么命令是写?什么命令是读?发的什么数据?等等。
全栈程序员站长
2022/09/16
6450
FPGA综合项目——SDRAM控制器
Testbench编写指南(2)文件的读写操作
文章转自:https://blog.csdn.net/FPGADesigner/article/details/80470972
碎碎思
2020/06/30
1.5K0
fpga的spi的编程_UASP协议
FPGA实现的SPI协议(二)—-基于SPI接口的FLASH芯片M25P16的使用
全栈程序员站长
2022/11/03
1.2K0
fpga的spi的编程_UASP协议
vhdl testbench实例_支持veriloghdl的工具及获取方法
一般而言,一个testbench需要包含的部分如下: (1)VHDL:entity 和 architecture的声明;Verilog:module declaration (2)信号声明 (3)实例化待测试文件 (4)提供仿真激励 其中第(4)步是关键所在,需要完成产生时钟信号,以及提供激励信号两个任务。
全栈程序员站长
2022/09/29
5130
vhdl testbench实例_支持veriloghdl的工具及获取方法
毛刺消除与输入消抖(单边毛刺滤除、双边毛刺滤除、输入防抖|verilog代码|Testbench|仿真结果)
经典电路设计是数字IC设计里基础中的基础,盖大房子的第一部是打造结实可靠的地基,每一篇笔者都会分门别类给出设计原理、设计方法、verilog代码、Testbench、仿真波形。然而实际的数字IC设计过程中考虑的问题远多于此,通过本系列希望大家对数字IC中一些经典电路的设计有初步入门了解。能力有限,纰漏难免,欢迎大家交流指正。快速导航链接如下:
Loudrs
2023/05/26
5.3K0
毛刺消除与输入消抖(单边毛刺滤除、双边毛刺滤除、输入防抖|verilog代码|Testbench|仿真结果)
verilog_移位寄存器_仿真(程序逐句解释)
  之前老是想着学的快点,就直接编译了程序就下载在开发板上跑,后来发现这样不行,因为如果程序有问题,验证和纠错的时间成本太高了(毕竟vivado跑一次花的时间很长),反过来学习仿真,下面是一点心得和体会。
全栈程序员站长
2022/09/13
9410
verilog_移位寄存器_仿真(程序逐句解释)
FPGA和外围接口-第一章 爱上FPGA(1.5 爱上FPGA从计数器开始))
在这里感谢网上各位大神和前辈的指导资料,在此一一谢过,本系列文章主要是以交流和学习为主,欢迎各位转载,转载请注明下出处,谢谢!
碎碎思
2020/06/30
5520
FPGA逻辑设计回顾(6)多比特信号的CDC处理方式之异步FIFO
异步FIFO是处理多比特信号跨时钟域的最常用方法,简单来说,异步FIFO是双口RAM的一个封装而已,其存储容器本质上还是一个RAM,只不过对其添加了某些控制,使其能够实现先进先出的功能,由于这个功能十分的实用,因此得以广泛应用。真双口RAM可以实现在一端存储,另一端读取的功能,两端的时钟可以不同,将数据存入一个容器,再取出来,这个过程在双口RAM的两端完全不存在亚稳态的问题。由于异步FIFO的实现中也存在数据的存取问题,和双口RAM类似,再加上空满信号的控制,存在跨时钟域的问题,因此只要处理好,空满信号的判断中的跨时钟域问题,就可以使用FIFO解决多比特信号的跨时钟域问题。下面从多个方面来了解一下,异步FIFO的内容,最后会给出异步FIFO的一种普遍的实现方式及其仿真,让我们一起进入今天的内容吧。
Reborn Lee
2021/01/21
1.2K0
FPGA实验3时序逻辑电路-计数器设计
【实验四】设计一个m序列码产生器模块(要求:码长为31,寄存器级数5,反馈系数为75(八进制)的m序列产生器)
timerring
2022/07/20
1.4K0
FPGA实验3时序逻辑电路-计数器设计
我眼中的UVM|只有driver的验证平台
嗨,屏幕前的你还好吗?我是不二鱼,一个不喜欢写技术博客的IC验证工程师,写这个系列,是需要很大的勇气的,因为,写得人很多,但写得好的不多,我也是如此。我一个菜鸡,敢写UVM(应该也不止UVM,我尽量把其他知识杂糅进去),我是疯了吗?至今能有比张强老师写得好的估计也没有,我之所以写,是为了促进自己进步,换了一个新的环境,使用UVM也是日常必备,所以,以写促学,写一写我眼中的UVM,也希望能和大家一起学习,相互成就,如有错误,欢迎私信我批评指正。
用户10108023
2022/10/28
5350
Testbench编写指南(3)模块化工程的仿真方法
文章转自:https://blog.csdn.net/FPGADesigner/article/details/80816066
碎碎思
2020/06/30
3.9K0
MyHDL,体验一下“用python设计电路”
下面的myhdl代码写了一个模块top,里面有两个计数器:cnt1从0计到9,当cnt1=9时,cnt2从0计到4。
ExASIC
2022/03/29
7090
MyHDL,体验一下“用python设计电路”
奇偶校验器设计(奇偶校验与奇偶检测,XOR法和计数器法|verilog代码|Testbench|仿真结果)
经典电路设计是数字IC设计里基础中的基础,盖大房子的第一部是打造结实可靠的地基,每一篇笔者都会分门别类给出设计原理、设计方法、verilog代码、Testbench、仿真波形。然而实际的数字IC设计过程中考虑的问题远多于此,通过本系列希望大家对数字IC中一些经典电路的设计有初步入门了解。能力有限,纰漏难免,欢迎大家交流指正。快速导航链接如下:
Loudrs
2023/05/14
4.2K0
奇偶校验器设计(奇偶校验与奇偶检测,XOR法和计数器法|verilog代码|Testbench|仿真结果)
源码系列:基于FPGA的 IIC 设计(附源工程)
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。
FPGA技术江湖
2020/12/29
1.4K0
源码系列:基于FPGA的 IIC 设计(附源工程)
源码系列:基于FPGA的串口UART设计(附源工程)
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。
FPGA技术江湖
2020/12/29
1.5K0
源码系列:基于FPGA的串口UART设计(附源工程)
SystemVerilog的一个简单验证demo
是一个简单的memory。就六个信号,时钟信号clk,复位信号reset(高有效),读使能信号rd_en,写使能信号wr_en,写数据信号wdata,读数据信号rdata。
数字IC小站
2020/07/01
2.1K0
推荐阅读
相关推荐
verilog经典教程(ps入门教程自学图解)
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验