EETOP 创芯网论坛 (原名:电子顶级开发网)

标题: Verilog基本电路设计之一(单bit跨时钟域同步) [打印本页]

作者: 杰克淡定    时间: 2016-6-15 17:31
标题: Verilog基本电路设计之一(单bit跨时钟域同步)
本帖最后由 杰克淡定 于 2016-6-21 19:37 编辑

     看到坛子里不少朋友,对于基本数字电路存在这样那样的疑惑,本人决定开贴,介绍数字电路最常见的模块单元,希望给初学者带来帮助,也欢迎大佬们前来拍砖。如果想要做数字设计,下面这些电路是一定会碰到的,也是所有大型IP,SOC设计必不可少的基础,主要包括异步信号的同步处理,同步FIFO,异步FIFO,时钟无缝切换,信号滤波debounce等等,后面会根据大家反馈情况再介绍新电路。
     首先介绍异步信号的跨时钟域同步问题。一般分为单bit的控制信号同步,以及多bit的数据信号同步。多bit的信号同步会使用异步FIFO完成,而单bit的信号同步,又是时钟无缝切换电路以及异步FIFO电路的设计基础,这里先介绍单bit信号同步处理。

     clka域下的信号signal_a,向异步的clkb域传递时,会产生亚稳态问题。所有的亚稳态,归根结底就是setup/hold时间不满足导致。在同一个时钟域下的信号,综合以及布线工具可以在data路径或者clock路径上插入buffer使得每一个DFF的setup/hold时间都满足;但是当signal_a在clkb域下使用时,由于clka与clkb异步,它们的相位关系不确定,那么在clkb的时钟沿到来时,无法确定signal_a此时是否处于稳定无变化状态,也即setup/hold时间无法确定,从而产生亚稳态。这种异步信号在前后端流程里面是无法做时序分析的,也就是静态时序分析里常说的false_path。

      消除亚稳态,就是采用多级DFF来采样来自另一个时钟域的信号,级数越多,同步过来的信号越稳定。对于频率很高的设计,建议至少用三级DFF,而两级DFF同步则是所有异步信号处理的最基本要求。

       单bit的信号跨时钟域同步,又分成电平信号同步以及脉冲信号同步。电平信号,就是说clka下的信号signal_a在clkb看来,是一个很宽的信号,会保持多个clkb的时钟周期,一定能被clkb采到。这种情况,只需要使用clkb用至少两级DFF连续抓signal_a即可,特别需要强调的是,此时signal_a必须是clka下的寄存器信号,如果signal_a是clka下的组合逻辑信号,一定要先在clka下用DFF抓一拍,再使用两级DFF向clkb传递。这是因为clka下的组合逻辑信号会有毛刺,在clka下使用时会由setup/hold时间保证毛刺不会被clka采到,但由于异步相位不确定,组合逻辑的毛刺却极有可能被clkb采到。电平信号的同步处理,一般用于知道确定的时钟频率大小关系或者极慢时钟下的信号向极快时钟域传递时使用,简单处理如下:

always @ (posedge clkb or negedge rst_n)
begin
    if (!rst_n) begin
       levl_b_d1 <= #DLY 1'b0;
       levl_b_d2 <= #DLY 1'b0;
       levl_b_d3 <= #DLY 1'b0;
    end
    else begin
       levl_b_d1 <= #DLY levl_a_in;
       levl_b_d2 <= #DLY levl_b_d1;
       levl_b_d3 <= #DLY levl_b_d2;
    end
end

assign puls_b_pos = levl_b_d2 & (~levl_b_d3);
assign puls_b_neg = levl_b_d3 & (~levl_b_d2);
assign levl_b_out  = levl_b_d2;

上面三个输出分别是经过同步之后,clkb下可以使用的0变1脉冲信号,1变0脉冲信号以及电平信号。再次强调:levl_a_in必须是clka的DFF信号

下面是更常见的,clka下的脉冲信号,同步到clkb时钟域下,它对于clka与clkb的时钟频率关系没有任何限制,快到慢,慢到快都没问题。其主要原理就是先把脉冲信号在clka下展宽,变成电平信号,再向clkb传递,当确认clkb已经“看见”信号同步过去之后,再清掉clka下的电平信号。脉冲信号同步处理电路,有两个地方使用了上面的电平信号同步处理原则,请仔细揣摩原因。详细见下面的RTL,其中省略了信号定义声明:


module sync_pulse (
                  // input
                  rst_n             , // system reset
                  clka               , // clockA
                  clkb               , // clockB
                  puls_a_in       , // pulse input from clka
                  // output
                  puls_b_out     , // pulse output in clkb
                  levl_b_out        // level output in clkb
                  );

parameter         DLY      =  1   ; //

