异步FIFO设计
FPGA异步fifo设计完整报告

FPGA异步fifo设计完整报告1、名目一、技术规范31、设计完成的功能:32、系统整体框图:33、I/O管脚的描述:34、验证和测试工具选择:45、说明关键模块:46、拟选用的FPGA类型:4二、FIFO总体设计方案5系统功能描述:5电路结构图:5系统的总体输入输出设定6系统时序分析:6关键模块设计分析:7三、FIF0验证方案8FIFO功能:81、概述:82、预确认:83、模块运行确认:94、系统运行确认:9四、仿真激励代码10五、电路设计FIFO源代码11六、FPGA设计FIF0综合布局布线报告:16综合引脚安排:16电路布局布线:16七、时序仿真报告17时序仿真波形:17八、FIFO下载代码和引脚分布17系统输入输出引 2、脚分布:21九、心得体会21技术规范1、设计完成的功能:本试验完成的是8位异步FIFO的设计,其中写时钟100MHz,读时钟为5MHz,其中RAM的深度为256。
当写时钟脉冲上升沿到来时,推断写信号是有效,则写一个八位数据到RAM中;当读时钟脉冲上升沿到来时,推断读信号是有效,则从RAM中把一个八位数据读出来。
当RAM中数据写满时产生一个满标志,不能再往RAM再写数据;当RAM 中数据读空时产生一个满标志,不能再从RAM读出数据。
2、系统整体框图:3、I/O管脚的描述:管脚名称方向H/L电平位宽功能描述rst_ninput3.3V/01全局复位信号rd_eninput3.3V/01读使能低有3、效wr_eninput3.3V/01写使能低有效rd_emptyoutput3.3V/01读空标志高有效wr_fuIIoutput3.3V/01写满标志高有效rd_dataoutput3.3V/08数据输出wr_datainput3.3V/08数据写入cIk_1OOMinput3.3V/01写数据时钟cIk_5Minput3.3V/01读数据时钟4、验证和测试工具选择:ModelsimSE6.If进行前仿真和后仿。
异步FIFO的VHDL设计

异步FIFO的VHDL设计下面是一个异步FIFO的VHDL设计示例:```vhdllibrary ieee;use ieee.std_logic_1164.all;entity AsyncFIFO isgenericDATA_WIDTH : natural := 8; -- 数据宽度FIFO_DEPTH : natural := 16 -- FIFO深度portclk : in std_logic; -- 时钟信号rst : in std_logic; -- 复位信号read_en : in std_logic; -- 读使能write_en : in std_logic; -- 写使能read_data : out std_logic_vector(DATA_WIDTH-1 downto 0); -- 读数据write_data : in std_logic_vector(DATA_WIDTH-1 downto 0); -- 写数据full : out std_logic; -- FIFO满标志empty : out std_logic -- FIFO空标志end AsyncFIFO;architecture Behavioral of AsyncFIFO istype buffer_array is array (FIFO_DEPTH-1 downto 0) ofstd_logic_vector(DATA_WIDTH-1 downto 0);signal buffer : buffer_array; -- 数据缓冲区signal wr_ptr : natural range 0 to FIFO_DEPTH-1; -- 写指针signal rd_ptr : natural range 0 to FIFO_DEPTH-1; -- 读指针signal count : natural range 0 to FIFO_DEPTH-1; -- 缓冲区中数据个数beginprocess (clk)beginif rising_edge(clk) thenif rst = '1' thenwr_ptr <= 0;rd_ptr <= 0;count <= 0;elseif write_en = '1' and full = '0' then -- 写使能且FIFO非满buffer(wr_ptr) <= write_data;wr_ptr <= wr_ptr + 1;count <= count + 1;end if;if read_en = '1' and empty = '0' then -- 读使能且FIFO非空read_data <= buffer(rd_ptr);rd_ptr <= rd_ptr + 1;count <= count - 1;end if;end if;end if;end process;full <= '1' when count = FIFO_DEPTH-1 else '0';empty <= '1' when count = 0 else '0';end Behavioral;```在上面的代码中,`DATA_WIDTH`和`FIFO_DEPTH`是异步FIFO的泛型参数,可以根据实际需求进行配置。
异步fifo设计及时序约束设置

