Saber 酱的抱枕

Fly me to the moon

10/29
2020
学习

跨时钟域电路(CDC)杂记

关于CDC(clock domain crossing)的知识可谓是满天飞。有太多太多人组织、分析……我不是来重复这个的。我……
我流.jpg
那么我也要写出“我流”的杂记

CDC电路五花八门,但是最终要考虑的,其实就三个问题:

1.抑制亚稳态的传播

最最最最常见的多DFF就是这个了,通过多个DFF同步尽力降低亚稳态向后传递的概率。这概率有公式可算,不多说。总之就是一般就2个DFF,要是高频可以进一步增加。(我觉得可以说多DFF基本是CDC电路不可或缺的基础方法……)
但是,符合这个特性,并不一定满足下面其他的特性。
(另,似乎有见到过meta stable的cell,但是应该也会是这样)

2.保证每bit(单bit)信号不漏不错

多DFF虽然能够抑制亚稳态,但是并不能保证抑制完出来的信号是正确的——本来进来的是1,不幸产生了亚稳态,虽然被强行归正到一个确定的信号,但并不一定是1,完全可能是0。
要保证这个,就需要其他手段,例如延长信号时间。比如那个1.5T还是几T的原则,比如握手法中产生电平信号。信号时间长了就有足够的时间去读到一个稳定态了。
但是,单纯的传一个电平信号到另一个时钟域,并不能保证不会被对面抓到亚稳态,运气不好时完全可能发生。(试想你的电平过来时刚好就在对面的时钟上升沿附近)所以还得结合前面一条抑制亚稳态的做法去做。
看起来保证不漏不错这条是正确的废话,但是世间总是有例外:异步fifo(指Clifford E. Cummings的设计)的指针同步就偏偏不需要保证这一点,就算漏采错采也没有多大关系。这个也被无数人说过了,也不多提。
当然,满足这个也不会就天然满足下一条。

3.多bit信号对齐(skew的解决)

应该也都基本上知道这个问题的重要性了。就算你发过去的是几个电平,虽然保证对面总是能收到,但并不能保证对面在哪一T收到:也许就刚好错过了要等下一T,这就使得多bit中不是每一bit都是对(同步)的。(虽然说起来和2有点像,但是,总之有那么一点区别……)所以这个也要特别处理。


如何指导CDC电路选择

纵观五花八门的CDC电路,无非就是组合各种手段解决这三个问题。例如握手就是结合了电平信号和多DFF解决了1和2,但不会天然就解决了3。格雷码很神奇地在某种程度上解决了3(再次,参考异步fifo),但本身并没能解决1和2。也因此如何选用CDC电路也可以从这三点入手,你的电路有哪些问题,就针对性的去选就好了。

论外

当然了还有异步fifo之类这种论外级别的电路,通过储存再读取的方式进行。这的确是无敌的解法,延迟也相当低。在我看来,一般的CDC电路是确实地在两个CD之间交互,而论外方法是把信号提到了CD之外(储存),因此等级上和其它CDC完全不一样233但且不提这里面本身就含有CDC电路,也不提设计的复杂性与问题隐藏的深度,这面积还是会增大的吧……

共性(我流的总结)

除了论外级,CDC的电路目标是,把信号放在对面CD里呆几T(当然,是对面CD的几T),再参与到对面的使用中去。这里的呆几T,不一定限定在某一个cell,可以是一个DFF链(这就是多DFF嘛)。当然一般的逻辑电路是不行的,那不就直接用了……
最体现这点的,莫过于下面这个多bits信号CDC电路:
https://zipcpu.com/blog/2020/10/03/tfrvalue.html
见Fig 3. A proposed 2-phase CDC structure

假装我是图.jpg

你可以看到,多bits的data就这么直直地扔到了对面CD。但是单bit的控制信号仍然是走握手法类似握手的方法传了过去,这使得data在对面CD充分地稳定了一段时间,等到控制信号终于同步过去之后,所有bits早就都稳稳地到达了目标MUX/DFF上。(我在想,这里bits够多的话,做成clock gating行不行?毕竟这博主是做FPGA的,对这事没那么关注我猜)这样就能正确地锁存data了。


关于仿真

异步电路仿真是很难受的,主要是前仿都是理想电路,很多问题都仿不出来。如果问题全积累到后仿…………
有一个方案是这样的。CDC电路中同步的每一bit加入随机延迟(多bits的每一bit延迟时间不同)来模仿skew。反正delay是会被综合器无视的仅仿真参数。这样就能在一定程度上在前仿中发现问题。
当然了现代设计中异步电路仍然需要后仿,这个跑不了。这里面还涉及到LEC问题。不提了。


大概这样就能对CDC问题有一定认识了吧,我猜。

跨时钟域电路(CDC)杂记