(完整版)异步FIFO设计

合集下载

异步FIFO设计(非常详细,图文并茂,值得一看!)

异步FIFO设计(非常详细,图文并茂,值得一看!)

异步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的电路原型以及局部波形的放大。

异步FIFO设计

异步FIFO设计

异步FIFO设计2011.6.22摘要本文采用格雷码设计了一个异步FIFO,经过DC综合的结果如下:时钟频率:1.1GHz面积: 10744.447um2功耗: 7.791mw目录1. 异步FIFO的设计 (22)1.1 异步FIFO简介 (22)1.2 FIFO的参数 (22)1.3 FIFO的设计原理 (22)1.4 FIFO的设计模块 (66)1.5 用modelsim仿真FIFO (1111)1.6 用DC对FIFO进行综合 (1313)2.参考文献 (1515)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的设计分析及详细代码

异步FIFO的设计分析及详细代码本文首先对异步FIFO设计的重点难点进行分析,最后给出详细代码。

一、F1FO简单讲解FIFO的本质是RAM,先进先出重要参数:fif。

深度(简单来说就是需要存多少个数据)fif。

位宽(每个数据的位宽)FIFO有同步和异步两种,同步即读写时钟相同,异步即读写时钟不相同同步F1FO用的少,可以作为数据缓存异步FIFO可以解决跨时钟域的问题,在应用时需根据实际情况考虑好fifo 深度即可本次要设计一个异步FIFO,深度为8,位宽也是&代码是学习Simu1ation andSynthesis Techniquesfor AsynchronousFIFODesignC1iffordE.Cu mmings,SunburstDesign,InC.这篇文章的,百度搜搜很容易找到,虽然是英文的但是写的酸值得研究。

下面我会对设计的要点进行分析,也是对自己学习过程的一个总结,希望能和大家交流共同进步。

二、设计要点解析1、读空值号如何产生?写满信号如何产生?读空信号:复位的时候,读指针和写指针相等,读空信号有效(这里所说的指针其实就是读地址、写地址)当读指针赶上写指针的时候,写指针等于读指针意味着最后一个数据被读完,此时读空信号有效写满信号:当写指针比读指针多一圈时,写指针等于读指针意味着写满了,此时写满信号有效我们会发现读空的条件是写指针等于读指针,写满的条件也是写指针等于读指针,到底如何区分呢?解决方法:将指针的位宽多定义一位举个例子说明:假设要设计深度为8的异步FIFO,此时定义读写指针只需要3位(2-3二8)就够用了,但是我们在设计时将指针的位宽设计成4位,最高位的作用就是区分是读空还是写满,具体理论1如下当最高位相同,其余位相同认为是读空当最高位不同,其余位相同认为是写满注意:理论1试用的是二进制数之间的空满比较判断。

但是这篇文章中确不是这样比较的,而是用的理论2,这里我解释一下由于文章在设计中判断是读指针是否等于写指针的时候,用的是读写指针的格雷码形式(为什么用格雷码后面解释),此时若用上面的理论1就会出问题,因为格雷码是镜像对称的,若只根据最高位是否相同来区分是读空还是写满是有问题的,详情我会慢慢说,请看图1绿色框起来的是0-15的格雷码,用红线将格雷码分为上下两部分通过观察格雷码相邻位每次只有1位发生变化,且上下两部分,除了最高位相反,其余位全都关于红线镜像对称,7—>8,格雷码从0100->1100,只有最高位发生变化其余位相同6->9,格雷码从0101->1101,只有最高位发生变化其余位相同以此类推,为什么要说镜像对称呢?试想如果读指针指向8,写指针指向7,我们可以知道此时此刻并不是读空状态也不是写满状态但是如果在此刻套用理论1来判断,看会出现什么情况,我们来套一下7的格雷码与8的格雷码的最高位不同,其余位相同,所以判断出为写满。

高速异步FIFO的设计与实现

高速异步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的设计示例

一、异步FIFO 技术规范 1. 总体描述1.1. 功能定义异步FIFO ( First In First Out)指的是在两个相互独立的时钟域下, 数据从一个时钟域写入FIFO 而另一个时钟域又从这个FIFO 中将数据读出。

本设计用8*256的RAM 实现异步FIFO 。

具体功能:1. 写使能有效,且FIFO 不为满时,在写时钟的上升沿向FIFO 中写入数据。

2. 读使能有效,且FIFO 不为空时,在读时钟的上升沿从FIFO 中读出数据。

3. 当FIFO 写满时产生满信号,当FIFO 读空时产生空信号。

1.2. 应用范围异步FIFO 是用来作为缓冲的存储器, 它能对数据进行快速、顺序的存储和发送, 主要用来解决不同速率器件间的速率匹配问题。

