上一篇文章中我们分析了异步fifo内跨时钟域信号走线问题,反复提到了两个隐患:功能问题和性能问题。对于功能问题我们必须通过约束路径延迟来进行处理,对于性能问题可以通过加深fifo的深度来进行规避。那么就引出了这一篇的问题,fifo的深度应该设置为多深呢?
在此还是要重复一下我之前的观点,异步fifo的作用就是单纯的进行多比特信号的跨时钟域传输,其他的事情如缓存、整流、校验、数据拼接等功能理应在同步时钟域下去进行处理,因此异步fifo的理论上是有一个最小的满足需求的深度。这个深度应该满足什么要求呢?应当满足当fifo两侧均以慢时钟域无反压的满带宽传输数据时,上游不阻塞,下游不断流。
qrcks5rh2zl64024565502.jpg
为什么要以慢时钟为依据呢?很简单,如果以快时钟为依据,快时钟保持满带宽发送数据进入fifo,无论fifo多深都一定会压爆。当然了我们也可以设定一定的吸收突发的缓存能力,根据吸收最大突发的大小来设置异步fifo深度,不过正如上文所说,我建议吸收突发的功能由同步fifo来完成,不重要在异步fifo中糅杂太多的功能点,这篇文章也是基于该观点进行展开讨论。
所以说fifo深度的计算就简化成了这样一个问题:慢时钟域满带宽写入,快时钟域满带宽读出,既不反压又不断流时,fifo需要多深?或者倒过来也一样,总之以慢时钟域满带宽传输为基准)。
再把异步fifo结构图拿出来看看,同时令Twr为写时钟的周期,Trd为读时钟周期,Twr_sync是写指针异步走线延迟,Trd_sync是读指针走线延迟。
zsij425ieim64024565602.jpg
那么来思考一个问题,一个数据由写入了fifo到被写侧知道这个读被读取走,需要经历多长时间?
winc时写数据有效,下一拍Twr时间后数据稳定在寄存器Q端,同时写指针在写控制单元内完成跳变,准备开始漫长的传输过程。那么从winc有效到读侧知道了这个事,需要经过(Twr+Twr+Twr_sync+Trd*3),然后读侧就会把这个数读走了,但是写侧能立刻知道吗?不能啊,都指针还得回到写侧这边才知道被读走了啊,那么写指针到了读侧,需要下一拍读指针完成跳变然后再走回写侧共需要时间(Trd+Trd+Trd_sync+Twr*3)。因此写侧一个数据从winc有效的当拍知道有一个数写入,到知道了这个数被读走,一共会经历:
fdwxuub2hod64024565702.png
然后你想想如果这个时间已经很长了,那么这过程中噌噌噌的来了很多写侧的数据,fifo深度必然就不够。那么fifo被打满反压写侧,造成了慢打快且快时钟域无反压情况下出现了fifo反压上游的奇怪场景。所以要怎么样呢?fifo的深度必然要能够盛下这段时间内写侧来的所有数据来能保证不反压上游,所以有:
vo5dpqktxcj64024565802.png
那么这个公式就可以作为我们计算异步fifo深度的一个参考公式。当然,还需要一些经验者,比如在项目中我们一般默认约束Twr_sync和Trd_sync为70%的快时钟周期(基于偏恶劣的考虑,也可能约束更大)。不过说句实话哈,异步走线延迟和异步fifo深度实际上是逻辑环的关系,也就是说需要根据走线延迟推导深度,然后再根据深度推导延迟,然后再根据延迟推导...所以我们才需要一个经验值嘛。
来实际的算个fifo深度吧。现在是1GHz跨异步到2GHz,下游不会起反压,那么fifo深度最小需要设置为多少呢?代数Twr = 1ns,Trd = 0.5ns,Twr_sync = Trd_sync = 0.35ns,所以DEPTH >= (5*1.5+0.7)/1 = 8.2。所以fifo的深度至少为9项深,而在我之前交付的一个系统中,系统时钟为1GHz,SOC时钟为2GHz,异步fifo深度最终设定的深度是10项(最开始设置为8项,后改为10项)。
那么如果已经明确了fifo深度,也可以反过来推导异步路径走线延迟。假如说现在还是1G跨到2G,fifo深度定为10项,那么可以计算得到Twr_sync + Trd_sync
继续看上面的公式可以发现,如果读侧时钟降低的话,fifo就存在深度不足的风险,或者说指针走线延时会更紧张,比如1G跨1.5G情况下Twr_sync + Trd_sync
最后一个问题,算下异步fifo最深的情况,观察上面的公式:
d0cpyxbrdcp64024565902.png
Twr、Twr_sync、Trd_sync都和慢时钟有关,注意因为Twr为慢时钟,因此Trd最大值是Twr。那么DEPTH >= (10Twr + 0.7Twr + 0.7Twr)/Twr,大概12项深就是极限情况了,此时是两个互为异步关系的同频时钟域间进行异步数据传输操作。 |