FPGA验证简介之FPGA开发分析一个testbench

很多fpga/ic开发工具都提供设计例子,方便使用者学习和练习,例如,xilinx ise提供了很多设计实例,放在ise5.x的安装目录下的iseexamples目录下,例如cdma匹配滤波器、johnson计数器、pn码发生器、频率计等,这些例子是经验丰富的工程师写的,我们可以学到编程思想、代码风格等方面的知识和经验,这些东西可能从学校老师或一般书籍都学习不到。
如果你用的不是xilinx的fpga,也就是说不使用ise,那也没关系,hdl代码和testbench的设计思想和方法是一样的,你照样可以从中学到很多东西。下面以其中一个例子――同步fifo为例,分析一下我们的第一个testbench,设计的源代码可以在iseexamples目录下找到,xilinx还提供了application note详细介绍了该fifo的细节,
1.511x8同步fifo功能简介
为了对这个511x8同步fifo进行功能验证,首先要清楚它的功能,只有这样才能知道需要验证什么功能,以及如何进行验证,图1为该同步fifo的原理框图。
与异步fifo相比,同步fifo的读、写时钟是同一个时钟,简化了fifo的设计,empty和full标志的产生也比较容易,同步fifo内部使用二进制计数器记录读地址和写地址。在异步fifo中,由于读写使用不同的时钟,也就是说设计存在两个时钟域,为了减少出现亚稳态时产生的错误,记录读写地址的计数器要使用格雷码,empty和full标志的产生也比较复杂。511x8同步fifo(以下简称fifo)的工作时序如图2所示。
读fifo数据时,首先read_allow信号置高,时钟上升沿到来时read_addr地址处的数据将出现在read_data处,同时read_addr加1。让read_allow信号持续为高可以完成burst read操作。如果读出的数据是fifo的最后一个数据,那么读操作完成后empty信号变高。empty信号为高时读出来的数据是无效的。
写fifo数据时,首先write_allow信号置高,同时准备好输入数据write_data,时钟上升沿到来时,数据将写入write_addr所指向的地址中,同时write_addr加1。让write_allow信号持续为高可以完成burst write操作。如果某一个时钟上升沿时写入第511个数,那么下一个时钟沿到来的时候full信号变高,表示fifo已经写满。
我们再详细分析fifo的工作时序图。在图2中,开始时fifo的读写指针均为0,empty为高表示fifo处于空的状态,然后write_allow置高,时钟上升沿到来时写入第一个数据,empty变低;一个clk之后,read_allow置高,时钟上升沿到来时,读出数据,由于是最后一个数据,所以empty信号又变为有效(高电平)。在时序图的右半部分,写入509个数据之后,再写入两个数据,full信号变为有效,表示fifo为满。
这个fifo还有一个名为fifo_count_out的输出,从4’b0000~4’b1111,分别表示fifo满的程度从不足1/16到15/16,为某些应用提供方便。
2.验证
清楚fifo的功能之后,我们就可以开始验证工作了。验证工作的第一步是整理出fifo需要验证的功能点,这些功能点一般直接来源于fifo应该具有的功能,或者来源于它的使用方法。fifo需要验证的功能点包括:
1)fifo复位后,read_addr和write_addr为0,full为0,empty为1。
2)读fifo数据时,read_allow信号必须置高,时钟上升沿到来时read_addr地址处的数据将出现在read_data处,同时read_addr加1。
3)读出fifo的最后一个数据后,empty信号变高。
4)写fifo数据时,write_allow信号必须置高,时钟上升沿到来时,输入数据write_data将写入write_addr所指向的地址中,同时write_addr加1。
5)如果某一个时钟上升沿时写入第511个数,那么下一个时钟沿到来的时候full信号变高,表示fifo已经写满。
6)fifo_count_out端能正确的指示fifo满的程度。
分析xilinx提供的testbench可以为我们编写自己的testbench提供很好的参考。fifo的rtl代码和testbench代码放在iseexamplesfifo_ver_131和fifo_vhd_131下。以verilog代码为例,fifo_ver_131中包括了两个testbench文件,一个是功能仿真testbench文件fifoctlr_cc_tb.tf,另一个是时序仿真(后仿真)testbench文件fifoctlr_cc_tb_timing.tf,这里我们主要分析功能仿真文件,为了方便大家理解,以下(下一帖)为注释过的功能仿真testbench。大家看testbench的代码时,对照fifo需要验证的功能点,检查是不是所有功能点都经过了验证。
fifo的testbench主要包括初始化、验证initial块、读写task等内容,初始化部分主要完成复位信号、clk信号等的初始化工作,读写task把读写、delay等操作模块化,方便使用。这里主要介绍一下验证initial块,也可以说是验证的主程序,如下所示。
initial begin
delay; //保证验证环境正确复位
writeburst128; //写入512个数,full信号应该在写入511个数后变高
writeburst128;
writeburst128;
writeburst128;
read_enable = 1; //读出一个数,full信号应该变低
writeburst128; //同时读写,检查fifo操作是否正确
read_enable = 0; //读操作结束
endwriteburst; //写操作结束
delay;
readburst128; //连续读512次,empty信号应在读出511个数后变高
readburst128;
readburst128;
readburst128;
endreadburst;
end
这段程序首先延迟5个时钟周期,等初始化完成之后再开始验证工作。验证时,首先写入512个数,使用波形观察器可以检查写入的过程是否正确,以及full信号在写入511个数后是否变高;然后read_enable = 1,读出一个数,full信号应该变低,这样写操作和full信号的验证就基本完成了;程序接着也启动了写操作,由于此时read_enable仍然为高,即读写同时进行,这是对实际情况的模拟,可以对fifo的功能进行更严格的验证;最后,连续读fifo 512次,用波形观察器检查读操作是否正确,empty信号是否在读出511个数后变高,如果这些操作都是正确的,那么fifo的功能就基本正确了。
需要注意的一点是,以上的程序是不可综合的,因为不是rtl级描述,而是行为级描述(behavioral description)。行为级描述的特点是直接描述对象的功能,具有比较高的抽象层次,开发、运行速度都比rtl代码要快,因此testbench都是用行为级描述写的。关于行为级描述的特点、写法以后将有专门的章节论述。
这个testbench的特点是,输入激励由testbench产生,输出响应的检查人工完成,这样的testbench编写相对容易,可以加快开发速度,作为开发人员自己验证是非常好的选择。有些testbench能完成输入激励和输出检查,不用观察波形也能完成验证工作,这样的testbench具有更高的自动化程度,使用方便,可重复性好,当设计比较复杂而且团队中有专门的验证工程师时,一般会有验证工程师建立一套这样的testbench,用于验证开发工程师的rtl级代码,如果发现问题,开发工程师修改后在testbench再运行一次所花的时间非常少,开发复杂项目时这样做可以比用波形观察器节省很多时间。
3.总结
验证一般要通过写testbench实现,testbench要完成向dut施加激励和检查dut相应是否正确的功能,这就要求我们非常清楚待验证模块(dut)的功能,这样才知道需要验证什么、如何施加激励和如何检查响应是否正确。写testbench时, 首先要列出需要验证的功能,让后再编写testbench,这样可以做到有的放矢,避免遗漏。


核芯互联12/14/16BIT 8通道DAC产品介绍
Flyme7测试版曝光 黑科技系统?
氧化镧氧化物半导体材料经过改进后,很可能成为真正的可再生氢气的无污染的新型人造半导体材料
对比不同物联网开发平台的智能家居解决方案
微软发布exFAT文件系统规范,使用无需安装其它软件包
FPGA验证简介之FPGA开发分析一个testbench
数字货币的分类有哪些
Nordic举办全球技术巡回展 绝佳嵌入式系统+无线应用方案
!销售/收购/维修HP6012B直流电源HP6012B.小兵
新型硅铜工艺提升手持设备中射频电子系统性能
九种常用的UML合集
佩洛西窜访台湾后暂停天然砂出口影响几何?引发EDA工具断供?
首颗10nm移动处理器联发科Helio X30或年底亮相
智能的运动手表TicWatch GTX
雪佛兰这辆合资车丢光脸,标配ESP+爱信变速器,月销不到200台!
安检门如何快速识别
浴霸相机石锤!谷歌Pixel 4设备出现在公众视野
转战海外 国产手机抓紧布局产业链 印度是必争之地
5G确定性网络在工业互联网领域的应用前景探讨
在MAXQ8913微控制器中从RAM执行应用程序