FPGA 设计之 跨时钟域的弹性Buffer

2022-05-27     大方老师单片机

原标题:FPGA 设计之 跨时钟域的弹性Buffer

FPGA设计跨时钟域Buffer

\\\插播一条:

自己在今年整理一套单片机单片机相关论800余篇

论文制作思维导图

原理+源代+开题报++外文资料

想要的同学私信找我。

在前面的文章中我们已经介绍了异FIFO的设计原FPGA设计跨时钟-FIFO)。我们知道为了防FIFO overflow underflow,异FIFO有空满信号。当满信号有效时会反压前级逻辑,不让其继续写数据FIFO内,当空信号有效时,则通知后级逻辑,数据已经全部读出,不让其继续读FIFO如果我们的应用需求是数据必须不断流入然后流FIFO呢?这意味着既不能反压前级也不能通知后级。

Buffer便是应用在这种需求下的一种跨时钟域的设计方法。本文将从以下几点介绍弹Buffer:

·Buffer的应用背景

·Buffer与普通异FIFO的区别

·Buffer的具体设计

·Buffer有什么缺点

Buffer的应用背景

在起初PCI总线设计中,采用的是同步时序结构,即发送端和接收端使用同步时钟,发送端只需要发送数据,接收端正常采样即可。这种同步结构要求时钟到达发送端和接收端的时间精确相同,特别是对总线接pin-to-pinskew要求极高。随着总线频率的提升,skew的要求也越来越高,使得时钟网络布线越来越困难。

因此,当前的很多高速接口设计,PCIeEthernet都是采用了源同步source-synchronous)时序结构,即发送端同时发送时钟和数据,接收端需要从接收到的数据中恢复出数据的采样时钟,用该时钟来采样收到的数据。这种设计方式虽然避免了上述的问题,但是也带来了新的问题,即跨时钟域的问题,因为这种设计结构下一般会有两个时钟域,Recovered Clock Domain Local Clock Domain。一般来说Recovered Clock Local Clock之间频率只有些微的差别,弹Buffer便是用来解决这种情况下的跨时钟域数据传输问题的。如1所示:

1 - PCIe器件中使用弹Buffe做跨时钟域处理

Buffer与普通异FIFO的区别

普通的异FIFO读写时钟不同,随着数据的不断写入或者不断读出,最终必然会到达满或空的状态,从而停下数据从写时钟域向读时钟域的流动,直FIFO不再为满或空。

对于弹Buffe来说,读写时钟之间独有些微的差别,频次近似。数据会不断从写时钟域流向读时钟域的,为了到达这个目标,弹Buffer会自己丢弃或者插入数据来补偿读写时钟之间的频/相位差。应用弹Buffer的总线协议会定义特定Symbol,假PCIe协议SkipEthernet协议IDLE,这些特殊定义Symbol就能够被用来丢弃或者插入而不影响正常的数据传输。

Buffer的详细设计

从上一局部的内容我们能够看出来,弹Buffer相比普通异FIFO主要是增加丢弃或插特殊字符的逻辑,同时也没有满空信号。

1G Ethernet协议为例Ethernet协议要求两个包之间须要发送特殊字IDLE,该字符能够被弹Buffer用来做时钟频/相位的补偿。我们的设计10bit位宽的数据,采样时钟125M,读写时钟之间允许最高300ppm的频次差别。

如何考Buffer的深度

+/-300ppm的容忍程度,频次范围则是124.9625M~125.0375M之间。以最差情况看,假入写时钟124.9625Mhz8.0024ns),读时钟125.0375Mhz7.9976ns)。两者之间时钟周期的差0.0048ns,也就是说 7.9976/0.0048=1666Cycle会有一次时钟周期的漂移。

Ethernet最长的包1500bytes计算,一个包会跨 (1500*8)/10=1200Cycle。所以一Ethernet包至多有一次时钟周期的漂移。假设我们想在每次漂移之后都做时钟补偿,那FIFO的深度4即可,想留一些裕量则能够考虑更大的深度,816

如何决定是否丢弃或插IDLE字符

FIFO深度4为例。FIFO的正常工作模式下,我们会FIFO总是处在半满状态,即2个数据。然后我们设置两个阈值31。当

【文章福利】:小编整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!~点击绿色通讯软件搜airuimcu加入。

FIFO内所含的数据大于等3时,我们认为写时钟过快,则丢IDLE字符。FIFO内所含的数据数目小于等1时,我们认为读时钟过快,需要插IDLE字符。

那么什么时候丢弃或插入呢?当然不能在一Ethernet包内,因为这样会导致数据传输错误。前面我们已经提到在两Ethernet包的间隔,协议要求要发IDLE字符,我们可以在间隔期间看IDLE字符后选择丢弃或插入。

综上,我们设计的弹Buffer可能会是这样的一个工作流程:

.FIFO上电后达到半满状态

.数据不断流FIFO再流出FIFO一直处于半满状态,所存数据个数2

.一个新Ethernet数据包来临,在传输这个包期间FIFO的读写时钟发生了一次漂移,写时钟更快。导FIFO内所存放的数据个数变成3

.Ethernet包传输结束,发送端开始发IDLE字符,我们检测IDLE字符后同时检FIFO内的数据个数,发FIFO不是半满,而3

.我们认为写时钟快了,则丢弃接下来收到IDLE字符,直FIFO恢复半满

Buffer就不需要考OverflowUnderflow了么?

因为我们对弹Buffer的深度设计是基于读写时钟之间ppm差计算的,如果能保证读写时钟ppm差满足要求,那么是不用考虑的。

如果无法保证,我们则需要考虑增OverflowUnderflow的判断,并报Error。一旦出OverflowUnderflow我们认为系统无法正常工作,需要停止运行。

Buffer有什么缺点

从弹Buffer的设计可以看出,其主要的缺点是会带来延迟。为了保证弹Buffer在正常情况的半满状态,我们需要先将数BufferFIFO中。上文中的设计,弹Buffer会引入至3Cycle,至2Cycle的延迟。

总结

本篇文章主要介绍了用于跨时钟域的弹Buffer的应用背景和设计原理。

文章来源: https://twgreatdaily.com/zh-hans/211445a241dad7a1d1ca3b5d364fe5e4.html