一、前言跨时钟域的同步处理,使用异步FIFO是常用的方式之一,对于异步FIFO的设计,网上的大部分资料来源于《Simulation and Synthesis Techniques for Asynchronous FIFO Design》一文其异步FIFO的结构如下图所示本文不是介绍上图描述的设计。
我从基本的数字电路时序开始,介绍异步FIFO的相关问题。
最后介绍如何用时序约束保证设计的正确性二、数字电路时序对于数字电路来讲,我们的信号在时钟边沿发生变化,Dat1信号是一种理想情况,而Dat2是实际情况,其特点是一、相对时钟边沿有延时二、信号变化有一段时间(电平转换时间),在这段时间就是亚稳态在亚稳态期间进行数据采样,不能获得稳定的值。
数字电路中经过时序约束,在T1产生的信号,在T2一定稳定(否则就是不满足时序),所以对于只有一个时钟的数字电路来说,它在T1和T2都能获得稳定的信号(T1时刻的值为0、T2时刻的值为1)三、跨时钟域时序问题对于异步时钟而言(相位不同),对于CLK1产生的信号,CLK2有可能在任意时刻进行数据采样在FIFO的设计中,将会产生2种信号,一种是数据本身(用Data表示),另外一种是指示数据是否有效(用valid表示),注意(valid不一定是一个比特的寄存器,可以是由FIFO中的读写指针产生而来,例如fifo的full或empty状态)异步FIFO的问题在于,如果CLK2在时钟T2进行采样,那么有可能得到valid有效,而数据无效的情况。
这样在CLK2采样取得的设计就是错误的数据。
四、处理异步FIFO的valid和data(理论基础)我们假设valid为低电平表示没有数据,高电平为有数据,解决的办法就是,当CLK对valid进行采样时,即使valid处于亚稳态期间,数据信号也是稳定的如上图所以,在T1时刻进行上升沿采样,虽然valid是一个亚稳态状态,但是此时Data 是一个稳定的值,如果在T1时刻采样的valid为1,那么可以得到稳定的Data信号,如果在T1时刻采样的valid为0,那么控制逻辑认为在T1无法获得数据,从而在下一个时钟获取注意:T2时刻是在下降沿进行采样,而此时的Data信号也是稳定的五、如何实现为了让valid和Data处于上面的状态,我们可以对valid进行延时处理,即使用时钟对其进行采样,必须使用2个寄存器依次采样,才能保证至少有一个时钟的延时valid1是CLK2对valid进行采样产生的,如果采样的时机不好,那么valid1相对valid只有一点点延时,valid2是CLK2对valid1的采样,这样valid2相对于valid至少有CLK2一个周期的延时,也就满足了第二节的条件。
高速异步FIFO的设计与实现

