微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 跨时钟域FIFO的老话题:快时钟域的地址信息如何同步到慢时钟域?

跨时钟域FIFO的老话题:快时钟域的地址信息如何同步到慢时钟域?

时间:10-02 整理:3721RD 点击:
昨天面试被问题这个问题,面试官问译码FIFO的关键技术,如何解决?
我当时以为理解的没问题,就按照Clifford Cummings的论文上来讲。关键技术在于处理译码读写时钟域的地址信息,产生空满信号。解决方法是使用同步器降低亚稳态,使用格雷码保证每次只变1位,即使采错也是+1或-1的问题,不会造成致命错误。
但那个面试官就说,如果两个时钟相差很大,怎么保证快时钟域的信号传递到满时钟域?
我说需要在快时钟域进行信号宽带的展宽,保证被慢时钟域采到。
接着他就问,那FIFO两侧不能这样做吧,怎么保证快时钟域的地址被慢时钟域采到?会不会出现问题?
我就蒙了,感觉有问题,但觉得应该没问题。就说没问题,但不知道为什么?
希望明人指点

要使用hand shake 機制,通過一訊號傳達溝通


不要忘了 这是在FIFO里 地址有可能一直变 握手来得及吗?

我觉得既然是FIFO,就一定满足满了就不能再写,空了就不能再读这一个前提。
假设我们说写的时钟很快,而读的时钟很慢,那满标志的判断就得利用到从读时钟域同步过来的读地址,这是一个从慢到快的同步,就不说了。
空标志的判断需要将写时钟域的地址同步到读时钟域,因为写时钟很快,所以写地址的变化也很快,但无论变化得多快,一定是写到满为止。那同步到读时钟域的写地址到底是哪一个呢?我想这个没办法确定,也不需要确定,但唯一能确定的就是用传到读时钟域的写地址做空标志的运算,不会造成空读这种现象,原因是当某个写地址传到读时钟域后,写地址的当前值一定是大于或等于传递过去的写地址(我这里想说明的是FIFO中有多少数据,不是做地址大小的比较)。
所以从快到慢,这里是不需要展宽的,也不需要关于慢时钟到底采到了哪一个写地址。
因为使用了gray码,一次只有一位数据发生了变化,所以假设因为亚稳态出现了采错的情况,也不会发生任何错误(不是小编说的不会发生致命错误,我想只要是这里发生了错误,就一定是致命的),可以这样分析原因,产生亚稳态的条件,数据在setup-hold time的时间窗内发生变化,无非是从0变到1,或从1变到0这两种情况,以从0变到1为例说明,如果因为亚稳态采到了0,那传递到慢时钟域的就还是上一个地址,如果采到了1就是正确的,想要的当前地址,一定不会采到下一个地址去,从1到0也是一样的情况。

不需要展宽信号,如果从快到慢同步,不管时钟相差多大,同步过来的指针总是滞后于实际指针,因此最多造成虚空虚满,不会有问题的。

好久以前我就想在论坛上问这个问题,现在终于有人问了,还有热心人详细解答了,感谢感谢。

    现在有个问题就是,格雷码是保证相邻两个数字只有一位跳变,那么有个问题:从快时钟域过渡到慢时钟域的地址,不一定能保证慢时钟前后两拍所采到的是两个相邻的地址的值,有可能慢时钟采到一拍来自快时钟域的地址之后,在慢时钟的下一个有效沿到来之前,快时钟域的地址已经跳变了几次了,这样慢时钟所采到的地址也可能同时变化了好几位,这样做格雷码转换就失去意义了。这个问题一直困扰着我


1. 快时钟域地址变化很快,但我想在某一个时刻慢时钟域只能采到其中的一个地址,把这个地址传到慢时钟域,这个过程跟用什么编码没有关系,无论是gray code还是bin code都是一样的。2. 对于多bit数据,gray code只是能降低整个数据因发生亚稳态而采到数据的范围。举个例子,如果使用二进制编码,4'b1111跳变到4'b0000,因为4根数据线都在发生变化,都可能产生亚稳态,在这种情况下,采到的数据可能值范围是0x0~0xf。
假设使用gray code, 4'b1111跳变到4'b1110,只有一根数据线在发生变化,如果发生亚稳态采到的数据范围仅限于0xf和0xe这两个值,因为其它三根线没有发生变化,所以不会产生亚稳态。
所以我觉得gray code的意义在于慢时钟采到当前的数据时发生亚稳态的几率,而不是因为快时钟域内地址变化很快导致慢时钟两次采到的数据不是相邻的,这之间没有什么关系,慢时钟某一时刻只能采到一个值,但我们不希望慢时钟在采数据的时候这个数据的每一个bit都在变化,所以相邻可以理解为相邻两个时钟沿之间的数据变化,而不是具体的数据值。
看一下这样解释gray code的意义您能不能理解。