2. 引脚描述图12.1. 引脚功能描述2.2.引脚时序描述当写满时full由低变高,当读空时empty由低变高。

只要不为满full就为低,不为空empty就为低。

3.顶层模块划分图2顶层模块说明:1.ram_fifo :存储器模块,用于存放及输出数据;2.w_addr_reg : 保存访问RAM的写地址;3.r_addr_reg : 保存访问RAM的读地址;4.w_addr_adder : 计算RAM下一个写地址;5.r_addr_adder: 计算RAM下一个读地址;6.cmp : 将读地址和写地址进行比较产生空满标志。

设计思想说明:FIFO满空的判定:当读地址的值加1之后等于写地址的值时,表明FIFO写满,当写地址的值加一之后等于读地址的值时,表明FIFO读空。

在初始状态时FIFO的读地址在RAM的中间位置,写地址在RAM的开始位置,所以初始状态FIFO不满也不空。

空满信号的产生由组合电路产生。

4.功能模块描述4.1.ram_fifo模块ram_fifo:RAM存储器。

用8*256双口RAM实现。

4.2.w_addr_reg模块w_addr_reg模块:写地址寄存器。

异步FIFO的设计文档

异步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(FIRST IN FIRST OUT)即先进先出的队列,其结构图如下图所示。

DIN W_EN DOUT EMPTY FULL在具体实现FIFO时,数据存储的部分是采用简单双端口模式操作的,一个端口只写数据而另一个端口只读数据,另外在RAM周围加一些控制电路来输出指示信息。

FIFO最重要的特征是具有满(FULL)和空(EMPTY)的指示信号,当FULL信号有效时(高电平),就不能再往FIFO中写入数据,否则会造成数据丢失;当EMPTY信号有效时(高电平),就不能从FIFO中读取数据,此时输出端口处于高阻态。

实验步骤1.打开ISE软件创建一个新的工程。

2.用IP核生成器建立FIFO的核,选择下列的配置参数。

(1)在READ/WRITE CLOCK DOMAINS域中,选中Independent clock(RD_CLK,WR_CLK)(2)在DATA PORT PARAMEMTERS中选择WRITE WIDTH-16,WRITE DEPTH-32,READ WIDTH-16。

(3)其余参数按默认配置即可。

3.生成设计的顶层模块,并在该文件中加入所生成的FIFO的例化模板。

4.对设计进行检查,并用VHDL语言生成顶层测试文件。

5.调用ISE仿真器进行行为仿真,观察仿真结果。

波形文件如下:设计代码1.FIFO设计代码library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity top isport(din : IN std_logic_VECTOR(15 downto 0);rd_clk : IN std_logic;rd_en : IN std_logic;rst : IN std_logic;wr_clk : IN std_logic;wr_en : IN std_logic;dout : OUT std_logic_VECTOR(15 downto 0);empty : OUT std_logic;full : OUT std_logic);end top;architecture Behavioral of top iscomponent fifo1port (din : IN std_logic_VECTOR(15 downto 0);rd_clk : IN std_logic;rd_en : IN std_logic;rst : IN std_logic;wr_clk : IN std_logic;wr_en : IN std_logic;dout : OUT std_logic_VECTOR(15 downto 0);empty : OUT std_logic;full : OUT std_logic);end component;beginu1 : fifo1port map (din => din,rd_clk => rd_clk,rd_en => rd_en,rst => rst,wr_clk => wr_clk,wr_en => wr_en,dout => dout,empty => empty,full => full);end Behavioral;2.VHDL测试代码LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.all;USE ieee.numeric_std.ALL;ENTITY test_vhd ISEND test_vhd;ARCHITECTURE behavior OF test_vhd IS-- Component Declaration for the Unit Under Test (UUT)COMPONENT topPORT(din : IN std_logic_vector(15 downto 0);rd_clk : IN std_logic;rd_en : IN std_logic;rst : IN std_logic;wr_clk : IN std_logic;wr_en : IN std_logic;dout : OUT std_logic_vector(15 downto 0);empty : OUT std_logic;full : OUT std_logic);END COMPONENT;--InputsSIGNAL rd_clk : std_logic := '0';SIGNAL rd_en : std_logic := '0';SIGNAL rst : std_logic := '0';SIGNAL wr_clk : std_logic := '0';SIGNAL wr_en : std_logic := '0';SIGNAL din : std_logic_vector(15 downto 0) := (others=>'0');--OutputsSIGNAL dout : std_logic_vector(15 downto 0);SIGNAL empty : std_logic;SIGNAL full : std_logic;BEGIN-- Instantiate the Unit Under Test (UUT)uut: top PORT MAP(din => din,rd_clk => rd_clk,rd_en => rd_en,rst => rst,wr_clk => wr_clk,wr_en => wr_en,dout => dout,empty => empty,full => full);tb1 : PROCESS BEGINrd_clk<='0';wait for 10 ns;rd_clk<='1';wait for 10 ns; END PROCESS;tb2 : PROCESS BEGINwr_clk<='0';wait for 20 ns;wr_clk<='1';wait for 20 ns; END PROCESS;tb3 : PROCESS BEGINrst<='1';wait for 20 ns;rst<='0';wait for 1 ms; END PROCESS;tb4 : PROCESS BEGINwr_en<='0';wait for 95 ns;wr_en<='1';wait for 1285 ns;wr_en<='0';wait for 1 ms; END PROCESS;tb5 : PROCESSvariable j : std_logic_vector(15 downto 0);BEGINj:=x"0000";din<=x"0000";wait for 95 ns;for i in 0 to 31 loopdin<=j;j:=j+1;wait for 40 ns;end loop;wait for 1 ms;END PROCESS;tb6 : PROCESSBEGINrd_en<='0';wait for 1600 ns;rd_en<='1';wait for 1880 ns;END PROCESS;END;。

