同步FIFO的设计与实现
- 格式:doc
- 大小:429.50 KB
- 文档页数:20
fifo电路结构结构
FIFO电路结构是一种特殊的存储器结构,主要用于数据的缓存和传输。
FIFO,即First In First Out,意为先入先出,其特性是数据按照进入的顺序依次被读出。
这种特性使得FIFO在数据传输和缓冲中扮演着重要的角色。
FIFO电路结构主要由两部分组成:输入部分和输出部分。
输入部分负责接收数据并将其存储到FIFO中,而输出部分则负责从FIFO中读取数据并将其输出。
这种结构使得数据在FIFO中的流动呈现出一种线性、有序的状态。
在FIFO中,数据的存储和读取都是通过指针来实现的。
指针是一个地址指示器,它指向FIFO中当前要读取或写入的数据的位置。
当数据被写入FIFO时,写指针会向前移动,指向下一个可用的存储位置。
当数据被从FIFO中读取时,读指针会向前移动,指向下一个要读取的数据位置。
由于FIFO的先入先出特性,写指针和读指针的移动方向是一致的,都是从FIFO的一端向另一端移动。
FIFO电路结构有两种主要类型:触发导向结构和零导向传输结构。
触发导向结构的FIFO 由寄存器阵列构成,当满足一定条件时,数据会被写入或读取。
而零导向传输结构的FIFO 则是由具有读和写地址指针的双口RAM构成,数据的读写操作是通过地址指针来完成的。
FIFO电路结构在许多领域都有广泛的应用,如计算机系统中的缓存、数据传输、图像处理等。
由于其先入先出的特性,FIFO能够有效地缓解数据传输和处理过程中的速度不匹配问题,提高系统的整体性能。
存储器模块FIFO结构和设计实现前言:在现代系统中,为了提高系统的性能,设计者对数据的传输率、数据的传输量,对系统各部分之间的接口部分不同数据输入和接收传输率的匹配有越来越高的要求,FIFO存储器以其合理的价格、使用的方便灵活性以及对速度匹配的应用而成为解决这类问题的理想途径,尤其利用FIFO可以实现快速处理,提高控制的速度,比如我们SPI,IIC或者UART将采集的一组数据送出去,但是这些数据传送都是需要一定时间的,有时为了不耽误数据采集的时间,就可以采集的数据直接先连续的存放在缓冲区内.数据的发送交给另外一个任务去处理.这样就不会耽误数据采集任务的时间来等待每个字节的发送完毕了.因此FIFO存储器在计算机、多媒体和数据通信领域都有着广泛的应用,它的实现具有理论上和实际应用上的双重意义。
正文:存储器模块FIFO的定义及简介:FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端时AD数据采集,另一端时计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其最大传输速率为1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。
另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。
FIFO的现状:在大规模集成电路设计中,一个系统包含了很多不相关的时钟信号,当其目标域时钟与源域时钟不同时,因而在这些不同域之间传递数据成为了一个重要问题。
同步FIFO的应用
随着社会生产与研究设计对喷绘产品高速化的需求与日俱增,传统的数字喷墨式印刷机已经不能满足这种需求。
而大幅面高速彩色喷绘机无论是
在数据的传输速度还是在打印的质量上都超过了传统的数字喷墨式印刷机。
但是,大幅面高速彩色喷绘机的技术并不是十分成熟,还有许多的地方可以
改进。
近年来,随着微电子设计技术与工艺的发展,数字集成电路从电子管、晶体管、中小规模集成电路、超大规模集成电路逐步发展到今天的专用集成
电路(ASIC)。
ASIC的出现降低了产品的生产成本,提高了系统的可靠性,缩小了电路的物理尺寸,推动了社会的数字化进程[1]。
数字电路设计当中用FPGA来实现FIFO的功能可以更好地解决并行性和实时性问题,而且用FPGA实现的FIFO更容易修改和测试,可以降低成本和缩短开发周期。
1像素数据传输定时分析
像素数据传输时序如图1所示,像素数据传输在CLK的同步下进行,每次传送256&TImes;2bit,使用256个CLK时钟。
在传输开始前和传输结束后,CLK应该保持在高电平。
每次传输完后,等待3个连续的像素时钟。
第29卷第1期 2006年2月电 子 测 量 技 术EL ECT R ON IC M EASU R EM EN T T ECH N OL OG Y信息技术利用FPGA 实现同步FIFO 设置方法刘志杨 郭继昌 关 欣 黄彩彩 天津大学摘 要 文中在Q ua rtus 环境中,用V H DL 作为编程语言,实现用F PG A 器件对同步FIF O 设置的方法,在基于DSP 的图像处理系统中达到使同步FIF O 高效完成数据缓冲作用的目的。
这种方法对F IFO 的使用具有很好的借鉴意义。
关键词 先进先出(FIFO) 硬件描述语言 偏置寄存器Method of using FPGA to realize synchronous FIFO configurationL iu Zhiyang G uo Jichang Guan X in Huang CaicaiAbstract In this paper,a config ur ation method of synchro no us FI FOs w ith FP GA and V HD L lang uag e is realized in the Quar tus develo pment envir onment.A nd the pur po se o f effect ive data buffer with sy nchro no us F IFO s is obtained in the infrar ed imag e processing system based on DSP.T his metho d is o f import ant r eference v alue to the utility o f FIF Os.Keywords F IFO har dw are descr iption lang uage offset r egister1 系 统在基于DSP 的红外图像数据处理系统中,FIFO 器件IDT72V263[1]用作高速DSP 与低速设备的缓冲接口,系统的原理框图如图1所示。
怎么⽤Verilog语⾔描述同步FIFO和异步FIFO感谢知乎龚⼤佬打杂⼤佬⽹上⼏个nice的博客(忘了是哪个了。
)前⾔虽然FIFO都有IP可以使⽤,但理解原理还是⾃⼰写⼀个来得透彻。
什么是FIFO?Fist in first out。
先⼊先出的数据缓存器,没有外部读写地址线,可同时读写。
规则:永远不要写⼀个已经写满了的fifo。
永远不要读⼀个读空了的fifo。
FIFO种类?同步FIFO和异步FIFO。
同步FIFO只有⼀个时钟,也就是说写端和读端的时钟是⼀⽑⼀样的。
异步FIFO读端和写端两个时钟则是不⼀样的。
包括同频异相,异频异相。
FIFO⽤途?1. 数据缓冲器。
⽐如你写端burst⼀个数据,没有fifo缓冲的话就炸了。
Fifo会把写端的突发数据吃到肚⼦⾥,读端可以慢慢的⼀个个读出来。
2. 跨时钟域。
异步fifo主要使⽤在不同时钟域的边缘,⽤来同步数据到另⼀个时钟域。
3.ALTERA FIFO IP 的缺点是什么?虽然altera贴⼼的提供了FIFO的IP块,但是对于可移植性与⾃定义位宽深度更好的话,还是⾃⼰写的更佳。
FIFO深度如何计算?(避免溢出)对于异步fifo,如果读时钟⼤于写时钟且每个周期读写,那么⼀定是会读空的,反之⼀定会被写满。
⼀般来说,不会设计这么⽆聊的东西。
假设写端有突发的数据,⽽读端是均匀的读出,怎么保证fifo不溢出呢?异步FIFO快转慢的问题:可能采样踩不到某些值。
同步FIFO:当缓冲器使⽤,可以⽤ram资源搭。
原理图:信号定义:clk:时钟信号rst_n:异步复位信号wr:写请求rd:读请求data:数据输⼊q:数据输出full:满信号,表⽰fifo吃饱了empty:空信号,表⽰fifo肚⼦已经空掉了usedw:表⽰fifo中已有的数据个数仿真:没有usedw款:有usedw款:资源使⽤量:如何设计⼀个异步FIFO?⼀般⽤作跨时钟域,可⽤ram搭。
判断读空与写满,读写指针要跨时钟域,所以采⽤格雷码减少亚稳态。
同步fifo的设计原理同步FIFO的设计原理概述同步FIFO(First-In-First-Out)是一种常用的数据缓存器,用于在数据的产生与消费之间进行数据传输。
本文将从浅入深,分步骤地介绍同步FIFO的设计原理。
设计目标同步FIFO的设计旨在解决数据产生与消费之间的速度差异问题。
具体来说,它需要实现以下目标: - 确保数据的顺序性:数据按照进入FIFO的顺序被读取,保持“先进先出”的特性 - 确保数据的完整性:数据不会在传输过程中丢失或损坏 - 处理不匹配的产生和消费速度:当数据的传输速度不匹配时,FIFO能够进行适当的流量控制,以确保数据的稳定传输和存储基本原理同步FIFO的设计基于以下几个基本原理:写入过程1.写指针(Write Pointer):用于指示下一个数据写入的位置2.存储单元(Storage Element):用于存储数据的内部单元3.信号控制线(Control Signal Line):用于控制写入操作的时序,如写使能信号(Write Enable)读取过程1.读指针(Read Pointer):用于指示下一个数据读取的位置2.信号控制线:用于控制读取操作的时序,如读使能信号(ReadEnable)同步机制为了确保数据的顺序性和完整性,同步FIFO采用了以下同步机制:1. 读写指针同步:读取操作与写入操作之间存在同步关系,保证数据按照正确的顺序被读取 2. 写使能同步:写使能信号与写指针同步,确保只有在正确的时刻写入数据 3. 读使能同步:读使能信号与读指针同步,确保只有在正确的时刻读取数据流控制为了处理数据产生与消费速度不匹配的情况,同步FIFO采用了流控制机制: 1. 读写时钟同步:读写操作在同一个时钟周期内完成,通过同步读写时钟,确保数据传输的稳定性和一致性 2. FIFO空闲状态检测:通过判断FIFO的存储区是否为空,进行流量控制,避免数据丢失或溢出 3. 推、拉操作:当数据产生速度快于消费速度时,FIFO可以通过推操作将多余的数据推出;当消费速度快于产生速度时,FIFO可以通过拉操作补充数据总结同步FIFO是一种常用的数据缓存器,可以解决数据产生与消费速度不匹配的问题。
课程设计报告题目:同步FIFO的设计姓名:**学号:********组员:罗文奇冷原野指导老师:杞宁杨小平目录目录............................................................................. 错误!未定义书签。
第1章课程设计的要求 .. (3)1.1 课程设计的目的 (3)1.2 课程设计的条件 (3)1.3 课程设计的要求 (3)第2章课程设计的内容 (4)2.1 设计思路 (4)2.2 软件流程图 (3)2.3 Verilog代码阐述 (3)2.4 ModelSim验证 (5)第3章课程设计的心得 (13)第1章课程设计的要求1.1 课程设计的目的●通过运用Verilog语言编写程序,体会程序的逻辑性,掌握基本的程序开发的注意事项。
在实践中,学习掌握简单、周全的编程方法●掌握较大工程的基本开发技能●培养综合运用Modelsim,Quartus II工具进行硬件开发的能力●培养数字系统设计的基本能力●理解FIFO的定义与功能,掌握FIFO的verilog编写方法1.2 课程设计的条件●FIFO的定义与功能●Modelism仿真工具1.3 课程设计的要求●FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
●使用Verilog语言和Modelsim仿真器完成同步FIFO的设计和验证第2章课程设计的内容2.1 设计思路FIFO的核心部分即为一计数器,与指针。
通过计数器来决定当前栈的状态,通过指针来将数据按顺序写入或者读取。
由FIFO得的定义可以定义输入输入及内部变量:(图2)输入:data_in: 输入数据端口,位宽为8位;rd_en: 读使能端,当read_n=0时,可以读出数据;wr_en: 写使能端,当write_n=0时,可以写入数据;clock: 时钟信号,在时钟的正边沿进行采样;rst: 复位信号,当reset_n=0时,计数器及读写都被清零(即:读写地址指针都指向0)输出:data_out: 输出数据端口,位宽为8位;;full:FIFO状态信号,当full=1时,表明该FIFO存储器已经写满;empty:FIFO状态信号,当empty=1时,表明该FIFO存储器已经读空;2.2 软件流程图顶层模块划分及功能实现该同步fifo可划分为如下四个模块,如图1所示:①存储器模块(RAM)——用于存放及输出数据;②读地址模块(rd_addr) ——用于读地址的产生;③写地址模块(wr_addr)——用于写地址的产生④标志模块(flag_gen)---- 用于产生FIFO当前空满状态。
292练习十二利用 SRAM 设计一个 FIFO在本练习中,要求同学利用练习十一中提供的 SRAM 模型,设计 SRAM 读写控制逻辑, 使 SRAM 的行为对用户表现为一个 FIFO (先进先出存储器。
1 设计要求:本练习要求同学设计的 FIFO 为同步 FIFO,即对 FIFO 的读/写使用同一个时钟。
该 FIFO 应当提供用户读使能(fiford和写使能(fifowr输入控制信号,并输出指示FIFO 状态的非空 (nempty 和非满 (nfull信号, FIFO 的输入、输出数据使用各自的数据总线:in_data 和2 FIFO 接口的设计思路FIFO 的数据读写操作与 SRAM 的数据读写操作基本上相同,只是 FIFO 没有地址。
所以用 SRAM 实现 FIFO 的关键点是如何产生正确的 SRAM 地址。
我们可以借用软件中的方法, 将 FIFO 抽象为环形数组, 并用两个指针:读指针(fifo_rp 和写指针(fifo_wp控制对该环形数组的读写。
其中,读指针 fifo_rp指向下一次读操作所要读取的单元,并且每完成一次读操作, fifo_rp加一;写指针 fifo_wp则指向下一次写操作时存放数据的单元,并且每完成一次写操作, fifo_wp加一。
由fifo_rp和 fifo_wp的定义易知 , 当 FIFO 被读空或写满后, fifo_rp和 fifo_wp将指向同一单元, 但在读空和写满之前 FIFO 的状态是不同的,所以如果能区分这两种状态,再通过比较 fifo_rp和 fifo_wp就可以得到 nempty 和 nfull 信号了。
下图为 FIFO 工作状态的示意。
N单元内有数据单元内无数据一般情况再写即满再读即空在得到 nfull 和 nempty 信号后,就需要考虑如何应用这两个信号来控制对 FIFO 的读写,使得 FIFO 在被写满后不能再写入,从而防止覆盖原有数据,并且在被读空后也不能再进行读操作,防止读取无效数据。
FIFO同步、异步以及Verilog代码实现FIFO 很重要,之前参加的各类电⼦公司的逻辑设计的笔试⼏乎都会考到。
FIFO是英⽂First In First Out 的缩写,是⼀种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使⽤起来⾮常简单,但缺点就是只能顺序写⼊数据,顺序的读出数据, 其数据地址由内部读写指针⾃动加1完成,不能像普通存储器那样可以由地址线决定读取或写⼊某个指定的地址。
FIFO⼀般⽤于不同时钟域之间的数据传输,⽐如FIFO的⼀端是AD数据采集, 另⼀端是计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,⽽PCI总线的速度为33MHz,总线宽度32bit,其最⼤传输速率为 1056Mbps,在两个不同的时钟域间就可以采⽤FIFO来作为数据缓冲。
另外对于不同宽度的数据接⼝也可以⽤FIFO,例如单⽚机位8位数据输出,⽽ DSP可能是16位数据输⼊,在单⽚机与DSP连接时就可以使⽤FIFO来达到数据匹配的⽬的。
FIFO的分类根均FIFO⼯作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。
同步FIFO是指读时钟和写时钟为同⼀个时钟。
在时钟沿来临时同时发⽣读写操作。
异步FIFO是指读写时钟不⼀致,读写时钟是互相独⽴的。
FIFO设计的难点 FIFO设计的难点在于怎样判断FIFO的空/满状态。
为了保证数据正确的写⼊或读出,⽽不发⽣益处或读空的状态出现,必须保证FIFO在满的情况下,不 能进⾏写操作。
在空的状态下不能进⾏读操作。
怎样判断FIFO的满/空就成了FIFO设计的核⼼问题。
.........................................................................................................................................同步FIFO的Verilog代码之⼀在modlesim中验证过。
一、同步FIFO的意思是说FIFO的读写时钟是同一个时钟,不同于异步FIFO,异步FIFO的读写时钟是完全异步的。
同步FIFO的对外接口包括时钟,清零,读请求,写请求,数据输入总线,数据输出总线,空以及满信号。
下面分别对同步FIFO的对外接口信号作一描述:1.时钟,输入,用于同步FIFO的读和写,上升沿有效;2.清零,输入,异步清零信号,低电平有效,该信号有效时,FIFO被清空;3.写请求,输入,低电平有效,该信号有效时,表明外部电路请求向FIFO写入数据;4.读请求,输入,低电平有效,该信号有效时,表明外部电路请求从FIFO中读取数据;5.数据输入总线,输入,当写信号有效时,数据输入总线上的数据被写入到FIFO中;6.数据输出总线,输出,当读信号有效时,数据从FIFO中被读出并放到数据输出总线上;7.空,输出,高电平有效,当该信号有效时,表明FIFO中没有任何数据,全部为空;8.满,输出,高电平有效,当该信号有效时,表明FIFO已经满了,没有空间可用来存贮数据。
使用VHDL描述的FIFO将以上面的接口为基础,并且可以参数化配置FIFO 的宽度和深度。
二、同步FIFO内部通过控制电路和RAM实现,控制电路主要包括写指针管理电路,读指针管理电路,以及FIFO状态判断电路,对于同步FIFO来讲,读和写的指针管理电路实际上就是二进制计数器。
现在的FPGA都具有Block RAM,通过VHDL描述可以对其进行调用,为了能够实现任意深度和宽度的FIFO,那么在用VHDL描述RAM的时候需要使用generic 使得RAM的调用能够参书化。
同样,对于读写指针计数器,也需要参数化的描述方法。
下面主要对FIFO的状态判断如何判断进行一些说明。
假设宽度任意而深度为8的FIFO,当读指针read_pointer和写指针write_pointer的值一样的时候,很显然,这时FIFO的状态为空。
比较麻烦的是对FIFO是否已经满的状态的判断,因为存在两种情况,第一种情况时写指针write_pointer比读指针read_pointer 大,比如writer_pointer = 7而read_pointer = 0,还有一种情况时写指针writer_pointer比读指针read_pointer小,比如writer_pointer = 2而read_pointer = 3。
同步缓冲器(FIFO)的设计与实现姓名:学号:012004022102班级:2010级测控1班院系:控制系专业:测控技术与仪器同组人姓名:(说明:我们三个人前面的报告部分是一样的,因为课设基本是三个人商议完成,所以就感觉报告部分没什么不同的就只写了一份报告)目录1原理与系统设计 (3)2设计思想 (4)3源码与注释 (5)4仿真 (12)5综合 (15)6心得体会与建议 (19)1 原理与系统设计FIFO(First In First Out)——是一种可以实现数据先入先出的存储器件。
FIFO就像一个单向管道,数据只能按固定的方向从管道一头进来,再按相同的顺序从管道另一头出去,最先进来的数据必定是最先出去。
FIFO被普遍用作数据缓冲器。
FIFO的基本单元是寄存器,作为存储器件,FIFO的存储能力是由其内部定义的存储寄存器的数量决定的。
本题中所设计的是同步FIFO(即输出输入端时钟频率一致),异步复位,其存储能力为(16x8),输出两个状态信号:full与empty,以供后继电路使用。
根据系统要求,画出的系统框图,如图1所示clockreset 读控制信号写控制信号inputfullemptyoutput 图1同步FIFO框图端口说明:输入:in_data: 输入数据端口,位宽为8位;read_n: 读使能端,当read_n=0时,可以读出数据;write_n: 写使能端,当write_n=0时,可以写入数据;clock: 时钟信号,在时钟的正边沿进行采样;reset_n: 复位信号,当reset_n=0时,计数器及读写都被清零(即:读写地址指针都指向0)输出:out_data: 输出数据端口,位宽为8位;;full:FIFO状态信号,当full=1时,表明该FIFO存储器已经写满;empty:FIFO状态信号,当empty=1时,表明该FIFO存储器已经读空;FIFO满的情况下,不能再写,写指针不能加1;FIFO空的情况下,不能再读,读指针不能加1;2 设计思想由以上的系统框图和端口分析,我们将设计的重点定在了解决以下三个核心问题上:1.FIFO的存储体如何表示?2.如何实现“先进先出”的逻辑功能?3.如何知道FIFO内部使用了多少,是满是空?针对以上三个问题,我们所采取的方法是:1.定义一个16×8的二维数组来表示FIFO的存储体。
2.为了实现“先进先出”的逻辑功能,我们定义了“读指针”及“写指针”,分别用来指示读操作与写操作的位置。
3.为了表示FIFO是满还是空,我们定义了一个计数器,用以标志FIFO已使用了多少空间。
在解决了以上三个重点问题以后,针对同步FIFO的逻辑功能,我们拟定了以下一个结构图,如图2所示:图2 FIFO设计结构图3.源码与注释3.1源代码我们在完成了之前两步的准备工作之后,进行了源码的设计,具体的代码如下:`define DEL 1 //为了使仿真接近真实情形,我们定义了从时钟到输出的延时module sfifo(clock,reset_n,in_data,read_n,write_n,out_data,full,empty);//输入信号input clock; //输入时钟input reset_n; //复位信号,低有效input[7:0] in_data; //输入的数据input read_n; //读控制信号,低有效input write_n; //写控制信号,低有效//输出信号output[7:0] out_data; //FIFO的输出数据output full; //FIFO满标志信号output empty; //FIFO空标志信号//信号声明reg [7:0] out_data;reg [7:0] fifo_mem[15:0]; //FIFO存储体即8*16存储器,用数组表示reg [4:0] counter; //计数器表示FIFO中已用了多少reg [3:0] rd_pointer; //FIFO读指针,指向下次读操作的地址reg [3:0] wr_pointer; //FIFO读指针,指向下次读操作的地址//赋值声明,给出满标志与空标志的实现assign #`DEL full=(counter==16)?1'b1:1'b0;assign #`DEL empty=(counter==0)?1'b1:1'b0;//本模块实现读指针、写指针和计数器的功能always@(posedge clock or negedge reset_n)beginif(~reset_n)begin //计数器及读、写指针清零rd_pointer<=#`DEL 4'b0;wr_pointer<=#`DEL 4'b0;counter<=#`DEL 5'b0;endelsebeginif(~read_n)begin//如果FIFO为空,不能再读,并报错if(counter==0)//检查fifo是否溢出(empty)begin$display("\nERROR at time %0t:",$time);$display("FIFO Underflow\n");$stop; //终止系统任务,用于调试end//读有效,写无效时,计数器减1if(write_n)begincounter<=#`DEL counter-1;end//如果读指针已指到最后一个位置,则返回起始位置if(rd_pointer == 15)rd_pointer <= #`DEL 4'b0;elserd_pointer <= #`DEL rd_pointer + 1;endif(~write_n)//检查fifo是否溢出(full)beginif(counter>=16)begin$display("\n ERROR at time %0t:", $time);$display("FIFO overflow\n");$stop;endif(read_n)//写有效,读无效时,计数器加1begincounter <= #`DEL counter + 1;endif(wr_pointer == 15)//如果写指针已指到最后一位,则返回起始位置wr_pointer <= #`DEL 4'b0;elsewr_pointer <= #`DEL wr_pointer + 1;endendendalways@(posedge clock)//本模块实现数据的读写功能beginif(~write_n)beginfifo_mem[wr_pointer] <= #`DEL in_data;endif(~read_n)beginout_data <= #`DEL fifo_mem[rd_pointer];//读取数据endendendmodule3.2测试文件本设计中为了让输入激励能够完整地测试出设计的功能,以证明FIFO确实能起到数据缓冲的作用,因而要测试当读写速度不一致的情况,即要仿真写速度大于读速度的情形以及读速度大于写速度的情形。
测试文件中:异步复位如下进行:reset_n=1; #20 reset_n=0; #20 reset_n=1;时钟信号如下产生:always #100 clock<=~clock;写入数据递增加1产生:in_data <= in_data + 1;而编写测试文件的核心问题在于:在同一文件中如何既能仿真写快与读的情形又能仿真读快于写的情形?对此,我们的想法:先让写快于读以达到满的状态(full=1),而后让读快于写以达到排空的状态(empty=1)由此我们定义了两个状态信号:fast_read: fast_read=1时以高速度进行读操作fast_write:fast_write=1时以高速度进行写操作又为了让读和写的速度产生差异,我们定义了一个周期计数信号cycle_count(其周期计数的值为......01010101......),它用来控制生成读写使能信号,控制方式为:当fast_write=1时,只要FIFO 非满就使写入,得到写使能信号;在非空的情况下,当cycle_count==1时才产生读使能信号;当fast_read=1时,只要FIFO非空就使读取,得到读使能信号;在非满的情况下,当cycle_count==1时才产生写使能信号;从而达到了让快的一方速度是慢的一方速度2倍的效果。
在解决了以上核心问题之后,具体的测试代码如下://DEFINES`define DEL 1 //时钟到输出的延时module test_sfifo(clock,reset_n,in_data,read_n,write_n,out_data,full,empty);//INPUTSinput [7:0]out_data;input empty,full;//OUTPUTSoutput clock,reset_n,read_n,write_n;output [7:0]in_data;//信号声明,这些信号应与测试模块中的端口信号一一对应reg clock;reg reset_n;reg[7:0] in_data; //输入到端口in_data的激励信号reg read_n;reg write_n;wire[7:0] out_data; //从端口out_data输出的信号wire full;wire empty ;//定义需要的一些信号integer fifo_count; //记录FIFO中的字节数,定义为实型整数reg[7:0] exp_data; //期望从FIFO输出的数据reg fast_read; //标志以高速度进行读操作reg fast_write; //标志以高速度进行写操作reg filled_flag; //标志FIFO已填满reg cycle_count; //周期计数,用来生成读写控制信号//对FIFO进行实例化sfifo Sfifo(.clock(clock),.reset_n(reset_n),.in_data(in_data),.read_n(read_n),.write_n(write_n),.out_data(out_data),.full(full),.empty(empty));initial beginin_data=0;exp_data=0;fifo_count=0;read_n=1;write_n=1;filled_flag=0;cycle_count=0;clock=1;//写速度大于读速度fast_write=1;fast_read=0;//复位reset_n=1;#20 reset_n=0;#20 reset_n=1;//初始情况下,FIFO应该为空,即empty==1且full==0if(empty!==1)begin$display("\nERROR at time %0t:",$time);$display("After reset,empty status not asserted\n");//报错$stop;endif(full!==0)begin$display("\nERROR at time %0t:",$time);$display("After reset,empty status not asserted\n");$stop;endend//生成时钟信号always #100 clock<=~clock;//对FIFO中的字节数进行计数。