always @ (posedge clka or negedge rst_n)
begin
    if (rst_n == 1'b0)
        signal_a <= # DLY 1'b0 ;
    else if (puls_a_in)
        signal_a <= # DLY 1'b1 ;
    else if (signal_b1_a2)
        signal_a <= # DLY 1'b0 ;
    else ;
end

always @ (posedge clkb or negedge rst_n)
begin
    if (rst_n == 1'b0)
        signal_b <= # DLY 1'b0 ;
    else
        signal_b <= # DLY signal_a ;
end

always @ (posedge clkb or negedge rst_n)
begin
    if (rst_n == 1'b0) begin
        signal_b_b1 <= # DLY 1'b0 ;
        signal_b_b2 <= # DLY 1'b0 ;
    end
    else begin
        signal_b_b1 <= # DLY signal_b ;
        signal_b_b2 <= # DLY signal_b_b1 ;
    end
end

always @ (posedge clka or negedge rst_n)
begin
    if (rst_n == 1'b0) begin
        signal_b1_a1 <= # DLY 1'b0 ;
        signal_b1_a2 <= # DLY 1'b0 ;
    end
    else begin
        signal_b1_a1 <= # DLY signal_b_b1 ;
        signal_b1_a2 <= # DLY signal_b1_a1 ;
    end
end

assign puls_b_out = signal_b_b1 & (~signal_b_b2) ;
assign levl_b_out = signal_b_b1 ;

endmodule

下一篇讲时钟切换电路。

留下一个思考题:clka下的同一个寄存器信号signal_a,电平宽度对clkb而言足够长,如果同时调用两个相同的电平同步模块向clkb时钟传递,分别得到levl_b1和levl_b2,那么在clkb时钟域下看到的lev_b1和levl_b2信号是否一样?
这个问题是实际设计中一不小心就会犯错的,如果能够想明白正确回答这个问题,异步信号的理解就可以过关了。
作者: silencefpga    时间: 2016-6-15 21:36
本帖最后由 silencefpga 于 2016-6-15 23:14 编辑

基本赞成楼主的看法,不过两级同步器是建立在一个特定的条件上面的:假设clkb的 是周期为T,那么必须满足 第一级Tco + 第一级输出数据恢复稳定时间 + 第一级触发器输出到第二级触发器输入端的路径传输延时为Tnet + 第二级的Tsu < T 才可以避免亚稳态的发生,满足不了这个条件就是打N拍都是无用的。当然一般来讲,一拍不行,多大几拍,只要工具布线的时候按照设计者的想法: 尽可能缩短第一级触发器输出到第二级触发器输入端的路径传输延时为Tnet的方式去把多级寄存器都插在中间的话,是可以避免亚稳态的。
呵呵, 这就是我们常说的: 时序是设计出来的,时序也是约束出来的。

------------------------
IC / FPGA 逻辑开发:
1.千兆/万兆以太网MAC
2.OTN / SDH 接口设计
3.    PCIE/USB/STA
4.    H264视频处理算法
作者: haimo    时间: 2016-6-16 09:09
楼主讲的很好,谢谢。

思考题没理解,两个相同的电平同步模块syn_a,syn_b,输入端都接signal_a,syn_a输出levl_b1,syn_b输出levl_b2,但levl_b1和levl_b2会不一样?

期待时钟切换的讲解,尤其是异步时钟切换,信号clksw是clka时钟域的,初始值为0,工作中可以配置为1,clk_out=clksw?clk_a:clk_b,工作模块使用clk_out,如何使clk_out没有毛刺。
作者: 老阮    时间: 2016-6-16 09:26
回复 3# haimo


可能会出现不一样的情况。
这种情况发生在:第一级触发器输出亚稳态后,经过一段时间,最后得到的稳定电平可能是0,也可能是1,因此第二级触发器的输出可能不同。
作者: haimo    时间: 2016-6-16 09:44
回复 4# 老阮

这个和后端实现有关吧,如果是前仿,应该一样吧
作者: 老阮    时间: 2016-6-16 10:05
回复 5# haimo


   从硬件的角度理解,为啥要停留在仿真呢?
作者: yaya126    时间: 2016-6-16 10:07
思考题:
如果两个电平同步模块的输入时完全一样的,也就是说信号线等长,信号相位相同,那么我认为levl_b1和levl_b2一样,但是实际系统中有可能无法保证这个前提,那么levl_b1和levl2有可能差一个clkb的宽度。

一个关于亚稳态的基本问题:
在芯片内部,亚稳态的理解是“非0非1”,还是“非0即1”? 我的理解是“非0即1”, 异步采样一个跳变沿,即使setup/hold不满足,但结果也只是有可能采到0,也有可能采到1, 不会变成X在系统里传播。
作者: 杰克淡定    时间: 2016-6-16 11:30
本帖最后由 杰克淡定 于 2016-6-20 14:39 编辑

回复 5# haimo

4楼的理解是正确的。对于异步问题,RTL仿真是无法判断真伪的,仿真仅仅是模拟行为,仿真正确不能等价于实际电路正常。
你说的后端实现,其实也是无法保证的,原因在于signal_a去到sync_a与sync_b两个模块的第一级DFF都是false_path,它们的时序是无法约束的。signal_a走的是两条独立路径达到sync_a和sync_b的第一级DFF的D端,sync_a与sync_b第一级DFF的clkb在实际布线中也存在差异,再加上sync_a与sync_b的两个第一级DFF对于0/1判定也无法完全一致。当clkb的上升沿来临时,如果刚好在signal_a信号跳变附近,发生亚稳态问题,这两个同步电路第一级DFF对于signal_a是0还是1的判断理解会存在差异,从而导致多级同步之后得到的两个信号在clkb域下不一致。

因此,对于异步信号,不要使用两个同步电路同步后,分别给到clkb下的不同地方去做逻辑,这与signal_a不经过同步直接用在clkb下的多个地方做逻辑犯的错误后果是一样的!
作者: 杰克淡定    时间: 2016-6-16 11:45
回复 7# yaya126

verilog写出来的,是硬件电路,不能以软件思维来考虑,所谓的信号等长,相位一样,这些只存在于纯粹的仿真模拟中,实际芯片无法做到,即使同一个std cell在两颗芯片中表现都会存在差异。

另外,两个相同电路同步过去得到的两个信号,还不仅仅是宽度相差一个cycle这么简单,可能出现很多种情况,最可能的情况有宽度相差2个1个0个cycle,相位提前或者滞后一个cycle或者相位相同,以及上面宽度差异和相位差异的任意组合,如果clkb的频率很高在1GH级别,情况复杂度更难确定。
   
其实至于到底有多少种差异不用去深究,对于数字设计,我们需要的是确定的东西,要么0要么1,要么对要么错,所有存在不确定的设计,一定是错误的设计。
作者: yaya126    时间: 2016-6-16 13:20
回复 9# 杰克淡定
你所说的两个clkb,发生条件是第二个DFF才到第一个DFF的亚稳态,0/1继续不确定, 按照这个理论推导,不管多少级,也就是降低亚稳态传递发生的概率。 而不是确定0/1.

我的亚稳态问题想了解的是:
如果芯片内部非0即1,那用一级DFF同步即可,何必两级或三级DFF。 如果有大神能介绍亚稳态,请从analog或者器件的角度来解释,从digital的角度,我觉得一级即可。
作者: 杰克淡定    时间: 2016-6-16 14:09
回复 10# yaya126

我们这里总共讨论了两个不同的问题,你搞混淆了。
1、消除亚稳态,需要多少级的问题。
两级是最基本要求,如果是高频率设计,三级以上,我只能说每增加一级,不稳定概率是大幅降低。至于你说从数字角度讲因为非0即1的问题所以只需要一级,是没有理解到亚稳态的电路表现状态。第一级DFF的输出,最终的确会停留在确定的0或者1状态,但是这里存在一个“需要多长时间后”才能稳定在0或者1的问题。实际电路里的信号0到1或者1到0的变化,绝对不是你从仿真波形上看到的垂直陡峭变化的方波,它是一个缓慢渐变的过程。存在亚稳态问题的电路,相对正常信号而言,最直接的影响就是它的渐变过程更加缓慢,达到稳定需要的时间更长。如果只使用一级DFF,显然它的输出信号稳定有效宽度比较窄,跟clkb下的其他信号做组合逻辑会把这个稳定有效的窄脉宽信号影响延伸下去,这就导致亚稳态传播。如果增加一级DFF去抓,虽然前一级有效宽度窄,但如果窄脉宽也能稳定地被第二级DFF抓到,第二级DFF的输出信号显然就能达到正常信号水平了,即使第二级DFF还是无法稳定抓到,至少第二级DFF的输出信号会相对第一级改善很多,这就是每增加一级大幅降低不稳定概率的原因。


2、clka下的同一个信号,不能分别使用两个同步器同步后拿到clkb中不同地方使用,即使调用的是一模一样的RTL同步模块。原因见上面几楼的分析。
作者: haimo    时间: 2016-6-16 14:47
回复 8# 杰克淡定

谢谢您,之前从没想过这个问题。
期待时钟切换的讲解,尤其是异步时钟切换。
例如:信号clksw是clka时钟域的,初始值为0,工作中可以配置为1,clk_out=clksw?clk_a:clk_b,工作模块使用clk_out,如何使clk_out没有毛刺。
作者: wdhruien    时间: 2016-6-18 09:19
学习了
作者: 杰克淡定    时间: 2016-6-20 14:46
回复 2# silencefpga

关于你说的这个“如果无法满足这个条件,打N拍也没用”的理解是有误区的,详见11楼的分析。
作者: yaya126    时间: 2016-6-20 17:27
回复 14# 杰克淡定

如果满足不了他说的那个条件,时钟本身就不能跑那么快,这已经不是跨时钟域的问题了。
他讲的理念很对,时序是设计和约束出来的,2拍或者N拍sync DFF, 在物理上本来就应该摆在一起来减少propgation delay, 或者干脆调用预先设计好的sync_cell。
作者: 杰克淡定    时间: 2016-6-20 17:55
回复 15# yaya126

“不过两级同步器是建立在一个特定的条件上面的:假设clkb的 是周期为T,那么必须满足 第一级Tco + 第一级输出数据恢复稳定时间 + 第一级触发器输出到第二级触发器输入端的路径传输延时为Tnet + 第二级的Tsu < T 才可以避免亚稳态的发生,满足不了这个条件就是打N拍都是无用的”
    他的解释,对于两级DFF可以消除亚稳态必须满足的条件很正确。但是不能得出,当这个条件无法满足时,即使使用N拍DFF都无法消除亚稳态这样的结论。按照这个理论,如果第二级DFF还无法稳定,我们后面加再多DFF也没有意义。实际上,多级DFF的存在意义就是为了解决第二级DFF还是无法稳定这种情况。
作者: xinhaoqi    时间: 2016-6-29 16:22
学习了,讲得很透彻
作者: xg7zyj    时间: 2016-6-29 18:42
学习了!一直对亚稳态的实际电路电压变化比较模糊,楼主在11楼讲的很清楚。
作者: yuxuandl    时间: 2016-7-4 15:35
看了大神的帖子,受益
作者: lk24203    时间: 2016-8-29 11:20
涨( ̄︶ ̄)↗知识啦~
作者: 风中飞    时间: 2016-9-4 17:49
学习了,谢谢楼主
作者: 没有关系    时间: 2016-9-8 08:57
mark
好东西
作者: jiejie1224    时间: 2016-9-8 09:12
很有用,谢谢楼主~
作者: yaphetszyj    时间: 2016-9-8 21:37
确实是比较重要的基础知识,今天在这里学习到了!感谢楼主
作者: komatsu001    时间: 2016-9-9 10:22
感谢楼主!遇到一道类似的面试题,找错误 ,没答上来。
作者: yyyll615917    时间: 2016-9-9 10:51
不明白作者这里两句话的意思,《单bit跨时钟域同步》
assign puls_b_pos = levl_b_d2 & (~levl_b_d3);
assign puls_b_neg = levl_b_d3 & (~levl_b_d2);
assign levl_b_out&#160;&#160;= levl_b_d2;
--puls_b_pos 、puls_b_neg这两个信号是做什么的,也没见用到?还有既然选择三级DFF,为何最后输出的是第二级DFF的结果?
作者: 杰克淡定    时间: 2016-9-9 15:55
回复 26# yyyll615917


   额,后级电路你需要用电平信号那就用_d2,后级电路你需要用沿变化信号就用_neg或_pos,自己灵活选择嘛。
作者: yaphetszyj    时间: 2016-9-9 16:37
楼主,问你个问题,从慢时钟域到快时钟域,需要同步的信号宽度大于快时钟域的周期,就会被采到两次,这个怎么解决?
作者: 杰克淡定    时间: 2016-9-9 16:44
回复 28# yaphetszyj


   同步到快时钟域后,想要使用多周期信号就用*_d2,想要用单周期信号就用*_pos或*_neg
作者: 月华如练    时间: 2016-9-11 11:14
请教一个问题,既然第一级DFF输出的0/1是不确定的,那么就算第二级采到稳定的信号,结果也可能跟我想要的结果不一样呀,也就是说clk_a下输入的信号本来是0,第二级DFF采到的是1.
作者: 杰克淡定    时间: 2016-9-12 09:09
回复 30# 月华如练

异步电平信号同步到另一个时钟域,只能保证信号最终一定能同步过去,对于哪个周期才能稳定同步过去则是不确定的,这是基本常识。如果说信号同步过去的时间快慢会影响你的电路功能,说明你这里应该使用同步设计,而不是异步设计。
作者: 小红帽奶爸    时间: 2016-9-13 10:50
回复 31# 杰克淡定

我觉得30楼问的是在同步过程中,对亚稳态的值进行决断的时候可能会产生一个错误的错误的值,即clka中输入的是0,而经过同步电路后,在clkb最终得到了1,这个应该也是有可能的,要怎么才能尽量减少这种亚稳态决断的错误?
作者: 杰克淡定    时间: 2016-9-13 12:37
回复 32# 小红帽奶爸


  单bit信号同步,亚稳态会发生在输入信号0变1或者1变0的时刻,同步过去后的信号也得到的是0到1或者1到0的电平变化,只是变化时间点的早晚问题。早晚问题不应该影响功能,不再赘述。
作者: 我没逗你玩儿    时间: 2016-9-23 21:00
多谢分享~~受益匪浅!!!
作者: hg7230688    时间: 2016-9-25 18:35
来学习学习。
作者: xiangpeis    时间: 2016-9-26 16:42
回复 32# 小红帽奶爸

我认为这是不可能的,如果在clka中是0,那同步到clkb中也一定是0。

只有当clka中的signal在从0往1跳变时,才可能被clkb同步后得出0/1的情况。
如果clkb同步的结果是0,那下一拍的同步结果一定是1;如果当前同步结果是1,下一拍的同步结果也一定是1,只是一个时间早晚的问题。

亚稳态也只是发生在source signal变化的瞬间被destination clock domain采样了,此时setup或者hold不满足,于是出现不确定的值。
作者: 我没逗你玩儿    时间: 2016-9-27 19:42
请问,对于最后的assign赋值,为啥不用assign levl_b_out = signal_b_b2;而用的signal_b_b1呢?
作者: 杰克淡定    时间: 2016-9-27 20:45
回复 37# 我没逗你玩儿


   _b1是打过两拍的,基本可用。_b2是打过三拍的,当然更加保险。 这样写的意思是说:如果你的设计不需要用到同步过去的_puls信号,而且认为打两拍已经足够,_b2这个寄存器就可以节省掉不需要了。
作者: 我没逗你玩儿    时间: 2016-9-27 23:12
回复 38# 杰克淡定


   谢谢您~~
作者: lllggg000111    时间: 2016-9-28 09:04
前两天看接到华为面试,电话里问我单bit跨时钟域设计,当时一下子没回答上来
作者: ilovinit    时间: 2016-9-28 16:50
先赞后看,mark占位~
作者: 洋大侠00    时间: 2016-9-30 13:47
回复 1# 杰克淡定


   大牛,你好,想问一下简单的单bit可以打两拍降低亚稳态,那么多bit数据可以打两拍降低亚稳态吗?
作者: 杰克淡定    时间: 2016-9-30 15:19
回复 42# 洋大侠00


   多bit直接抓,不仅仅是亚稳态的问题,而是会出现非期望的值。比如,两bit,00向11变化时,出现的可能是00-01-11或者00-10-11等,中间的01和10是错误值而不仅仅是亚稳态的问题。
作者: bdzcf    时间: 2016-10-14 17:04
学习了,最近在做FIFO,楼主详细的讲解给了我很大的启发
作者: xinpan    时间: 2016-10-30 14:30
回复 32# 小红帽奶爸



   
我觉得30楼问的是在同步过程中,对亚稳态的值进行决断的时候可能会产生一个错误的错误的值,即clka中输入的是0,而经过同步电路后,在clkb最终得到了1,这个应该也是有可能的,要怎么才能尽量减少这种亚稳态决断的错误?



FF对输入采样,在输入不跳变的情况下,输出就等于输入,不存在采样错误。这应该很好懂。

我觉得你真正想问的是,会不会一个0/1 或者1/0 signal_a 信号被同步成 1/0 或者0/1.
这是有可能的,这就是Failure。signal_a在第一级FF1的电平边沿跳变,造成setup/hold violation,所以FF1_Q就出现metastability, 但是它的值还是要回归到1或者0,这就有可能和实际想要的signal_a的值不一样。
假设signal_a 0/1, FF1_Q 的结果是metastability → 0, 然后下一个clk,FF2采样这个0,也输出了0;

到这里,就出现一个分水岭,signal_a到底有多长,假如它足够长,那么第二个clk的时候,它就被FF1正常采样,然后第三个clk被FF2正常采样,实际的level_b 输出也就只有时间早晚的问题。  

再一个就是上述的 两级FF 不是100% metastability free, 第二级的FF 还是会因为各种原因有setup/hold violation. 减少metastability就只能继续增加FF的级数。
作者: ericxgj    时间: 2016-11-3 07:49
写的不错  楼主的时钟切换思路与我的项目中基本一致  呵呵
作者: lxc806705    时间: 2016-11-4 11:45
楼主你这异步复位的代码风格,我不太赞同。
在我看来,xilinx提倡的使用同步复位并且尽量避免使用无谓的复位更适合。
作者: lxc806705    时间: 2016-11-4 11:49
另外关于异步信号的同步处理,我的通用做法是这样:
单bit,使用两级ASYNC_REG(这是xilinx的用法,我也只熟悉xilinx);
多bit,如果速率低仍然可以使用ASYNC_REG,速率高我一半使用分布式RAM的FIFO来完成,这样处理
时序上是比较稳妥的。

当然我这里都是说的实际设计中的一些用法,如果纯粹将verilog设计则不见得适用。
作者: qlqc    时间: 2016-11-4 15:12
参考了
作者: abiggg    时间: 2016-11-5 11:08
好货,谢谢分享
作者: 冲出藩篱    时间: 2016-11-6 16:19
第二种 通过握手跨时钟的方案,是有逻辑上的漏洞的。
建议楼主再仔细思考一下
作者: 杰克淡定    时间: 2016-11-7 09:13
回复 51# 冲出藩篱

什么漏洞?请指出
作者: 杰克淡定    时间: 2016-11-7 09:18
回复 47# lxc806705

整个设计中,除了全局异步复位rst_n,何来异步复位风格?你如果说全局异步复位信号都不应该使用,那我们就没什么好谈的了,哈哈!
作者: 冲出藩篱    时间: 2016-11-7 10:02
本帖最后由 冲出藩篱 于 2016-11-7 12:19 编辑

回复 52# 杰克淡定


   我的个人理解,不一定对。
   单比特跨时钟域,由快到慢,握手的时间会造成,传输的bit信息的丢失。
作者: 杰克淡定    时间: 2016-11-7 12:23


   
回复  杰克淡定


   我的个人理解,不一定对。
   单比特跨时钟域,由快到慢,握手的时间会造成,传输 ...
冲出藩篱 发表于 2016-11-7 10:02




   任何电路使用都有它的前提条件的,这不是漏洞,是电路自身的限制而已。同步是需要花时间的,clka的脉冲向clkb同步,如果当前同步过程正在进行,clka又来了一个脉冲,那么后来的这个脉冲信息是无法同步到clkb,而是被遗漏的。使用电路的人应该清楚自己的电路工作场景并合理选用哪种电路。   这个就跟异步FIFO同步类似,FIFO的限制条件是空了不能读,满了不能写。现在就相当于clka写满了FIFO,此时你却不管它已经满了,一定再硬写一个数进去,那FIFO只能写爆了。
作者: 冲出藩篱    时间: 2016-11-7 14:51
回复 55# 杰克淡定

所以单bit跨时钟域,有以下几种情况:   1. 快到慢, 快慢时钟同源。
   2.  快到慢,   快慢时钟不同源。
    3.  慢到快,   
快慢时钟同源。

4.  慢到快,   
快慢时钟不同源。
    5. 不清楚两个时钟域的快慢,两个时钟同源/不同源。
根据每种情况,考虑到实际信号和时钟的特点,采取不同的处理方式。

纯粹交流,希望能够把单bit跨时钟域的问题,考虑完备。
作者: b10107009    时间: 2016-11-7 18:11
謝謝大大分享
作者: 杰克淡定    时间: 2016-11-7 19:12
回复 56# 冲出藩篱

请仔细看两种代码前面的文字部分,都已经说明了代码适用场景。另外,同源同步时钟处理简单,不在本篇考虑之列,帖子专门针对的是两个异步时钟域之间的信号传递。
作者: 冲出藩篱    时间: 2016-11-7 19:57
回复 58# 杰克淡定

  用握手的电路来对应下面这段话,是不严谨的。

“clka下的脉冲信号,同步到clkb时钟域下,它对于clka与clkb的时钟频率关系没有任何限制,快到慢,慢到快都没问题。其主要原理就是先把脉冲信号在clka下展宽,变成电平信号,再向clkb传递,当确认clkb已经“看见”信号同步过去之后,再清掉clka下的电平信号”。



换句话说,我200M的信号:10000100 跨到 100M直接展宽两拍打拍同步过去没问题,但是用了握手之后,我就会1bit的信息的丢失。

所以应用握手电路跨时钟域要看实际的场景,而并非对于“clka与clkb的时钟频率关系没有任何限制,快到慢,慢到快都没问题。”。


纯粹技术讨论,做技术的。
作者: lei619lei    时间: 2016-11-7 21:33
不错不错
作者: yunfei2012    时间: 2016-11-7 21:34
学习了,不错
作者: 腾钰    时间: 2016-12-15 17:59
请教楼主关于单bit跨时钟域传输的问题:
   慢时钟域clk_a向快时钟域clk_b同步信号signal_a,当signal_a在clk_b上升沿附近由0变1时,不满足setup/hold time要求,所以FF1采样不确定的值给FF1_Q,即FF1进入亚稳态。经过亚稳态时间之后,FF1_Q由不定值变为1或0。此时FF2可能就会采样一个稳定的1或者0输出。与此同时FF1也会采样一个新值给FF1_Q。这个值应该才是我们真正想要的值,而不是FF2_Q。之所以采用双锁存器只是为了降低亚稳态发生的概率,不要让一个不稳定的信号进入clk_b域。但是问题是:如果采用2个一样的同步器,FF1_Q由亚稳态变为1或者0是可能不一样,这也导致FF2_Q不一样,但是下一个时钟,FF1采样的signal_a已经稳定了,这个值才是我们真正需要的值,经过FF2两个同步器的输出不就是一样了。这样理解对吗?请LZ解释一下,谢谢。
作者: 杰克淡定    时间: 2016-12-15 19:30
回复 62# 腾钰


   没有看明白你题的问题。单bit同步强调的是,不要把一个单bit信号,通过两条路径向clkb去同步,这样在clkb下看到的两个信号signal_x与signal_y是不一样的。如下图: ( , 下载次数: 166 )
作者: 腾钰    时间: 2016-12-15 20:27
回复 63# 杰克淡定

我明白你的意思,signal_a同步过去,signal_x和signal_y可能会不同,这是没问题的。但是signal_x和signal_y并不是我们需要的值,下一个时钟的signal_x和signal_y才是我们需要的值。比如signal_a从0变1,同步过去的signal_x可能会是0,这样的话,同步过去的这个值就是错误的,但是等下一个FF1采样的时候signal_a已经稳定为1了,这样采样就没有问题,输出signal_x也就是1.lZ方便加QQ交流一下吗?最近正在学习跨时钟域传输。我的QQ:2579576028
作者: 腾钰    时间: 2016-12-15 20:27
回复 63# 杰克淡定

我明白你的意思,signal_a同步过去,signal_x和signal_y可能会不同,这是没问题的。但是signal_x和signal_y并不是我们需要的值,下一个时钟的signal_x和signal_y才是我们需要的值。比如signal_a从0变1,同步过去的signal_x可能会是0,这样的话,同步过去的这个值就是错误的,但是等下一个FF1采样的时候signal_a已经稳定为1了,这样采样就没有问题,输出signal_x也就是1.lZ方便加QQ交流一下吗?最近正在学习跨时钟域传输。我的QQ:2579576028
作者: xiaogou1233    时间: 2016-12-27 13:17
好东西,学习了,但是有一个else少了东西吧
作者: mlqe    时间: 2016-12-28 11:03
很好的东西啊 前来学习学习  补充一下自己咯
作者: novman    时间: 2017-1-6 12:19
干货,值得看看。
作者: anytao    时间: 2017-1-9 11:10
都很专业的大神
作者: 飘渺仙    时间: 2017-1-11 10:20
关于楼主的思考题:其实同步后的两个信号未必是一样的,可能会有一个或多个时钟周期的差别。
其实这样同样引入了跨时钟域的另一个问题:信号汇聚。
作者: 天易飞飏    时间: 2017-2-21 18:30
码一下,留着慢慢看
作者: slsy    时间: 2017-2-23 21:50


   
回复  yaya126

我们这里总共讨论了两个不同的问题,你搞混淆了。
1、消除亚稳态,需要多少级的问题。
...
杰克淡定 发表于 2016-6-16 14:09



“如果只使用一级DFF,显然它的输出信号稳定有效宽度比较窄,跟clkb下的其他信号做组合逻辑会把这个稳定有效的窄脉宽信号影响延伸下去,这就导致亚稳态传播。如果增加一级DFF去抓,虽然前一级有效宽度窄,但如果窄脉宽也能稳定地被第二级DFF抓到,第二级DFF的输出信号显然就能达到正常信号水平了,即使第二级DFF还是无法稳定抓到,至少第二级DFF的输出信号会相对第一级改善很多,这就是每增加一级大幅降低不稳定概率的原因。”
大神,这段话还不是太理解,为什么DFF1信号稳定有效宽度比较窄,可以画个图讲解一下吗,非常感谢!
作者: 口口JM    时间: 2017-3-2 14:06
回复 1# 杰克淡定


   楼主你好,我想把你这篇文章转载到自己博客上面去用以以后复习和共别人分享,可以吗?
作者: 杰克淡定    时间: 2017-3-2 19:12
回复 73# 口口JM


   可以,转载注明出处即可
作者: 口口JM    时间: 2017-3-3 08:54
回复 74# 杰克淡定


   好的,谢谢。
作者: jerryyanngyuq    时间: 2017-3-3 15:34
从数字的角度来说,其实也不完全是非0即1的
作者: 547420883    时间: 2017-4-13 21:24
一直不太理解,异步电路的同步处理,中间丢的数据怎么办?
两个时钟频率相差的不是太多的话,一定会发生信号丢失吧!
如果是极快,极慢的情况可以看成快时钟采到的是慢时钟的电平信号。
作者: 三石哥哥    时间: 2017-4-23 14:12
好东西~mark~
作者: 南宫恨    时间: 2017-4-25 09:10
一般脉冲同步基本上是在输入脉冲时钟域内建立一个信号,在脉冲时刻就取反,然后同步到工作时钟域,最后经异或后得到工作时钟域的脉冲,典型应用是apb信号的同步,因为apb在收到ready才会开启下一次transfer,这样不会在同步过程中开启下一次transfer
作者: 三石哥哥    时间: 2017-4-27 09:13
刚刚入门,听大神讲讲课
作者: MKNIU    时间: 2017-5-5 20:59
感谢大神上课。时钟切换在哪里开贴呢???
作者: capcomwf    时间: 2017-5-23 17:24


   
“如果只使用一级DFF,显然它的输出信号稳定有效宽度比较窄,跟clkb下的其他信号做组合逻辑会把这个稳定 ...
slsy 发表于 2017-2-23 21:50



我来说下我的理解,因为亚稳态的出现,在这个区域的DFF_1的输出是一个亚稳态输出是不稳定不有效的,而用工作在CLK2的DFF_2再抓一拍,不管这个输出是否正确,抓到稳定的输出的概率会增大很多,虽然这个输出依然无法确认是否正确,但是至少是一个稳定的输出了
作者: xiangchengsun    时间: 2017-6-28 18:06
那怎样能既实现跨时钟域同步,又保证同步后的数据是正确的呢
作者: Burt    时间: 2017-8-28 10:20
感谢楼主大神的精彩讲解,获益很多。但是后面的程序没太看懂
在clka下,signal_a得等signal_b1_a2才能确定高电平宽度;
在clka下,signal_b1_a2是signal_b_b1在clka下被踩后延迟2个周期;
而signal_b_b1是在clkb下由signal_b延迟一个周期,然而signal_b又是在clkb下由signal_a得到的,又回去了;怎么回事呀???刚刚接触FPGA,看不懂您这个做法,求解答,谢谢了
作者: 杰克淡定    时间: 2017-8-28 13:49
回复 84# Burt

脉冲信号跨时钟域同步,用文字描述这段逻辑实现就是:在clka下将脉冲信号延长,直到确认clkb看到了延长后的信号,才撤销。理解了这段文字再去看看RTL设计?
作者: 寒烟问月    时间: 2017-9-1 12:08
回复 1# 杰克淡定

学习了,大赞!
作者: sureking    时间: 2017-9-1 17:41
技术人员要学习表达能力,仔细学习了本帖,中间有几楼相互都没get到对方的点,尤其是关于“第2个DFF没有抓到或者抓错,以后都错”的讨论,看的我有点着急……感谢楼主和各层主的讨论,受益匪浅。
作者: Chash    时间: 2017-10-24 15:35
哈哈,这帖子让我获益匪浅,联发科去年的笔试题就是考这个,一模一样,而且分别考察了这两种单比特跨时钟域传输。其实第二种情况应该叫握手反馈机制吧。看来基础很重要,要抓紧在学校的时间好好学习了。
作者: majingjaor    时间: 2017-10-25 17:52
感谢!
作者: yhmwjmm    时间: 2017-11-6 20:31
嗯,思路基本都差不多
作者: ljxrsly    时间: 2017-11-23 10:44
#DLY这个能综合吗?不能吧?
作者: xiaogou1233    时间: 2017-11-28 14:11
隔一段时间再来看看学习
作者: 志静    时间: 2018-4-25 16:17
谢谢分享
作者: jackstrive    时间: 2018-5-16 13:46
Thanks
作者: micdot    时间: 2018-6-4 11:31
感谢楼主的原创分享,谢谢!
作者: bingo426    时间: 2018-6-10 20:59
楼主,最后一个进程没有看懂,是用A的时钟来采集B时钟域的信号么?小白不理解这个进程用意,希望大神指点
always @ (posedge clka or negedge rst_n)
begin
    if (rst_n == 1'b0) begin
        signal_b1_a1 <= # DLY 1'b0 ;
        signal_b1_a2 <= # DLY 1'b0 ;
    end
    else begin
        signal_b1_a1 <= # DLY signal_b_b1 ;
        signal_b1_a2 <= # DLY signal_b1_a1 ;
    end
end
作者: LegendNing    时间: 2018-6-12 21:51
thanksforsharing
作者: shenstone    时间: 2018-7-9 19:40
学习了谢谢大佬
作者: 何妨轻佻    时间: 2018-7-17 21:48
楼主你好,我有一个疑惑,单bit的电平信号的跨时钟域同步,用两级DFF连续抓signal_a。可是代码综合出来的电路只有1个DFF。我刚学.....,希望大神指点指点
作者: 杰克淡定    时间: 2018-8-31 16:22
回复 99# 何妨轻佻


   要用接龙形式串行去抓,你是用两个DFF抓了同一个信号吧?




欢迎光临 EETOP 创芯网论坛 (原名:电子顶级开发网) (https://bbs.eetop.cn/) Powered by Discuz! X3.5