同步缓冲器(FIFO)的设计与实现..
同步FIFO与异步FIFO
同步FIFO之VHDL描述同步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的宽度和深度。
先把对外接口描述出来吧。
----------------------------------------------------------------------------------------------------------- Designer : skycanny-- Date : 2007-1-29-- Description : Synchronous FIFO created by VHDLlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity sfifo isgeneric(width : positivedepth : positive);port(clk : in std_logic;rst : in std_logic;wq : in std_logic;rq : in std_logic;data : in std_logic_vector(width - 1 downto 0);q : in std_logic_vector(width - 1 downto 0);empty : out std_logic;full : out std_logic);end entity sfifo;下面的框图主要描述同步FIFO的内部结构,画出框图有助于对电路结构的理解,同样也有助于RTL 代码的编写:异步FIFOFIFO (先进先出队列)是一种在电子系统得到广泛应用的器件,通常用于数据的缓存和用于容纳异步信号的频率或相位的差异。
同步FIFO的设计与实现
同步缓冲器(FIFO)的设计与实现姓名:学号:012004022102班级:2010级测控1班院系:控制系专业:测控技术与仪器同组人姓名:(说明:我们三个人前面的报告部分是一样的,因为课设基本是三个人商议完成,所以就感觉报告部分没什么不同的就只写了一份报告)目录1原理与系统设计 (3)2设计思想 (4)3源码与注释 (5)4仿真 (12)5综合 (15)6心得体会与建议 (19)1 原理与系统设计FIFO(FirstIn FirstOut)——是一种可以实现数据先入先出的存储器件。
FIFO就像一个单向管道,数据只能按固定的方向从管道一头进来,再按相同的顺序从管道另一头出去,最先进来的数据必定是最先出去。
FIFO被普遍用作数据缓冲器。
FIFO的基本单元是寄存器,作为存储器件,FIFO的存储能力是由其内部定义的存储寄存器的数量决定的。
本题中所设计的是同步F I FO(即输出输入端时钟频率一致),异步复位,其存储能力为(16x8),输出两个状态信号:full与e m pty,以供后继电路使用。
根据系统要求,画出的系统框图,如图1所示clockreset 读控制信号写控制信号inputfullemptyoutput 图1同步FI F O框图端口说明:输入:in_dat a: 输入数据端口,位宽为8位;read_n:读使能端,当read_n=0时,可以读出数据;write_n: 写使能端,当write_n=0时,可以写入数据;clock:时钟信号,在时钟的正边沿进行采样;reset_n: 复位信号,当reset_n=0时,计数器及读写都被清零(即:读写地址指针都指向0)输出:out_da ta: 输出数据端口,位宽为8位;;full:FIFO状态信号,当full=1时,表明该FIF O存储器已经写满;empty:FIFO状态信号,当empty=1时,表明该FIF O存储器已经读空;FIFO满的情况下,不能再写,写指针不能加1;FIFO空的情况下,不能再读,读指针不能加1;2 设计思想由以上的系统框图和端口分析,我们将设计的重点定在了解决以下三个核心问题上:1.FIFO的存储体如何表示?2.如何实现“先进先出”的逻辑功能?3.如何知道FI FO内部使用了多少,是满是空?针对以上三个问题,我们所采取的方法是:1.定义一个16×8的二维数组来表示FI FO的存储体。
VLSI课程设计——同步FIFO的设计与实现
VLSI课程设计同步FIFO设计与实现班级:学号:姓名:指导教师:VLSI课程设计报告——同步FIFO设计与实现一、FIFO概述FIFO是英文First In First Out的缩写,意为先入先出存储器,由于微电子技术的飞速发展,新一代FIFO芯片容量越来越大,体积越来越小,价格越来越便宜。
作为一种新型大规模集成电路,FIFO芯片以其灵活、方便、高效的特性,逐渐在高速数据采集、高速数据处理、高速数据传输以及多机处理系统中得到越来越广泛的应用。
它与普通随机存储器的区别是没有外部读写地址线,这样使用起来非常方便但缺点就是只能顺序读写数据,其读写数据地址依靠内部的读指针和写指针完成。
读操作与写操作可以异步进行,写入区上写入的数据按照写入的顺序从读取端的区中读出,类似于吸收写入端与读出端速度差的一种缓冲器。
计算机的串口,一般也都具有FIFO缓冲器(不是单一的FIFO存储器,而是嵌入在设备内部)。
二、同步FIFO同步FIFO(S ynchronous FIFO,下称SFIFO)的意思是说FIFO的读写时钟是同一个时钟,因此时钟频率是相同的,只是在相位上可能有差别,不同于异步FIFO,异步FIFO的读写时钟是完全异步的。
SFIFO的对外接口包括时钟,清零,读请求,写请求,数据输入总线,数据输出总线,空以及满信号。
查阅资料找到一款成型SFIFO产品的接口描述,如图1:图1 一款同步FIFO的接口资料为了更好的理解FIFO的工作方式,我们设定SFIFO的深度为8。
SFIFO的难点主要是状态判断,如图2是对空状态和满状态来进行判断的方式。
图2 FIFO空满状态判断可以看出,当读指针和写指针的值一样的时候,FIFO的状态为空。
比较麻烦的是对FIFO是否已经满的状态的判断,因为存在两种情况,第一种情况时写指针比读指针大,比如写指针= 7而读指针= 0,还有一种情况时写指针比读指针小,比如写指针= 2而读指针= 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的存储体。
存储器模块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的FPGA设计及仿真
摘要电子科技大学成都学院University of Electronic Science and technology ChengduUniversity本科毕业设计(论文)同步FIFO的FPGA设计与仿真学院名称成都学院专业名称机械制造设计及其自动化学生姓名冯川学号2840840634指导教师钟耀霞二〇一二年六月摘要同步FIFO的FPGA的设计及仿真摘要:为实现目标识别与跟踪的应用目的,在基于TMS320DM642的FIFO基础上拓展储存空间,提出一种FPGA实现SDRAM控制器的方法。
分析所用SDRAM的特点及工作原理,介绍FPGA中SDRAM控制器的组成及工作流程。
给出应用中的SDRAM的时序图,FPGA采用模块化设计,增强SDRAM控制器的通用性,更方便满足实际需求。
关键词:FIFO ;SDRAM控制器;FPGA ;实时跟踪IAbstractDesign and Simulation of FIFO Based on FPGAAbstract: In order to achieve the application of target recognition and tracking, the memory on the basis of TMS320DM642 FIFO is expanded. SDRAM controller of the implementation basing on the FPGA is designed ,Firstly, the characteristics and principles of SDRAM are analyzed. Then characteristics and principles of SDRAM controller and work flow in FPGA are introduced, The application in time of SDRAM timing, chart is given. In order to meet the actual needs more convenient and enhance the versatility of SDRAM controller FPGA used modular designKey words: FIFO ; SDRAM controller ;FPGA ;real-trackingII目录目录电子科技大学成都学院 (16)第一章引言 (1)1.1选题背景 (1)1.2研究目标和意义 (1)1.3 研究思路 (2)第二章FIFO设计 (3)2.1 FIFO系统设计 (5)2.2 FIFO的实现及控制 (6)1.3亚稳态 (8)2.3.1什么是亚稳态 (8)2.3.2 亚稳态发生原因 (8)2.3.3亚稳态的危害 (8)2.3.4亚稳态的解决方法 (9)2.4.关于FIFO的一点的思考 (9)第三章FPGA结构及工作原理 (11)3.1什么是FPGA (11)3.1.1逻辑阵列 (11)3.1.2嵌入式阵列 (13)3.1.3快速通道 (13)3.14I/o单元与专用输入端口 (13)3.2 FPGA基本结构图 (14)3.2.1查找表 (14)IR (14)3.2.2结构的FPGA逻辑实现原理 (15)3.2.3PGA查找表单元内部结构 (16)3.2.4基于LUT的FPGA逻辑单元(LE)内部结构 (16)3.3VHDL 语言 (17)3.4Quartus II (18)第四章利用FPGA实现同步FIFO设置方法 (19)4.1非对称同步FIFO设计难点 (19)4.2非对称同步FIFO设计 (20)4.3方案实现 (23)4.4FIFO类型 (25)4.5系统 (26)4.6 FPGA 设计 (27)III目录4.7 FPGA内部软FIFO的设计 (29)4.8 FPGA内部软FIFO的仿真 (31)总结 (33)参考文献 (34)致谢 (35)译文 (36)IV第一章引言第一章引言1.1选题背景FIFO 是一种常用于数据缓存的电路器件,可应用于包括高速数据采集、多处理器接口和通信中的高速缓冲等各种领域。
同步FIFO
Transmit Data in
Data word #n
. .
Data Data Data Data
word word word word
#3 #2 #2 #1
Receive Data Out 图1 FIFO functional diagram
Write Pointer
empty empty Data word #n
FIFO 应用
高速同步数据采集卡
同步FIFO在高速视频图像采集处理系统中的应用 高速同步FIFO存储器在数字信号源中的应用
应用——
高速同步FIFO存储器在数字信号源中的应用
高速数字信号源是数字信号处理系统中的一种常用设备,目的是 输出人为编制的任意数字信号,用来验证和测试后续数字处理设备的 功能和性能指标。对于一个大型的数字系统而言,高速数字信号源的 研制是必不可少的。 数字信号源主要采用CYPRESS 公司的CY7C4245芯片来实现对数据 流的高速转换、处理,其设计思想在多种领域中都具有广泛的应用价 值。
5.在时钟的下降沿处 a.判断读操作时,out_data是否等于exp_data,否则stop; b.cycle_count加1; c.当(fast_write||cycle_count&1’b1)&&~full时,write_n=0, in_data加1; 否则 write_n=1; d.当(fast_read||cycle_count&1’b1)&&~empty时,read_n=0 , exp_data加1,否则read_n=1; e.当full=1时, fast_write=0 ,fast_read=1,filled_flag=1; f.当filled_flag=1&&empty 时,仿真结束; 6.在fifo_count值发生变化时,检测empty、full、half三个状态信号是否正 确;当fifo_count=depth时, fast_write=1 ,fast_read=0, filled_flag=1 。
同步fifo的设计代码和分析
同步fifo的设计代码和分析《IC设计基础》同步fifo的设计行为级的描述:比较简单,因为是同步,所以只有一个时钟,读使能和写使能要保证不能同时有效,就是说,读的时候就读,不能写,写的时候就写不能读。
<错误!读和写可以同时进行的,只要保证不读空,不写满就可以了,只是说counter计数器的加减是在要么读使能要么写使能有效的情况下进行的>主要是要产生两个标志位:空,满。
当空的时候就不能再读了,当满的时候就不能再写了。
设计中考虑了调试,所以出错的地方会自动停止程序,进行调试。
输入和输出信号都是8位,fifo的深度是15.使用的是异步复位.因为fifo比较小,所以没有调用ram(fifo相当于是一个管子,一端进,一端出(先进的先出),堆栈相当于是一个水缸,先进的后出,后进的先出)同步fifo的使用场合:,,,,,,,,注意count计数器的设计目的.可以使得读写同时进行(只要有的读就可),也可以只读或只写,(只要保证不读空不写满就可)`define DEL 1modulesynfifo(clock,reset_n,data_in,read_n,write_n,data_out,full,empty);input clock,reset_n,read_n,write_n; input [0:7] data_in;output [0:7] data_out;output full,empty;wire clock,reset_n,read_n,write_n;//输入定义为线型,这条是可以省略的,系统默认 wire [0:7] data_in;reg [0:7] data_out;wire full,empty;//?reg[7:0] fifo_mem[14:0];//定义fifo的大小,用寄存器组表示宽为8深为15 reg [3:0] counter;//计数器,这是很重要的reg[3:0] rd_pointer;//读指针reg[3:0] wr_pointer;//写指针assign #`DEL full=(counter==15)?1'b1:1'b0;//计数到15说明写满了assign #`DEL empty=(counter==0)?1'b1:1'b0;//计数到0说明读空了(需要先写满,再去读空呢,还是先写一部分,然后从这部分读空???)可以同时读和写,对fifo不同的位置always @(reset_n)if(~reset_n)begin#`DEL;rd_pointer<=4'b0;wr_pointer<=4'b0;counter<=4'b0;endalways @(posedge clock)beginif(~read_n)//只要读信号有效就开始读beginif(counter==0)//code 1,读空了,就停止begin$display("\nERROR at time %0t:",$time);$display("\FIFO Underflow\n");$stop;endif(write_n)//非常重要的信号counter,,通过计数保证不读空不写满 . 时钟到来时,读有效,写无效时减1,读无效,写有效时加一 ,count有点像一个水位仪,要保证不在最高端也不在最底端,只有写时,水位仪上升一格,只有读时水位仪下降一格,有读有写或者不读也不写时,水位仪保持不动)begincounter<=counter-1;enddata_out<=#`DEL fifo_mem[rd_pointer];//把指针所指位置的值送给输出if(rd_pointer==14)rd_pointer<= #`DEL 4'b0;elserd_pointer<=rd_pointer+1;endif(~write_n)//只要出现写使能有效就开始写beginif(counter==15)begin$display("\nERROR at time %0t:",$time);$display("FIFO Overflow\n");$stop;endif(read_n)begincounter<=#`DEL counter+1;endfifo_mem[wr_pointer]<=#`DEL data_in;if(wr_pointer==14)wr_pointer<=#`DEL 4'b0;elsewr_pointer<=#`DEL wr_pointer+1;endendendmodule最妙的是testbench的书写,简直不是人写的,比fifo设计本身还要复杂`define DEL 10module syn_tb;reg clock,reset_n,read_n,write_n; reg [7:0] in_data;wire [7:0] out_data;wire full,empty;integer fifo_count; ///为什么要定义为integer类型呢,常用来表示行为级建模,整数的 reg [7:0] exp_data;//期望值,设定好了是0-1-2-3……reg fast_read,fast_write;//调试读比写快的情况,写比读快的情况. reg filled_flag;reg cycle_count;synfifosynfifo_tb(.clock(clock),.reset_n(reset_n),.data_in(in_data),.read_n (read_n),.write_n(write_n),.data_out(out_data),.full(full),.empty(empty));initialbeginin_data=0;exp_data=0;fifo_count=0;read_n=1;write_n=1;filled_flag=0;cycle_count=0;clock=1;fast_read=0;fast_write=1;reset_n=1;#20 reset_n=0;#20 reset_n=1;if(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("\nerror at time %0t:",$time);$stop;endendalways #100 clock=~clock;always @(posedge clock)beginif(~write_n && read_n)//只写不读时fifo加1fifo_count=fifo_count+1;else if(write_n && ~read_n)//只读不写时fifo减1fifo_count=fifo_count-1;endalways @(negedge clock)beginif(~read_n && (out_data!==exp_data))//读时,读出数据不对,调试begin$display("\nerror at time %0t:",$time);$display("expected data out=%h",exp_data);$display("actual data out=%h\n",out_data);$stop;endif((fast_write||(cycle_count&1'b1))&&~full)//生成写控制信号write_n,生成输入信号in_databeginwrite_n=0;in_data=in_data+1;endelsewrite_n=1;if((fast_read||(cycle_count&1'b1))&&~empty)//生成读控制信号read_n,生成期望信号;beginread_n=0;exp_data=exp_data+1;endelseread_n=1;if(full)//数据满时,读比写要快,设立满标志beginfast_read=1;fast_write=0;filled_flag=1;endif(filled_flag&&empty)//若曾经写满过,又读空了,则结束仿真begin$display("\nsimulation complete -no errors\n"); $finish;endcycle_count=cycle_count+1;//0101交替endalways@(fifo_count)begin# `DEL;# `DEL;# `DEL;case (fifo_count)0:beginif((empty!==1)||(full!==0))begin$display("\nerror at time %0t:",$time);$display("fifo_count=%h",fifo_count);$display("empty=%h\n",empty);$display("full=%h\n",full);$stop;endif(filled_flag==1)begin$display("\nsimulation complete -no error\n");//程序在写满并读空后就停止仿真$finish;endend15:beginif((empty!==0)||(full!==1))begin$display("\nerror at time %0t:",$time);$display("fifo_count=%h",fifo_count);$display("empty=%h\n",empty);$display("full=%h\n",full);$stop;endfilled_flag=1;fast_write=0;fast_read=1;enddefault:beginif((empty!==0)||(full!==0))//正常读写时出现读空标志和写满标志有效,则调试begin$display("\nerror at time %0t:",$time); $display("fifo_count=%h",fifo_count); $display("empty=%h\n",empty);$display("full=%h\n",full);$stop;endendendcaseendendmodule。
同步FIFO设计
同步FIFO设计同步fifo设计1.功能定义:用16*8 RAM实现一个同步先进先出(FIFO)队列设计。
由写使能端控制该数据流的写入FIFO,并由读使能控制FIFO中数据的读出。
写入和读出的操作由时钟的上升沿触发。
当FIFO的数据满和空的时候分别设置相应的高电平加以指示。
2.顶层信号定义:3.顶层模块划分及功能实现该同步fifo可划分为如下四个模块,如图1所示:①存储器模块(RAM)——用于存放及输出数据;②读地址模块(rd_addr) ——用于读地址的产生;③写地址模块(wr_addr)——用于写地址的产生④标志模块(flag_gen) ---- 用于产生FIFO当前空满状态。
图1 同步FIFO的模块划分1) RAM模块本设计中的FIFO采用采用16*8双口RAM,以循环读写的方式实现;l 根据rd_addr_gen模块产生的读地址,在读使能(rd_en)为高电平的时候,将RAM中rd_addr[3:0]地址中的对应单元的数据在时钟上升沿到来的时候,读出到data_out[7:0]中。
l 根据wr_addr_gen产生的写地址和在写使能(wr_en)为高电平的时候,将输入数据(data_in[7:0]) 在时钟上升沿到来的时候,写入wr_addr[3:0]地址对应的单元。
以下是ram程序:moduleram(clk,wr_en,rd_en,data_in,wr_addr,rd_addr,data_out);input clk;input rd_en;input wr_en;input[7:0]data_in;input[3:0]wr_addr;input[3:0]rd_addr;output[7:0]data_out;reg [7:0]data_out;parameter max_count=5'b10000;reg [7:0]fifo[0:max_count];//读操作always @ (posedge clk )beginif(rd_en)data_out<=fifo[rd_addr];end//写操作always @ (posedge clk )beginif(wr_en)fifo[wr_addr]<=data_in;endendmodule2)wr_addr_gen:该模块用于产生FIFO写数据时所用的地址。
同步fifo设计实验报告
课程设计报告题目:同步FIFO的设计姓名: 贾安乐学号:20105000学院:电子科学与应用物理学院专业:电子科学与技术10-3 组员: 徐健勋、兰伯章指导老师:杨小平、杞宁日期:2014.12.15一.课程设计要求1.课程设计的目的通过运用Verilog语言编写程序,体会程序的逻辑性,掌握基本的程序开发的注意事项。
在实践中,学习掌握简单、周全的编程方法。
掌握较大工程的基本开发技能。
培养综合运用Modelsim,Quartus II工具进行硬件开发的能力。
培养数字系统设计的基本能力。
理解FIFO的定义与功能,掌握FIFO的Verilog编写方法。
2.课程设计的条件FIFO的定义与功能Quartus II仿真工具3.课程设计的要求FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
使用Verilog语言和Quartus II仿真器完成同步FIFO的设计和验证。
使用Quartus II和SOPC实验箱验证设计的正确性。
Verilog代码要符合微电子中心编码标准。
4.Verilog语言Verilog HDL是一种硬件描述语言(HDL:Hardware Description Language),是一种以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。
Verilogs是由Gateway设计自动化公司的工程师于1983年末创立的。
当时Gateway设计自动化公司还叫做自动集成设计系统(Automated Integrated Design Systems),1985年公司将名字改成了前者。
该公司的菲尔·莫比(Phil Moorby)完成了Verilog的主要设计工作。
使用verilog_hdl实现8位宽,256位的深的同步fifo的实验原理
使用verilog hdl实现8位宽,256位的深的同步fifo的实验原理1. 引言1.1 概述本文旨在介绍如何使用Verilog HDL实现一个具有8位宽和256位深度的同步FIFO(First In, First Out)电路。
FIFO是一种常用的数据缓存结构,被广泛应用于数字系统中,具有先进先出的特性,能够实现数据的有序存储和检索。
文章将从FIFO的简介开始讲解,然后深入探讨同步FIFO设计时需要考虑的要点,并通过使用Verilog HDL进行设计和实现过程,最后对实验结果进行仿真验证、波形分析以及功能测试与性能评估。
1.2 文章结构本文总共包括五个部分。
首先是引言部分,概述了本文的目标和内容。
接下来是实验原理部分,从FIFO基本概念入手,详细介绍了同步FIFO设计时需要注意的要点以及Verilog HDL语言的简介。
然后是设计与实现部分,给出了8位宽、256位深度同步FIFO电路的设计思路,并逐步引导读者完成Verilog HDL代码的编写。
紧接着是实验结果与分析部分,通过仿真验证、波形分析以及功能测试与性能评估来验证所设计的同步FIFO电路是否符合预期。
最后是结论与展望部分,对实验结果进行总结,并探讨未来可能的改进方向和应用领域。
1.3 目的本文的主要目的是介绍使用Verilog HDL实现8位宽、256位深度同步FIFO电路的原理和方法。
读者可以通过本文了解到FIFO的基本原理和设计要点,以及如何使用Verilog HDL进行FIFO电路的实现。
通过本文,希望读者能够掌握基本的数字电路设计技巧和Verilog HDL编程能力,并在实践中提高对于同步FIFO电路设计的理解和应用能力。
同时,读者还可以通过仿真验证和功能测试等手段深入理解所实现的同步FIFO电路的性能特点,并为相关领域的研究与应用提供参考依据。
2. 实验原理:2.1 FIFO简介FIFO(First-In-First-Out)是一种常见的数据缓冲区结构,它的基本原则是按照先进先出的顺序处理输入和输出数据。
同步FIFO设计
FIFO的一些重要参数
FIFO的深度:THE DEEPTH,它指的是FIFO可以存储 多少个N位的数据(如果宽度为N)。如一个8位的 FIFO,若深度为8,它可以存储8个8位的数据,深度为 12 ,就可以存储12个8位的数据,FIFO的深度可大可 小,FIFO深度的计算并无一个固定的公式。
在FIFO实际工作中,其数据的满/空标志可以控制数据 的继续写入或读出。在一个具体的应用中也不可能由 一些参数算数精确的所需FIFO深度为多少,这在写速 度大于读速度的理想状态下是可行的,但在实际中用 到的FIFO深度往往要大于计算值。一般来说根据电路 的具体情况,在兼顾系统性能和FIFO成本的情况下估 算一个大概的宽度和深度就可以了。而对于写速度慢 于读速度的应用,FIFO的深度要根据读出的数据结构 和读出数据的由那些具体的要求来确定。
同步FIFO功能定义
用64*8 RAM实现一个同步先进先出(FIFO) 队列设计。由写使能端控制该数据流的写入 FIFO,并由读使能控制FIFO中数据的读出。 写入和读出的操作由时钟的上升沿触发。当 FIFO的数据满和空的时候分别设置相应的高 电平加以指示。
顶层信号定义:
信号名称
Rst Clk
在复位时(rst=0),写地址值为0。 如果FIFO未满(~full)且有写使能(wr_en)有效,则
wr_addr[5:0]加1;否则不变。
顶层模块划分及功能实现
rd_addr_gen:
该模块用于产生FIFO读数据时所用的地址。 由于64个RAM单元可以用6位地址线寻址。 本模块用6位计数器(rd_addr[5:0])实现读地址 的产生。
如果pt_cnt=0的时候,表示FIFO空,需要设置empty=1;如果 pt_cnt=64的时候,表示FIFO现在已经满,需要设置full=1。
高速异步FIFO的设计和实现
万方数据路中,这一信号最终会朝着0和1两个稳态转换,变成稳定的信号。
这一变换所需的时间取决于寄存器的结构和参数,通常在一个时钟周期内可以完成这一从亚稳态到稳态的转换。
所以,在设计中普遍采用两级寄存器串接的同步器来对信号进行同步,如图1所示。
图1解决亚稳态的同步器电路2.2毛刺单根信号的同步采用图1所示的同步电路即可消除亚稳态问题。
然而,对多位总线信号的同步,除了亚稳态外,还有一个重要的问题就是毛刺现象。
如果需要同步的总线的多位同时发生变化,由于在实际电路中各位的延时不可能完全一致,因此中间就可能会产生毛刺现象。
而用另一个频率相位完全不同的时钟采样的时候就有可能采样到毛刺信号,造成错误的同步。
例如,FIFO的读写指针是一个二进制计数器,当它从l计数到2时,位0从1变成0,位l从0变成1。
如果位0从1变成0的延时比位1从0变1要大,就会在1和2中间多出一个毛刺3,而如果直接用图l的同步电路同步,就有可能错误地在另一个时钟域得到一个3的结果。
对于FIFO的设计来说,这样的同步错误是致命的,会造成空满判断的失误。
解决这一问题就是需要采用无毛刺的电路结构,无毛刺电路要求信号同步前必须被寄存器锁存,并且每次只有一位发生变化。
例如,文献[2]中设计的FIFO就采用格雷码来避免这一问题。
3高速异步FIFO结构3.1基本结构本文设计的高速异步FIFO结构如图2所示,主要包括数据通路reg—file和控制模块fifo—eft两个部分。
reg—file模块是FIFO的存储器部分;fifo_eft模块负责FIFO的读写控制,如读写指针的产生和空满信号的产生。
图2高速异步FWO结构框图本设计的外部端口如表l所示。
3.2reg__file模块设计FIFO的存储器部分可以采用双端口SRAM或者用DFF寄存器搭建存储部分。
由于本设计为32×32的FIFC,存储器容量不大,采用双端口SRAM由于powerring等因素,面积会比用寄存器搭建要大,速度也不容易达86到500MHz的高速。
同步fifo的设计原理
同步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存储器的设计
FIFO存储器的设计摘要:FIFO是一种不同时钟域之间传递数据的常用方法,基于FIFO(先进先出)设计的存储器的数据读出顺序与数据写入顺序始终一致。
这种存储器主要用在两个处理数据速度不同的数字系统之间,作为数据缓冲器来提供必要的数据缓冲,使这两个数字系统达到同步,这在许多信号处理系统中是必须的。
这篇文章介绍了一种容量为1k×9的具有异步和同步功能FIFO存储器的设计方法,这种设计方法也可以用于存储容量更大的存储器的设计。
在设计具体逻辑单元时,基于Fundry厂商制定的工艺尺寸规则,优化了部分常用的逻辑电路,来减小版图面积和降低生产成本。
关键词:先进先出存储器;指针;数据缓冲;异步;同步中图分类号:TN432 文献标识码: ADesigning of FIFO memoryAbstract :FIFO is a general way to communicate between different clock domains. The memory based on FIFO (First-In, First-Out) keeps track of the order in which date is entered into the memory and reads the date out in the same order. The most common application of a FIFO is as a buffer memory between two digital systems operating at different speeds, providing the necessary data buffering to achieve synchronization, which is a requirement for many signal processing systems. This paper describes a design of a 1k×9 asynchronous and simultaneous FIFO memory, which can also be applied on the larger memory size. Based on the fundry’s rule of the technology, we optimize some units in order to reduce the square of the layout and cost, during designing of the units of the logic.Keywords: FIFO memory; pointer; data buffering; asynchronous; simultaneous1 引言存储器是存储数字信息的电路或系统,随着IC产业的迅猛发展,现代数字系统需要高速存储和检索大量信息的能力,存储器在数字电路中越来越重要。
fifo算法的工作过程
fifo算法的工作过程
FIFO(First-In-First-Out)算法是一种最简单的页面置换算法,通常用于操作系统中管理页面的缓存。
它基于先进先出的原则,即最先进入缓存的页面最先被替换出去。
以下是FIFO算法的工作过程:
1. 初始化:首先,初始化一个固定大小的缓存,以存储页面。
缓存的大小通常由系统或应用程序设置。
2. 页面访问:当一个新页面需要被加载到缓存中时,系统会检查该页面是否已经在缓存中。
-如果该页面已经在缓存中,系统认为这是一个缓存命中,不需要进行替换,直接使用该页面。
-如果该页面不在缓存中,系统进行下一步。
3. 页面替换:当缓存已满,而需要将新页面加载到缓存中时,FIFO算法会选择最早进入缓存的页面进行替换。
-算法维护一个队列,用于按照页面进入缓存的顺序排列。
新页面被加载时,加入队尾。
-当需要替换页面时,选择队首的页面进行替换,因为它是最早进入缓存的。
4. 更新队列:替换完成后,更新队列,将新页面移到队尾,保持队列的顺序。
FIFO算法的优点是实现简单,容易理解和实现。
然而,它也有一些缺点,其中之一是它可能导致"Belady's Anomaly",即增加缓存大小时缺页率反而增加。
这是因为FIFO算法只关注了页面进入的顺序,而没有考虑页面的访问频率或重要性。
因此,在某些情况下,FIFO算法可能不是最优的页面置换算法。
在实际应用中,其他更复杂的算法,如LRU(Least Recently Used)或LFU(Least Frequently Used),可能会更好地适应不同的场景。
最经典的FIFO原理
最经典的FIFO原理FIFO (First In, First Out)原理是一种常用的数据结构和算法。
它是指先进入的数据先出来的一种处理顺序。
下面将详细介绍FIFO原理的定义、实现方式、应用场景和一些具体示例,以及它的优点和缺点。
一、FIFO原理定义FIFO原理指的是按照数据进入的顺序,先进入的数据会在后面进入的数据之前被处理或者被取出。
这种处理数据的方式类似于一个队列,数据从队列的一端进入,从另一端出去。
在FIFO原理中,数据进入队列的这一端被称为“队尾”,数据出去的那一端被称为“队首”。
当新的数据进入队列时,它会排在队尾,而当数据被处理或者被取出时,它会从队首开始。
FIFO原理在计算机科学中有广泛的应用,如操作系统中的作业调度、缓存替换策略、网络通信等。
二、FIFO原理实现方式FIFO原理可以通过多种方式来实现。
下面介绍两种常见的实现方式。
1.数组实现使用数组作为底层数据结构来实现FIFO原理的队列。
当新的数据进入队列时,将其添加到数组的末尾;而当数据被取出或者被处理时,将数组的第一个元素移除。
需要注意的是,在数组实现的FIFO队列中,当队列的空间已满时,无法再添加新的数据;当队列为空时,无法再从队列中取出数据。
2.链表实现使用链表作为底层数据结构来实现FIFO原理的队列。
链表中的每个节点包含一个数据元素和一个指向下一个节点的指针。
当新的数据进入队列时,将其添加到链表的末尾;而当数据被取出或者被处理时,将链表的第一个节点移除。
链表实现的FIFO队列可以动态扩展和收缩,因为每个节点只需要存储指向下一个节点的指针,而不需要预先分配一定大小的存储空间。
三、FIFO原理的应用场景FIFO原理在计算机科学中有广泛的应用场景。
下面介绍几个常见的应用场景。
1.操作系统中的作业调度操作系统中的作业调度采用FIFO原理,根据作业进入系统的顺序来安排处理。
当多个作业同时进入操作系统时,根据进入顺序,它们会被添加到作业队列中,然后按照FIFO原理,从队首开始处理。
FIFO环形缓冲区的实现
FIFO环形缓冲区的实现在不同的系统之间交换数据时,往往由于两个系统时间不能完全同步。
为了保证生产者和消费者的同步,需要使用环形缓冲区。
生产者以某一速度存入数据,消费者以某一速度取出数据,两者的速度不用时刻一致,但总体的平均速度必须相等!以下是具体实现:1./**************FIFOBegin**************************************************/2./*溢出标志:0-正常,-1-溢出*/3.#define FLAGS_OVERRUN 0x00014./*5.buf- 缓冲区地址6.size- 大小7.free- 空余容量8.putP- 下一个数据写入位置9.getP- 下一个数据独处位置10.*/11.struct FIFO8{12.char *buf;13.int putP,getP,size,free,flags;14.pthread_mutex_t mutex;15.};16.17.int fifo8_init(struct FIFO8 *fifo,int size);18.int fifo8_put(struct FIFO8 *fifo, char data); //not mutiply thread safe19.int fifo8_get(struct FIFO8 *fifo); //not mutiply thread safe20.void fifo8_status(struct FIFO8 *fifo,int *len);21.void fifo8_free(struct FIFO8 *fifo,int *len);22.int fifo8_write(struct FIFO8 *fifo,char *data,int len);23.int fifo8_read(struct FIFO8 *fifo,char *data,int len);24.25./*初始化*/26.int fifo8_init(struct FIFO8 *fifo,int size) {27.28.int ret=0;29.30.fifo->flags=0;31.fifo->free=size;32.fifo->size=size;33.fifo->putP=0;34.fifo->getP=0;35.36.fifo->buf=(char *)malloc(size);37.if(fifo->buf==NULL){38.LOGI("malloc fifo buffer failed!\n");39.return -1;40.}41.42.ret = pthread_mutex_init(&(fifo->mutex),NULL);43.if(ret <0){44.LOGI("init mutex failed!\n");45.return -1;46.}47.48.return 0;49.}50.51./*向FIFO 中写入1个数据 */52.int fifo8_putPut(struct FIFO8 *fifo, char data) {53.if(fifo->free==0){54.fifo->flags |= FLAGS_OVERRUN;55.return -1;56.}57.fifo->buf[fifo->putP] = data;58.fifo->putP++;59.//循环队列缓冲区60.if(fifo->putP == fifo->size){61.fifo->putP = 0;62.}63.fifo->free--;64.65.return 0;66.}67./*从FIFO 中取出一个数据 */68.int fifo8_get(struct FIFO8 *fifo) {69.int data;70.if(fifo->free == fifo->size){71.return -1;72.}73.74.data = fifo->buf[fifo->getP++];75.//fifo->getP++;76.if(fifo->getP == fifo->size){//用来实现循环77.fifo->getP = 0;78.}79.fifo->free++;80.return data;81.}82./*写入len个字节,返回写入的字节数*/83.int fifo8_write(struct FIFO8 *fifo,char *data,int len){84.85.int i=0;86.pthread_mutex_lock(&(fifo->mutex));87.88.if(fifo->free < len) {89.pthread_mutex_unlock(&(fifo->mutex));90.LOGI("the free size in not enough!\n");91.return 0;92.}93.else {94.LOGI("current fifo->putP =%d \n",fifo->putP);95.for(i=0;i<len;i++){96.fifo->buf[fifo->putP++] = *(data+i);97.//循环队列缓冲区98.if(fifo->putP == fifo->size){99.fifo->putP = 0;100.}101.fifo->free--;102.}103.}104.105.pthread_mutex_unlock(&(fifo->mutex));106.107.return len;108.}109./*读出len个字节,返回读出的字节数*/110.int fifo8_read(struct FIFO8 *fifo,char *data,int len){ 111.112.int i=0;113.pthread_mutex_lock(&(fifo->mutex));114.115.if(fifo->size!=fifo->free){116.LOGI("current fifo->getP =%d \n",fifo->getP); 117.for(i=0; ; i++){118.*(data+i) =fifo->buf[fifo->getP++];119.if(fifo->getP == fifo->size){//用来实现循环120.fifo->getP = 0;121.}122.fifo->free++;123.if(fifo->size==fifo->free){124.LOGI("the buffer is no data left!\n");125.pthread_mutex_unlock(&(fifo->mutex));126.return i+1;127.}128.if(i+1==len){129.LOGI("read data finish!\n");130.break;131.}132.}133.}134.else{135.LOGI("the buffer is empty!\n");136.pthread_mutex_unlock(&(fifo->mutex));137.return 0;138.}139.140.pthread_mutex_unlock(&(fifo->mutex)); 141.142.return len;143.}144.145./*缓冲区被使用容量*/146.void fifo8_status(struct FIFO8 *fifo,int *used) { 147.pthread_mutex_lock(&(fifo->mutex));148.*used = fifo->size - fifo->free;149.pthread_mutex_unlock(&(fifo->mutex)); 150.}151./*缓冲区剩余容量*/152.void fifo8_free(struct FIFO8 *fifo ,int *free) { 153.pthread_mutex_lock(&(fifo->mutex));154.*free = fifo->free;155.pthread_mutex_unlock(&(fifo->mutex)); 156.}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
同步缓冲器(FIFO)的设计与实现姓名:崔琦学号:100260305班级:2010级电科3班院系:电气与信息工程学院专业:电子科学与技术同组人姓名:梁承润李建凯(说明:我们三个人前面的报告部分是一样的,因为课设基本是三个人商议完成,所以就感觉报告部分没什么不同的就只写了一份报告)目录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中的字节数进行计数。