高速异步FIFO设计-

高速异步FIFO设计-

课程设计报告高速异步FIFO设计目录技术规范 (3)FIFO的功能描述 (3)FIFO的引脚定义 (3)总体方案设计 (4)电路设计方框图 (4)电路设计连接图 (4)电路模块及其功能简介 (4)电路设计思想 (5)仿真方案及其仿真激励源代码 (8)仿真方案 (8)仿真激励源代码 (8)电路描述代码 (9)功能仿真 (14)分块仿真 (14)双口RAM仿真 (14)读数据控制电路仿真 (15)写数据控制电路仿真 (16)锁存器电路仿真 (16)满空标志电路仿真 (17)总体仿真 (18)综合与布局布线 (18)综合布局布线报告 (19)报告数据分析 (19)时序仿真 (19)实验心得 (20)一、技术规范1、FIFO的功能描述高速异步FIFO(First In First out)深度为256,数据宽度为8位(最大可存储256byte),可实时给出FIFO的满空标志,并可实现数据的平滑输出,其写时钟为带间隔的100MHz,读时钟为5MHz,从而实现了FIFO的异步数据传输。

2、FIFO的应交定义(3)写数据控制器引脚对照表:(4)读数据控制器引脚对照表:二、总体设计方案1、电路设计方框图(如图2.1所示)图2.12、电路设计连接图(如图2.2所示)3、电路模块及其功能简介双口256*8bit的RAM:用于存储FIFO的缓冲数据写数据控制器:用于控制FIFO中数据的写时序操作FIFO 读数据控制器:用于控制FIFO数据中的读时序操作锁存器:用于锁存上一个clock时的读写地址指针FIFO满空标志电路:用于实时标志FIFO的满空状态4、电路设计思想设计高速异步FIFO,首先,考虑如何实现数据的先进先出问题;为了解决这个问题,设计中就必须有一个可用于随机存取的存储器,又要实现异步,即异步读写,所以本设计中存储器选择采用双口RAM;其次,考虑如何实现在不同时钟下,实现读数据和写数据,在设计中,使用独立电路模块,分别控制读写操作;最后,一个要考虑的问题也是本设计中的难点,即对于高速异步FIFO来说,如何高速、实时判断FIFO的满和空。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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和读模块。

RAM产生模块,以及双端口存储rd_empty空标志位
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
上升沿到达rd_clk的电路原型以及局部波形的放大。

由于Fig.2.2.1上图是
三寄存器的时间各不相同,这就导致了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
1001
1110 14
15 1111 1000
0 0000 0000
2.3.2 二进制和格雷码的相互转换
1、二进制到格雷码:
gray[n?1]?bin[n?1];gray[n?2]?bin[n?2]?bin[n?1];??????g
ray[2]?bin[2]?bin[3];
gray[1]?bin[1]?bin[2];gray[0]?bin[0]?bin[1];
a?0?a?0?a?0?a,所以它们之间有如总结上述转换规律,又知
gray[n?1:0]?(bin[n?1:0]??1)?bin[n?1:0];下简化关系:2、格雷码到二进制:
bin[0]?gray[n?1]?gray[n?2]?...?gray[1]?gray[0];bi
n[1]?gray[n?1]?gray[n?2]?...?gray[1];.........bin[n?2 ]?gray[n?1]?gray[n?2];bin[n?1]?gray[n?1];
a?0?a?0?a?0?a,所以它们之间有如总结上述转换规律,又
知?(gray[n?1:0]??i);.................(0][bini??i?n?1)下简化关系:格
雷码计数器的实现 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。

相关文档
最新文档