1 引言
FIFO(First IN First Out)先进先出电路是一种实现数据先进先出的存储器件,普遍用作数据缓冲器。FIFO的基本单元是寄存器,作为存储器件,FIFO的存储能力是由其内部定义的存储寄存器的数量决定。
FIFO通常是双端口的存储器,其中一个端口用于写入数据,而另一个端口用于读出数据。可以同时对存储器字存储单元进行写入和读出操作。它的数据吞吐率是普通RAM的两倍。FIFO型的存储器不需要由地址来存取数据。需要由另外的信号线(或标志)来指明存储器的内容状态。
在现代数字系统设计中,FPGA(现场可编程门阵列)器件凭借其灵活、方便、资源丰富的优势在很多领域得到了广泛应用。随着其片内存储资源的增加,把FIFO器件集成到其中是一种方便地代替专用芯片的实现方法。根据异步逻辑的设计方法,引入乒乓操作的设计技巧,给出了一种新颖的异步FIFO设计方案,解决FPGA多时钟系统中不同时钟域传输数据的问题。
2 异步FIFO的设计与实现
2.1 通用异步FIFO的基本结构
在现代的集成电路芯片中,随着设计规模的不断扩大,一个系统中往往含有数个时钟。多时钟域带来的一个问题就是,如何设计异步时钟之间的接口电路。异步FIFO是解决这个问题一种简便、快捷的解决方案。使用异步FIFO可以在两个不同时钟系统之间快速而方便地传输实时数据。在网络接口、图像处理等方面,异步FIFO得到了广泛的应用。
异步FIFO常用于存储、缓冲在两个异步时钟之间的数据传输。在异步电路中,由于时钟之间周期和相位完全独立,因而数据的丢失概率不为零。如何设计一个高可靠性、高速的异步FIFO电路便成为一个难点。下面将介绍解决这一问题的一种方法,其结构框图如图1所示。
本系统FPGA内部FIFO的存储介质是一块双端口的RAM,具有两个独立的读写时钟,整个系统也分为两个完全独立的时钟域——读时钟域和写时间域。FIFO的控制逻辑执行所有的读写指针管理,产生各种状态标志。在写时钟域部分,由写地址产生逻辑产生写控制信号和写地址;读时钟域部分由读地址产生逻辑产生读控制信号和读地址。在空/满标志产生部分,由读写地址相互比较产生空/满标志。本设计的外部引脚如表1所示。
这种FIFO设计当中有两个难点:一是如何正确地设计空、满信号的控制电路;二是如何同步异步信号,使触发器不产生亚稳态。下一小节将具体阐述解决方法。
2.2 FIFO的读写控制
空/满标志的产生是FIFO的核心部分,如何正确设计这部分逻辑,直接影响到FIFO的性能。空/满标志产生的原则是:写满不溢出,读空不多读。即无论在什么时候,都不应出现读写地址同时对一个存储器地址操作的情况。在读写地址相等或相差一个或多个地址的时候,满标志应该有效,表示此时FIFO已满。在满信号有效时若继续向FIFO写数据,应根据设计的要求对数据作保持或抛弃重发处理,空标志的产生也是如此。
最直接的做法是,采用读写地址相比较来产生空满标志。当读写地址的差值等于一个预设值的时候,空/满信号被置位。这种实现方法逻辑简单,但它是减法器形成的一个比较大的组合逻辑,因而限制了FIFO的速度。所以,一般只采用相等不相等的比较逻辑,避免使用减法器。即:
空标志<=(|写地址-读地址|<=预定值)AND(写地址超前读地址)
满标志<=(|写地址-读地址|<=预定值)AND(读地址超前写地址)
另一种方法是,比较器只对读写地址比较是否相等。在读写地址相等的时候有两种情况:满或者空。所以,附加了一个并行的区间判断逻辑来指示是空还是满。这个区间判断逻辑将整个地址空间分为几个部分,以指示读写地址的相对位置。这种做法提高了整个电路的速度,但是也有其缺点。主要是直接采用读写地址等于不等于的比较逻辑来进行空/满标志的判断,可以带来误判。
将读写指针位宽分别定义为:rp[aw:0]和wp[aw:0],其中rp[aw]和wp[aw]为最高位进位位,rp[aw-1:0]和wp[aw-1:0]分别表示读写指针寻址的地址。当读写指针每次从初始地址处读写到最后一位地址位时,均需向最高位rp[aw]和wp[aw]进位。因为先有写才能有读,所以当wp[aw-1:0]=rp[aw-1:0]时,只要判断wp[aw]与rp[aw]是否相等就可以知道是写指针追赶上读指针写满了(wp[aw]!=rp[aw]),还是读指针追赶上写指针读空了(wp[aw]=rp[aw])。rp_pl1和wp_pl1分别定义为读写指针的下一个地址,而且为了在判断空满标志时对读写指针进行同步比较,设计中定义了与rd_clk同步的写指针wp_s以及与wr_clk同步的读指针rp_s,这两个信号可以通过同步逻辑来实现。
2.3 跨时钟域设计带来的亚稳态问题
亚稳态(Metastability)是指触发器信号和时钟不满足建立时间/保持时间(setup/hold)的基本要求,触发器的输出端将会达到一个不确定的状态。当一个触发器进入亚稳态时,既无法预测它的输出电平,也无法预测其输出何时才能稳定在某个正确的电平上。在这期间,触发器输出一些中间级电平,或者可能处于振荡状态,并且这种无用的输出电平可以沿信号通道上的各个触发器级联式传播下去。当一个信号跨越某个时钟域时,接收该信号的电路需要对其进行同步,用以防止前级存储单元(触发器)的亚稳态在新的时钟域里传播蔓延。
在本系统中内部工作时钟有两个互相异步的不同频率时钟,并且在两个时钟域的逻辑模块之间有许多控制信号需要传递,亚稳态是不可避免的,但是下面的设计可以将其发生的概率降低到一个可以接受的程度。
①对写地址/读地址采用格雷码。由实践可知,同步多个异步输入信号出现亚稳态的概率远远大于同步一个异步信号的概率。对多个触发器的输出所组成的写地址/读地址可以采用格雷码。由于格雷码每次只变化一位,采用格雷码可以有效地减少亚稳态的产生。
②采用两极触发器来同步异步输入信号。信号同步的目的是防止新时钟域中第一级触发器的亚稳态信号对下级逻辑造成影响。两级寄存器的同步化处理单元由两个触发器串联而成,中问没有其它组合电路。这种设计可以保证后面的触发器获得前一个触发器输出时,前一个触发器已退出了亚稳态,并且输出已稳定。但是,这种方法同时带来了对输入信号的一级延时,需要在设计时钟的时候加以注意。
虽然亚稳态是不可避免地,但是采用格雷码可以有效地减少亚稳态的产生。由前面的分析可以看出,由地址直接相减和将地址相互比较产生空/满标志都不可取。如何简单地进行直接比较,又不提高逻辑的复杂程度呢?对地址加延时可以做到这一点。
设读地址为rp_bin,用读地址产生读地址格雷码rp_grap_next,将rp_grap_next延一拍得到rp_grap,再将rp_grap延一拍得到rp_grap_x。在绝对时间上,rp_grap_next、rp_grap、rp_grap_x先后从大到小,相差一个地址,如图2所示。写地址也与此类似,即:wp_grap_next、wp_grap、wp_grap_x。利用这6个地址进行比较,同时加上读写使能,就能方便而灵活的产生空/满标志。
以空标志empty产生为例,当读写格雷码地址相等或者FIFO还剩下一个深度的字,并且正在不空的情况下执行读操作,这时empty标志设置为有效。即:empty<=(rp_gray==wp_gray)and(re== 1)或empty<=(rp_gray_next==wp_gray)and(we==1),同理可类推满标志的产生逻辑。
3 Verilog实现与仿真
本设计完成了一个完整的规格为256×8双时钟通用异步FIFO的Verilog建模,并对该设计的编写测试向量进行行为级仿真,仿真工具采用ModelSimSE6.0。图3给出了整个电路的仿真时序图。分析上面读写时序图中各状态变化和数据的传输情况,验证各状态信号时序正确,逻辑正确,功能仿真结果正确,整个的工作波形也符合设计要求。
图3 双口异步FIFO读写仿真波形
最后,用Synplify7.6 Pro软件进行综合,器件为Altera的EP1C6Q240C8。一般标志产生电路(用减法器,设阈值)和基于格雷码的标志产生电路,设计结果性能指标对照表如表2所示。
由表2可知,带区间指示逻辑设计的双时钟通用FIFO的特点是直接对读写指针地址进行比较,并通过辅助的区间指示来判断FIFO的读空与写满。这种方法正如前面所说的,因为避免了地址的减法比较,所以减少了逻辑的复杂度,提高了系统的速度,但是也容易出现一定的误判断现象,而且由于双时钟FIFO出现异步的情况,容易产生亚稳态现象,这种方法亦不能很好地解决。我们可以通过设计格雷码双时钟通用FIFO来较好地处理亚稳态的问题,提高了系统的稳定性。但是不可避免地,较之一般方式的FIFO来说,需要有更多的逻辑单元,需要用更长的数据传输时间。
4 总结
本文提出了一种新颖的用FPGA实现异步FIFO并作为异步时钟域数据传输的接口电路的方法,特别详述了空、满信号的产生。按此方案设计的异步FIFO的软件仿真和硬件实现都已经通过了验证,并应用到实际的电路。实践证明用此方案设计的异步FIFO具有性能稳定、空满状态标志可靠等特点。
文章评论(0条评论)
登录后参与讨论