高速异步FIFO的设计与实现2 异步FIFO的实现读时钟2.1 FIFO设计的难点如何同步异步信号,使触发器不产生亚稳态是设计异步FIFO的难点。
国内外解决此问题的较成熟方法是对写地址膜地址采纳格雷码,本文也挺直采纳格雷码。
异步FIFO设计的另一个难点是如何推断FIFO的空/满状态。
为了保证数据正确的写入或读出。
必需保证异步FIFO在满的状态下.不能举行写操作:在空的状态下不能举行读操作。
通常状况下将存储器组织成一个环形链表。
满/空标记产生的原则是:写满不溢出.读空不多读。
即无论在什么状况.都不应浮现读写地址同时对一个存储器地址操作的状况。
在读写地址相等或相差一个或多个地址的时候,满标记应当有效。
表示此时FIFO 已满,外部电路应停止对FIFO发数据。
在满信号有效时写数据应按照设计的要求,或保持、或抛弃重发。
同理,空标记的产生也是如此。
为了更好的推断满/空标记。
采纳在FIFO本来深度的基础上增强一位的办法,而由该位组成的格雷码并不代表新的地址。
也就是说3位格雷码可表示8位的深度,若再加一位最高位MSB,则这一位加其他三位组成的格雷码并不代表新的地址,也就是说格雷码的0100表示7,而1100仍然表示7,只不过格雷码在经过一个以0位MSB的循环后进入一个以1为MSB的循环,然后又进入一个以0位MSB的循环。
其他的三位码仍然是格雷码。
举例解释:一个深度为8字节的FIFO怎样工作(用法已转换为二进制的指针),N=3,指针宽度为N+I=4。
开头rd_ptr_bin和wr_ptr_bin均为“0000”。
此时FIFO中写入8个字节的数据。
wr_ptr_bin=“1000",rd_ptr_bin=“0000”。
固然,这就是满条件。
现在,假设执行了8次的读操作.使得rd_ptr_bin=“1000”,这就是空条件。
另外的8次写操作将使wr_ptr_bin等于“0000”,但rd_ptr_bin仍然等于“1000”,因此,FIFO为满条件。
异步FIFO设计

异步FIFO设计2011.6.22摘要本文采用格雷码设计了一个异步FIFO,经过DC综合的结果如下:时钟频率:1.1GHz面积:10744.447um2功耗:7.791mw目录1. 异步FIFO的设计 (2)1.1 异步FIFO简介 (2)1.2 FIFO的参数 (2)1.3 FIFO的设计原理 (2)1.4 FIFO的设计模块 (6)1.5 用modelsim仿真FIFO (11)1.6 用DC对FIFO进行综合 (13)2.参考文献 (15)1. 异步FIFO的设计1.1 异步FIFO简介FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。
同步FIFO是指读时钟和写时钟为同一个时钟。
在时钟沿来临时同时发生读写操作。
异步FIFO是指读写时钟不一致,读写时钟是互相独立的。
异步FIFO(Asynchronous FIFO),一般用于不同时钟域之间的数据传输,比如FIFO 的一端连接频率较低的AD数据采样信号,另一端与计算机的频率较高的PCI总线相连。
另外,对于不同宽度的数据接口也可以用AFIFO,例如单片机为8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用AFIFO来达到数据匹配的目的。
由于实际中,异步FIFO比较常见。
为了便于描述,在后面的章节中将异步FIFO 简称为FIFO.1.2 FIFO的参数FIFO的宽度:进行一次读写操作的数据的位宽。
FIFO的深度:双口存储器中能容纳的数据的总数。
满标志:FIFO已满或将要满时由FIFO的状态电路送出的一个信号,以阻止FIFO的写操作继续向FIFO中写数据而造成溢出。
异步FIFO的设计与实现

