跨时钟域FIFO

集成电路基础与数字电路设计2018-06-19 11:43:17

主要内容摘自:

基于Verilog HDL 的异步FIFO设计与实现(山东大学信息科学与工程学院,山东济南250100 魏芳,刘志军,马克杰)

发送数据端的时钟与接受数据端的时钟是一样的那么就是同步FIFO,发送数据端的时钟与接受数据端的时钟是不同的,也就是说是跨时钟域的那么就是异步FIFO

当数据从一个时钟域传递到另一个时钟域,并且目标时钟域与源时钟域不相关时,这些域中的动作是不相关的,从而消除了同步操作的可能性,并使系统重复的进入亚稳态状态。在有大量的数据需要进行跨时钟域传输且对数据传输速度要求比较高的场合,异步FIFO是一种便宜,快捷的解决方案。

1异步信号传输问题的分析

在一个ASICFPGA库中,每种触发器都有时序要求,对于使用上升沿触发的触发器来说,建立时间是在时钟上升沿到来之前,触发器数据保持稳定的最小时间;保持时间是在时钟上升沿到来之后,触发器数据还应该保持的最小时间。当然不满足相应的建立时间和保持时间数据传输就会出现错误,还有两种错误在传输的时候会出现,相应的距离建立时间满足要求差的不多,第一种可能导致传输的时候D-Q的时间大大延长,造成delay比较大;另一中就是造成传输的时候进入决断时间(看到有这种说法,就是说状态是在改变,电容在充电或者放电,但最终状态无法确定),最终状态无法确定的亚稳态状态。一般这种情况与时钟频率很相关,一般是在打开电源或者是在电路工作过程中出现的。

后续的会影响到之后的触发器,导致连锁反应,从而使整个系统功能失常;当一个信号跨越某个时钟域时,对新时钟的电路来说它就是一个异步信号,由于异步信号之间的时序是毫无关系的,因此比然后存在setup time hold time的冲突,为避免亚稳态问题,一般会采用双锁存器或者三锁存器的方式,即在一个信号进入另一个时钟域前,将该信号用两个锁存器连续锁存两次,最后得到的采样结果就可以消除亚稳态。消除亚稳态只是保证了信号电平的稳定,要在不同的时钟域中准确传输数据还需要一个接口电路。异步FIFO就是一种不同时钟域之间传递多位数据的常用方法。

2异步FIFO设计

异步FIFO是一种先进先出电路,用在需要实时数据接口的部分,用来存储,缓冲在两个异步时钟之间的数据传输。主要是由双口存储器,读地址产生逻辑,写地址产生逻辑,空满标志产生逻辑四部分组成,下图是一个简单的异步FIFO设计方案,读地址rptr和空标志rempty由读时钟wclk产生,而写地址wptr和满标志wfull由写时钟wclk产生。把写地址与读地址相互比较以产生空满标志。由于读写地址的变化由不用的时钟产生,所以对FIFO空或满的判断是跨时钟域的,如何避免异步传输带来的亚稳态以及正确的产生空/满标志是设计异步FIFO的难点。


PIC1异步FIFO结构框图

2.1读写地址产生逻辑

读写地址先一般有多位,如果在不同的时钟域内直接同步二进制码的地址指针,则很有可能产生亚稳态。例如,读指针从011变化到100时,所有位都要变化,读指针的每一位在读时钟的作用下,跳变不一致,即产生毛刺,如果写时钟恰好在读指针的变化时刻采样,得到的采样信号可能是000-111中的任何一个,从而导致空/满信号判断错误。由实践可知,同步多个异步输入信号出现亚稳态的概率远远大于同步一个异步信号的概率。解决这一问题的有效方法是采用格雷码。格雷码的主要特点是相邻的两个编码之间只有一位变化。下图是格雷码产生的逻辑框图。在读使能或写使能信号有效,并且空/满标志无效的情况下,读写指针开始累加,进行FIFO,进行FIFO读或写操作。二进制与格雷码的转换是一个异或运算:gnext=bnext>>1^bnext。格雷码gnext经寄存器输出格雷码指针ptr,这种方法采用了两组寄存器,虽然面积较大,但有利于提高系统的工作频率。


PIC2Gray Code Generation

2.2/满标志产生逻辑

正确的产生空/满标志是涉及任何类型的FIFO的关键点。空/满标志产生的原则是:写满而不溢出,能读空而不多读。传统的异步FIFO吧读写地址信号同步后再进行同步比较以产生空满标志,由于读写地址的的每一位都需要两级同步电路,大量使用寄存器必然要占用很大的面积。这种方法不适合设计大容量的FIFO。当读写可能出于空或满两种状态,必须区分FIFO是处于空状态还是满状态。传统的做法是把读写地址寄存器扩展一位,最高位设为状态位,其余低位作为地址位。当读写指针的地址位和状态位全部吻合时,FIFO处于空状态;当读写指针的地址位相同而状态位相反时,FIFO处于满状态,传统的异步FIFO工作频率低,面积大,下面介绍一种产生空/满的新方法。