继续关注~



    谢谢热心的指教。我的问题主要是这个意思:格雷码是保证二进制情况下相邻的两个数字只有一位跳变,例如从011到100,格雷码分别是010和110,这样没什么问题。但是我困惑的是,从快时钟域过度到慢时钟域的时候,假设慢时钟采第一拍的时候,快时钟域的地址是011转换为格雷码是100,当慢时钟采第二拍的时刻,快时钟域的二进制地址已经变成101而不是与011相邻的数(010或者100),这个时候转换成格雷码的值就是111了,也就是说慢时钟域第一拍采到的格雷码值为100,而第二拍采到的值为111,同时跳变了两位,这样在我看来格雷码就失去意义了,我很困惑。



   
    为什么你认为同时变化两bit就失去意义了? 你要明白
1. 格雷码目的是避免产生错误的空满信号,比如在fifo空/满的时候产生非空/非满指示,但是允许在非空/非满的时候产生空/满指示;
2. 前面多层楼已经解释得很清楚了,格雷码并不是不允许被采错或者采漏,而是限制了采错的时候的地址范围,比如同时采到2bit变化,那么真实的地址一定是在采到地址的相邻的2个地址范围内,再加上地址传递到慢时钟域时会至少用慢时钟打2拍,这样产生的空满信号是不会出错的。而如果使用线性码,采错的时候可能是任何一个地址,最后产生的空满信号就可能是错的。


说得相当好,

我面试也被问到这个问题了~


你这个疑问,clifford Cummings在他的论文里
http://www.sunburst-design.com/papers/
SNUG 2002
(San Jose)
Simulation and Synthesis Techniques for Asynchronous FIFO Design
with Asynchronous Pointer Comparisons
Rev 1.1
Apr 2002
Voted Best Paper
1st Place
SNUG 2002
(San Jose)
Simulation and Synthesis Techniques for Asynchronous FIFO Design
已经讲过了,你可以看看,你的楼下11楼讲的很对

4楼正解!



    thank  you



        thank  you



   说得很好!



   问一个很幼稚的问题,看你们讨论了这么多,从快时钟到慢时钟,读地址不是也应该一拍时钟变化一次么?怎么会变化多次呢?我之前的理解是,写信号按照输入时钟一个地址一个地址的写,输出按照读信号一个一个的读,如果地址差距为25%或者75%判断写满或读空。请高手指教

异步fifo两侧的时钟频率相差太大,异步fifo就失去的意义(格雷码就失去了意义)。
要用其他的方式同步,比如上面说的握手,就是一种。


格雷码存在的意义在于无论任何一个时钟上升沿,最多只有1bit在变化。这样就能保证在另一个时钟域转过来的地址是对的,要么正确的地址,要么前一个地址。 和两边哪边快慢无关。

gray码保证在某一个时刻,地址最多有1个bit会发生变化,这样在读时钟域采样的时候,最多也只是这个bit会采样出错,不会影响空满标志的判断。
比如写时钟域地址是这样变化的:000->001->011->010,读时钟域采样时,正确采样时如果是000->011,但是从001->011跳变时,只有一个bit发生了跳变,读时钟域采样时,在它的建立和保持时间窗口内,也只有中间1个bit可能会出错。

5楼说的很清楚了啊

之前对这个问题也是一知半解,谢谢各位的解释啊

格雷码是为了在不同时钟间(无论快到慢还是反之)同步地址的时候即使产生亚稳态也不会造成空满状态的误判。和两次采样隔了几个地址完全无关。
就是说如果慢时钟采样快时钟的地址,如果采样点是在快时钟地址变化的时刻发生,那么会产生亚稳态,但是此亚稳态只是地址中的一个bit的亚稳态,造成的结果就是这个采样值要么是当前正确的地址,要么是它上一个地址,所以不影响空满判断。
如果两个时钟相差太大,那么一下buffer就满了或者空了,那么用fifo就没有意义了

为什么不用快时钟域处理 ,满是中域向快时钟域同步呢

easy to implementation, using another fifo to transfer the address

學習了, gray code 原來是這樣用.

我是这样认为,写快于读的时候,一般情况下只会有满状态产生,不会出现空的状态吧。所以把读地址同步到写时钟域即可判断满或者临近满的状态就行了,而写地址同步到读时钟域时,同步需要有延时,而且,即便漏读跳过了某些写地址值,此时读到的写地址跟此时的读地址比较,也是多绕了一圈的地址,得到的也只能是满或者错误的满,而不可能为空。

看了大神们的解释,终于弄懂了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top