摘要随着数字系统规模的不断增大,单时钟域设计会极大地限制数字系统性能,现代数字系统为了提升性能,常采用多时钟域的设计。
跨时钟域的信号在传输时会遇到亚稳态现象,如何保持系统稳定地传输数据是多时钟域系统设计者重点关注的问题,在跨时钟域传递数据的系统中,常采用异步FIFO(First In First Out,先进先出队列)口来缓冲传输的数据,以克服亚稳态产生的错误,保证数据的正确传输。
常规的异步FIFO 设计采用先同步读写指针后比较产生空/满标志和用先比较读写指针产生空/满标志,再同步到相应时钟域的方法,但由于常规异步FIFO 模块中的RAM 存储器读写寻址指针常采用格雷码计数器以及“空满”控制逻辑的存在,工作频率低,面积大,将使通过这两个模块的信号通路延时对整个模块的工作频率造成制约。
本文提出了一种新型异步FIFO 的设计方法,该方法省略“了满”信号产生模块和多余的存储器位深来简化常规的FIFO 模块,而只保留“空”信号产生模块,避免使用大量的同步寄存器,减少了面积空间。
FPGA 验证的结果表明,改进后的异步 FIFO 性能有了显著的提高。
关键词:现场可编程门阵列(FPGA )亚稳态空/满标志产高速FIFOABSTRACTWith the increasing of digital system size, a single clock domain design will greatly limit the digital system performance. To enhance the performance of modern digital systems, multiple clock domain design is conventionally adopted. While being transmitted, Cross-clock domain signals will come across the phenomenon of metastability, hence it will be a major concern for the multi -clock domain system designers to probe how to maintain the system stability and to have data transmission conducted smoothly. As to the bus system data transmission in the system where the two data interface clocks don’t match, one of super and effective solutions is to use asynchronous FIFO buffer memory. How To solve the key and difficult issue that metastability and how to generate empty and full flag correctly in asynchronous FIFO design. Traditional FIFO design often synchronizes write/read address first, then compares them to generate empty/full signals or empty / full flag first compare the read and write pointer, and then synchronized to the clock domain, This design takes on too much area and can only work at a low frequency,this will allow the signaling pathways of these two modules delay caused by constraints of the operating frequency of the entire module. A new method of asynchronous FIFO is proposed to overcome these problems,omit the "full" signal generator module and redundant memory bit depth to simplify the conventional FIFO module, leaving only the "empty" signal generation module,avoid the use of a large number of synchronization registers, reducing the area of space. FPGA verification results show that the asynchronous FIFO improved performance has been significantly improved.Keywords: Field Programmable Gate Array (FPGA); Metastable; Mmpty / Full Flag production; High-speed FIFO目录摘要 (I)ABSTRACT (II)第一章绪论 (1)1.1研究背景和意义 (1)1.2研究现状 (1)1.3本文的主要工作 (3)1.4论文结构 (3)第二章跨时钟域设计的挑战与实现方法 (4)2.1跨时钟域设计的挑战 (4)2.1.1亚稳态问题 (4)2.1.2亚稳态产生的原因 (5)2.1.3亚稳态的危害 (5)2.2 跨时钟域的实现方法 (6)2.2.1同步器 (6)2.2.2握手机制 (9)第三章开发环境 (11)3.1硬件平台 (11)3.2软件平台 (11)第四章异步FIFO的设计与实现 (13)4.1异步FIFO (13)4.1.1异步FIFO工作原理 (13)4.1.2异步FIFO设计的难点 (14)4.2常见异步 FIFO 的设计 (16)4.2.1 读写地址产生逻辑 (18)4.2.2空/满标志的产生及代码的实现 (19)4.3.3改进的异步 FIFO 设计方法分析 (22)4.4高速异步FIFO的设计与实现 (23)4.4.1常见FIFO模块分析 (23)4.4.2高速异步FIFO 设计 (25)第五章结论 (28)第六章参考文献 (29)致谢 (30)附录高速异步FIFO设计仿真分析 (31)附1. 设计工作流程 (31)附.1.1 设计输入 (31)附.1.2 设计编译 (35)附.1.3 设计仿真 (36)第一章绪论1.1研究背景和意义作为21 世纪最重要的科学领域之一,超级计算机是体现科技竞争力和综合国力的重要标志。
异步FIFO的设计文档