通过异步比较读写指针ptr以及读写指针的最高两位进行判断,产生两个异步的空/满标志信号送入读写模块进行同步,最后向外部输出两个同步的空/满信号。空/满信号的产生过程如下图。对于深度是2n的异步FIFO,按照其读指针rptrn:0】和写指针wptrn0】最高两位的不同取值,可把地址空间分为四个象限。当写指针比读指针落后一个象限时,意味着写指针即将从后面追上读指针,FIFO处于可能将满状态,在下图中,空满信号产生逻辑框图中声明一个direction信号并把它置为1;当读写指针完全相等并且direction1时,则FIFO处于满状态并且把满信号afull置为0(低电平有效);当读指针比写指针落后一个象限时,意味着读指针即将追上写指针,FIFO处于“可能将空状态,或者当写操作复位信号wrst有效时,再进行读操作,则FIFO也处于可能将空状态,此时把direction信号置为0;当读写指针完全相等并且direction0时,则FIFO处于空状态,空标志aempty置为0


PIC3指针象限检测

读写地址异步相比较产生低电平有效的空/满标志,其汇总异步满信号(afull)要同步到写时钟域(wclk),异步空信号(aempty)要同步到读时钟域(rclk),以消除亚稳态的影响,并且向外界输出同步的空/满信号。下面以满信号(wfull)为例说明同步信号的产生过程:满信号afull是因为写地址追上了读地址并比读地址多循环一次所产生,此时不能再向FIFO中写入数据,否则会造成FIFO写溢出。由于写地址(wptr)的变化产生FIFO满标志afull,即afull的下降沿与wptr同属于写时钟域。当读时钟增加时,表明已经从FIFO中读走了一个数据,afull的上升沿与rptr同属于读时钟域。可见afull的由高变低与写时钟(wclk)同步,而由地变高则与读时钟(rclk)同步。由于满标志afull之影响FIFO的写入,故将其通布岛写时钟域。如下图,采用双锁存器法将afull过度到写时钟域,最后得到满信号wfull就输出写时钟域。代码如下:

wiredirset=~((wptr[nl^rptr[n"-1) ~(wptr[n1^rptrn))

 wiredirrst =~((~(wptrn]^rptrn1) (wptrn1~rptr hi))I~wrst)always@(po~dgehighornegedgedirsetornegedgedirrst)

if ( !dirrst) direction<= l'bO

 else if(!dirset)direction<= 1b1

elsedirection <= hish

 assign aempty=~((wptr==rptr、&&!direction)

assign afull=~((wptr==rptr、&&direction)

 always @(posedgerclkornegedgeaempty)

 if(!aempty){remptyrempty2} <=2"bl1

else{remptyrempty2}<= {rempty2~aempty}

 always@(posedgewclkornegedgeaful1)

if(!aful1){wfullwfull2}<=2"bl1

else{wfullwfull2}<= {wfull2~afull}


PIC4空满信号产生逻辑框图

异步比较法的关键是用异步比较结果的信号的下降沿作为最终比较结果的复位信号,而其上升沿则用传统的双锁存器法进行同步。最终得到的信号的上升沿与下降沿都属于同一个时钟域。与传统的先将地址信号同步再进行同步比较的方法相比,异步比较法避免了使用大量的同步寄存器,效率更高,实现更简单。

2.3保守的空/满信号

设计中的FIFO/满标志的设置是保守的,即FIFO/满标志的置位是立即有效的,而其失效则是在一段时间之后。例如一旦读指针追上写指针,就会立即声明一个低电平有效的异步空置位信号aempty。此信号会立即把上图中的set触发器置位,使触发器输出为1,即向外部输出同步的空信号rempty,并且保证了FIFO一旦为空,读指针就不增加,避免了FIFO的读溢出。当写地址增加时,表明FIFO已经非空,空标志aempty由低变高,此时可以进行安全的读操作。aempty信号的失效与写时钟同步。空信号rempty是在读时钟域中同步aempty信号得到的。由于同步器使用了两个触发器,因此空信号rempty的失效要经过至少两个时钟周期的延迟。所以,空信号的声明是及时的,而空信号的失效是保守的。也就是说,虽然FIFO已经非空了,但是空信号rempty要经过几个周期的延迟才能变成无效,满信号也是类似的。

有两种算法:

第一种:

构造一个指针宽度为N+1,深度为2^N字节的FIFO便于把格雷码指针转换为二进制指针)。当指针的二进制码中的最高位不一致而其他N位都相等时,FIFO为满;当指针完全相等时,FIFO为空。为比较不同时钟产生的指针,需将不同的时钟域的信号同步到本时钟域中来,使用格雷码视为了异步同步化时发生亚稳态几率最小。

第二种:

如上文,将FIFO地址分为4部分,分别用最高位的MSB00011011等来表示将满,将空等。

异步多时钟设计有以下原则(有些废话,摘自网络):

1)  尽可能将多时钟的逻辑电路分割成多个单时钟的模块,这样有利于静态时序分析工具来进行时序验证。

2)  同步器的实现应使得所有输入来自同一个时钟域,而使用另一个时钟域信号采样数据。

3)  面向时钟信号的命名方式可以帮助我们确定哪些在不同异步时钟域间需要处理的信号。

4)  当存在多个跨时钟域的控制信号时,要特别注意这些信号,保证这些信号到达新的时钟域仍能保持正确的顺序。