摘要:FIFO经常应用于从一个时钟域传输数据到另一个异步时钟域。为解决异步FIFO设计过程中空满标志判断难以及FPGA亚稳态的问题,提出一种新颖的设计方案,即利用格雷码计数器(每次时钟到来仅有1位发生改变)表示读/写指针,设计二级同步链为跨越不同时钟域的读/写指针,以提供充足的稳定时间,并通过对比格雷码指针产生空满标志位。该设计采用VHDL语言进行设计,利用ALTERA公司的FPGA得以实现。经验证进一步表明,模块化的设计不仅避免了亚稳态的产生,增大平均无故障工作时间(MBTF),也使工作效率大为提升。
关键词:FIFO;异步;亚稳态;格雷码
先进先出缓存电路读/写(FIFO)在大规模逻辑设计中被广泛应用,几乎每个芯片都要涉及,同样在空空导弹的数据传输体系中也得以大量应用。FIFO类型可以分为两种,第一种为同步FIFO,即读/写时钟是同步的,这里的同步不仅仅是指读/写时钟为同一个时钟,即属于同一个时终域。当读/写时钟频率为倍数关系,即相位关系确定时,也归属同步FIFO的范畴。另一种为异步FIFO,读/写时钟频率不成倍数关系或相位关系不确定,即跨时钟域。异步FIFO可以在不同的时钟域之间快速方便地传输实时数据,因此在遥测数据传输中,异步FIFO实用性更好。然而如何正确地产生空满标志以及如果解决亚稳态问题是异步FIFO设计的难点。
1 FIFO结构
首先,典型的FIFO结构框图如图1所示。FIFO的数据存储在具有独立写端口和读端口的RAM中。读指针r0_pointer指向下一个将要读取的位置,写指针wrpointer指向下一个将要写入的位置,每1次写操作后写指针加1,读操作使读指针加1。状态产生模块中,full和empty表示FIFO读/写的临界状态。FIFO设计的关键是产生读/写地址和空满标志。空满标志是基于引起指针相等的操作。如果是复位或者读操作引起
读/写指针相等,FIFO认为是空;如果原因是写操作,那么FIFO认为是满。异步FIFO设计的难点是如何同步跨时钟域的指针以及空满标志的产生。
2 亚稳态
亚稳态是当信号在无关的电路中或异步时钟域之间传输时导致FPGA系统失效的一种现象。包括FPGA在内的所有数字器件的寄存器都定义了信号时序要求,以保证每一个寄存器都能够从输入端获取数据和在输出端产生数据。为了确保可靠的操作,输入信号必须在时钟沿之前稳定一段时间(寄存器建立时间tsu),并且在时钟沿之后稳定一段时间(寄存器保持时间th),然后寄存器输出经过一个特定的时钟到输出延时后有效。满足此要求寄存器才可以正确的在输入端获取数据在输出端产生数据,否则输出有可能是亚稳态。在亚稳态时,寄存器的输出电压在高低电平之间摇摆,即输出将有可能是逻辑0(0 V)或者逻辑1(+5 V),或者是介于0~5 V中间的某个值。亚稳态产生机制图如图2所示,当建立时间或者保持时间不满足时序要求时便会产生亚稳态。
在同步系统中,输入信号必须总是满足寄存器时序要求,所以亚稳态不会发生。亚稳态问题通常发生在当一个信号在无关的线路中或异步时钟域中传输。一个寄存器进入亚稳态和从亚稳态进入稳态的时间依赖于制造商的制造工艺和使用环境。大部分情况下,寄存器会很快的进入一个定义的稳态中。在异步FIFO设计中就要避免亚稳态的产生。
3 解决问题的方法
3.1 同步寄存器
当信号在不相关或者异步时钟域传输时,在新的时钟域使用这个信号之前必须进行同步,比如异步FIFO的读指针被同步到写时钟域或写指针被同步到读时钟域。新时钟域里的第一个寄存器的作用就是一个同步寄存器。同步装置中寄存器到寄存器路径上的时序裕量可以为亚稳态信号提供稳定时间。由两个寄存器组成的二级同步链如图3所示,它大大的提高了系统的平均无故障工作时间(MTBF),减少了信号传输过程中亚稳态问题的风险。此外,可以通过三级同步进一步增加MTBF值,但在实际中很少需要。
3.2 格雷码(Gray code)计数器
设计异步FIFO的原则是安全可靠地把数据从一个时钟域传输到另一个时钟域。如果用一个相对于计数器时钟是异步的时钟来取样计数器的值,就要考虑计数器的每一位在哪个范围内变化,每一位都有机会同时发生变化,比如从FFFF变化到0000,这时每个单独的位都处于亚稳态。这种变化意味着读数有可能是0000~FFFF之间的任意一个值。这种情况下FIFO将无法正常工作,于是设计一个格雷码来表示的计数器,
因为格雷码是最小距离码,相邻的码元只有1位不同,它可以避免因延迟不一致而引起的毛刺现象。
计数器由触发器组和累加器组成,处理格雷码计数器的办法为:将格雷码转换为二进制码元,然后加1,再将它转换回格雷码并存储,这是解决产生N位格雷码算法棘手问题的一个办法。异步FIFO的写地址和读地址由格雷码计数器来实现计数,读/写指针均用格雷码来表示,格雷码计数器指针原理如图4所示,当FIFO非空或者非满时,读指针或者写指针实现加1操作。
3.3 一种新颖的设计方法产生空满标志
空满标志位是通过比较读/写指针来判断的,空满标志的判断方法:对于二进制地址来说,如果RAM大小为M,那么它需要的地址位宽度为N=log2 M。假设双口RAM大小是8 B,所需寻址地址位宽度是3 b。如果读/写指针均用3位来表示的话,那么当读/写指针相等时,无法判别是读时针追上了写时针造成读空还是写时针追上了读时针造成写满,这样就无法正确判断空、满标志。为了方便的区分空、满,读/写指针各增加1位,取地址指针宽度为log2M+1,寻址中没有使用的最高位地址标记为MSB,即读/写指针为N+1位,寻址范围为2n。表1为格雷码表示的4位地址指针。
仔细观察表1并分析数据,一种新颖的判断空满标志的方法为:当读/写指针的最高位(MSB)不相等且读/写指针的次高位不相等,剩余的N-2位地址相等时,此时写指针追上了读指针,即写指针比读指针多转一圈,状态模块输出满标志;当读/写指针N+1位都相等时,状态模块输出空标志。判断满标志部分的VHDL代码:
3.4 异步FIFO总体设计
通过时针比较产生的异步FIFO框图如图5所示。WCLK和RCLK分别为读时钟和写时钟,wrst_n和rrst_n分别为读/写模块的复位信号。 rdata为数据输出端口,wdata为数据输入端口。异步FIFO通过读/写指针来寻址一个双口RAM来实现对数据的读/写,双口RAM的大小为2nB。读指针被二级同步链到写时钟域,然后与写时针比较产生满标志,读指针产生读地址raddress;写时针被二级同步链同步到读时钟域,然后与读时钟比较产生空标志,写指针产生写地址waddress。需要注意的是此异步FIFO设计中,空满标志是保守的空满标志,比如满标志,当读时针通过二级同步链同步到写时钟域且满足满标志的条件时,写指针停止加1操作,而同步读指针的过程中,读时针则移动到了其他的地址,同样的适合于空标志,当输出空,满时,其实FIFO的真实状态是还有空间没被写满或者读空,这就是保守的空和满,而这正保证了FIFO不会向上会向下溢出,进一步提高了FIFO工作的可靠性。
表2为平均无故障工作时间的对比,C1和C2依赖于器件工艺。
4 结语
一个高的平均无故障工作时间表明一个设计是优秀的,提高亚稳态的平均无故障工作时间减少信号传输中导致亚稳态问题的风险。本文通过研究FIFO的基本结构以及FPGA亚稳态的产生机理,提出了利用二级同步链和格雷码计数器指针解决了同步以及空满状态判断的难题,给出了VHDL软件代码,且该设计已经通过QuartusⅡ的时序仿真验证,作为独立模块可以应用到需要异步时钟域传输数据的电路中,大大提高异步数据传输效率及平均无故障工作时间。