异步FIFO的设计版本v1.02011-05-06异步FIFO的设计一.功能描述本设计用16*8 RAM实现一个异步FIFO,具体功能定义如下:1. 异步复位。
2. FIFO不为满时,当写使能有效时,在写时钟的上升沿向FIFO中写入数据。
3. FIFO不为空时,当读使能有效时,在读时钟的上升沿从FIFO中读出数据。
4. 当FIFO写满的时候,产生满信号;当FIFO读空的时候,产生空信号。
5. FIFO一旦空或者满时候,复位FIFO;二.输入输出信号描述信号名输入/输出目标/源功能描述Rclk Input Pin 读时钟频率,10M ,占空比1:1。
Wclk Input Pin 写时钟,频率10M ,占空比1:1。
data_in[7:0] Input Pin 8位的输入数据rd_en Input Pin 读使能,高电平有效,在FIFO非空时,CLK上升沿读入数据;wr_en Input Pin 写使能,高电平有效,在FIFO非满时,CLK上升沿写入数据;Rst Input Pin 异步清零,低电平有效,低电平时读地址,写地址,计数器都清零。
三顶层划分图1 系统框图顶层模块说明:1.RAM :存储器模块,用于存放及输出数据;2.Waddr_Reg : 保存访问RAM的写地址;3.Raddr_Reg : 保存访问RAM的写地址;4.Wbin_addr : 计算RAM下一个写地址;5.Rbin_addr : 计算RAM下一个读地址;6.Gwaddr_reg : 将写地址的二进制编码转换成格雷码,并保存;7.Graddr_reg : 将读地址的二进制编码转换成格雷码,并保存;8.Syn_Rfield : 将写地址同步到读时钟域,并产生空标志;9.Syn_Wfield : 将读地址同步到写时钟域,并产生满标志;10、Reset_Unit : 复位信号产生单元设计思想说明:1、由于实现的异步FIFO,分别用不同的读、写时钟产生读写地址,因此FIFO 的判空和判满是本设计中的一个难点。
最新-一种异步FIFO的设计方法 精品

一种异步FIFO的设计方法摘要使用同步源自不同时钟域的数据是在数字设计中经常使用的方法,设计功能正确的会遇到很多问题,探讨了两种不同的异步的设计思路。
两种思路都能够实现功能正确的。
关键词异步握手同步二进制格雷码本文所研究的,从硬件的观点来看,就是一块数据内存。
它有两个端口,一个用来写数据,就是将数据存入;另一个用来读数据,也就是将数据从当中取出。
与操作相关的有两个指针,写指针指向要写的内存部分,读指针指向要读的内存部分。
控制器通过外部的读写信号控制这两个指针移动,并由此产生空信号或满信号。
对于异步而言,数据是由某一个时钟域的控制信号写入,而由另一个时钟域的控制信号将数据读出。
也就是说,读写指针的变化动作是由不同的时钟产生的。
因此,对空或满的判断是跨时钟域的。
如何根据异步的指针信号对的满状态或空状态进行正确的判断是本文研究的重点。
此外,设计过程中的一些细节问题也将在文中涉及到。
1指针以及满空信号的产生为了更好地说明问题,先探讨一下同步指针移动以及满空信号的产生过程。
对于同步,读写指针都指向一个内存的初始位置,每进行一次读写操作,相应的指针就递增一次,指向下一个内存位置。
当指针移动到了内存的最后一个位置时,它又重新跳回初始位置。
在非满或非空的情况下,这个过程将随着读写控制信号的变化一直进行下去。
如果处于空的状态,下一个读动作将会导致向下溢出,一个无效的数据被读人;同样,对于一个满了的,进行写动作将会导致向上溢出,一个有用的数据被新写入的数据覆盖。
这两种情况都属于误动作,因此需要设置满和空两个信号,对满信号置位表示处于满状态,对满信号复位表示非满,还有空间可以写入数据;对空信号置位表示处于空状态,对空信号复位表示非空,还有有效的数据可以读出。
当读指针和写指针相等也就是指向同一个内存位置的时候,可能处于满或空两种状态。
可以通过不同的方法判断或区分究竟是处于满状态还是空状态,也就是究竟是写指针从后赶上了读指针,还是读指针从后赶上了写指针。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
异步FIFO设计文档
一、概述
在大规模ASIC或FPGA设计中,多时钟系统往往是不可避免的,这样就产生了不同时钟域数据传输的问题,其中一个比较好的解决方案就是使用异步FIFO来作不同时钟域数据传输的缓冲区,这们既可以使相异时钟域数据传输的时序要求变得宽松,也提高了它们之间的传输效率。
此文内容就是阐述异步FIFO 的设计。
二、设计原理
2.1结构框图
Fig. 2.1.1
如上图所示的同步模块synchronize to write clk,其作用是把读时钟域的读指针rd_ptr采集到写时钟(wr_clk)域,然后和写指针wr_ptr进行比较从而产生或撤消写满标志位wr_full;类似地,同步模块synchronize to read clk的作用是把写时钟域的写指针wr_ptr采集到读时钟域,然后和读指针rd_ptr进行比较从而产生或撤消读空标志位rd_empty。
另外还有写指针wr_ptr和写满标志位wr_full产生模块,读指针rd_ptr和读空标志位rd_empty产生模块,以及双端口存储RAM模块。
2.2 二进制计数器存在的问题
异步FIFO读写指针需要在数学上的操作和比较才能产生准确的空满标志位,但由于读写指针属于不同的时钟域及读写时钟相位关系的不确定性,同步模块采集另一时钟域的指针时,此指针有可能正处在跳变的过程中,如图Fig.2.2.1所示,那么采集到的值很有可能是不期望的值,当然,不期望的错误结果也会随之发生。
Fig. 2.2.1
上图中,rd_ptr2sync 3和4以及4和5之间的中间态是由于到各寄存器的时钟rd_clk存在偏差而引起的。
二进制的递增操作,在大多数情况下都会有两位或者两以上的bit位在同一个递增操作内发生变化,但由于实际电路中会存在时钟偏差和不同的路径延时,二进制计数器在自增时会不可避免地产生错误的中间结果,如图Fig.2.2.2。
Fig.2.2.2
上图是Fig.2.2.1的电路原型以及局部波形的放大。
由于rd_clk上升沿到达
三寄存器的时间各不相同,这就导致了rd_ptr2sync的值从3’b011跳变3’b100的过程中经历了3’b111和3’b101,直到最后一个时钟(rd_clk0)沿的到来rd_ptr2sync 才跳变到正确结果3’b100。
中间结果的持续的时间虽然相对短暂,但是这些不正确的结果完全有可能被其它时钟域的同步模块采集到而产生错误的动作,见上图。
由此可见,要避免中间结果的产生,其中一个可行的方案就是使被同步模块采集的数据递变时,每次只有一个bit位发生改变。
格雷码计数器就是一个不错的选择。
2.3 格雷码计数器的实现
2.3.1 格雷码的表现形式
格雷码一个最大的特点就是在递增或递减的过程中,每次只变化一位,这是它最大的优点。
同时它也有自己的局限性,那就是循环计数深度必须是2的n 次幂,否则就失去了每次只变化一位的特性。
深度为16的二进制及格雷码递变表如下:
Binary Gray
0 0000 0000
1 0001 0001
2 0010 0011
3 0011 0010
4 0100 0110
5 0101 0111
6 0110 0101
7 0111 0100
8 1000 1100
9 1001 1101
10 1010 1111
11 1011 1110
12 1100 1010
13 1101 1011
14 1110 1001
15 1111 1000
0 0000 0000
2.3.2 二进制和格雷码的相互转换
1、二进制到格雷码:
[1][1];
[2][2][1];
[2][2][3];
[1][1][2];
[0][0][1];gray n bin n gray n bin n bin n gray bin bin gray bin bin gray bin bin -=--=-⊕-⋅⋅⋅⋅⋅⋅
=⊕=⊕=⊕ 总结上述转换规律,又知
000a a a a ⊕=∙+∙=,所以它们之间有如下简化关系:[1:0]([1:0]1)[1:0];gray n bin n bin n -=->>∧-
2、格雷码到二进制:
[0][1][2]...[1][0];[1][1][2]...[1];
.........
bin gray n gray n gray gray bin gray n gray n gray =-⊕-⊕⊕⊕=-⊕-⊕⊕ [2][1][2[1][1];b i n n g r a y n g r a y n b i n n g r a y n -=
-⊕--=
- 总结上述转换规律,又知
000a a a a ⊕=∙+∙=,所以它们之间有如下简化关系:[]([1:0]);.................(01)bin i gray n i i n =∧->>≤≤-
2.3.3格雷码计数器的实现
如下图fig.2.3.1所示,指向存储器的地址指针由二进制计数器产生,而用于跨时钟域传播的格雷码指针是对二进制指针的实时转换并用寄存器采集获得的。
这里要注意的是,计数器的位宽比实际所需的位宽要多出一位,这样做的目的是方便判断FIFO 的空或满,这一点下文中将会介绍。
Fig.2.3.1 格雷码计数器结构图
2.4 空满标志位的产生
异步FIFO最核心的部分就是精确产生空满标志位,这直接关系到设计的成败。
本文采用比较读写指针来判断FIFO的空满,如果FIFO的深度是n-1位线所能访问到的地址空间,那么此设计所要用的指针位宽就比实际多出一位,也就是n位,这样做有助于判断FIFO是空还是满。
2.4.1 读空标志位的产生
当读地址rd_ptr赶上写地址wr_ptr,也就是rd_ptr完全等于wr_ptr时,可以断定,FIFO里的数据已被读空,而且只有在两种情况下,FIFO才会为空:第一种是系统复位,读写指针全部清零;另一种情况是在FIFO不为空时,数据读出的速率快于数据写入的速率,读地址赶上写地址时FIFO为空。
空标志位的产生需要在读时钟域里完成,这样不至于发生FIFO已经为空了而空标志位还没有产生的情况,但是可能会发生FIFO里已经有数据了而空标志位还没有撤消的情况,不过就算是在最坏情况下,空标志位撤消的滞后也只有三个时钟周期,这个问题不会引起传输错误;还有一种情况就是空标志比较逻辑检测到读地址和写地址相同后紧接着系统产生了写操作,写地址增加,FIFO内有了新数据,由于同步模块的滞后性,用于比较的写地址不能及时更新,这样,一个本不应该有的空标志信号就产生了,不过这种情况也不会导致错误的发生,像这种FIFO非空而产生空标志信号的情况称为“虚空”。
Fig. 2.4.1.1 空标志产生逻辑
如图Fig. 2.4.1.1 空标志产生逻辑,写时钟域的写指针通过两级寄存被同步到读时钟域之后与读指针进行比较,如果完全相等,则会产生空标志信号;同步模块用两级寄存器来实现是为了消除可能的亚稳态,正如前面所述,因为wr_ptr_gray是用格雷码实现的,即使同步模块是在wr_ptr_gray跳变的时刻进行采集,其采集到的所有可能值也只有两个,一个是跳变之前的值,一个是跳变之后的值,它们只相差1,最坏情况也只是产生了“虚空”信号,而这不会引起错误传输。
Fig. 2.4.1.2 空标志产生时序
2.4.2 写满标志位的产生
和读空标志位产生机制一样,写满标志位也是通过比较读写地址产生的。
读写指针的关系就好比A,B两个田径运动员在一环形跑道上进行比赛一样,当B 运动员领先A并整整超前一圈时,A,B两人的地点相同,此种情况对应于读写指针指向了同一地址,但写指针超前整整一圈,FIFO被写满。
如此看来,和读空标志产生一样,写满标志也是读写指针相同时产生。
但是如果地址的宽度和FIFO实际深度所需的宽度相等,某一时刻读写地址相同了,那FIFO是空还是满就难以判断了。
所以读写指针需要增加一位来标记写地址是否超前读地址(在系统正确工作的前提下,读地址不可能超前于写地址),比如FIFO的深度为8,我们需要用宽度为4的指针。
Fig. 2.4.2.1 格雷码指针和存储空间的映射关系
如果读指针的最高位为0,而写指针的最高位为1,说明写指针超前于读指针,这时如果读写指针指向同一存储空间,参照Fig. 2.4.2.1 , 则FIFO被写满。
写满标志位产生逻辑只需关心格雷码指针最高位不同(写超前于读)且它们指向同一存储空间的情况,那么怎么通过比较两格雷码指针来判断这种情况的发生呢?首先,最高位相异(因为读指针不可能超前于定指针,所以只可能是写指针
超前于读指针);其次,如果把最高位为1的所有格雷码指针的次高位均取反后,除去最高位不看,则指向同一存储空间的两指针相同,从而得出第二个条件是:次高也相异。
Fig. 2.4.2.2 写满标志位产生逻辑。