(数字ic)CDC跨时钟域可能出现的问题及解决办法总结

CDC跨时钟域可能出现的问题及解决办法总结

1、CDC基本概念

时钟域(Clock Domain):时钟域为由单个时钟或具有恒定相位关系的时钟驱动的设计部分。换句话说,时钟域就是时钟信号的势力范围
且一个时钟域中只能存在一个时钟信号,而一个时钟信号最多可以对应两个时钟域。

多个时钟来自不同的来源,而由这些时钟驱动的逻辑单元部分为时钟域,这些异步时钟域之间的接口信号称为时钟域交叉(CDC)路径。

如图一,divCLK是由CLK分频得到的,所以divCLK和CLK为同步时钟,也是属于同一个时钟域的。
在这里插入图片描述

如图二,DA信号被认为是一个异步信号进入时钟领域,即CLKA和CLKB之间不存在恒定的相位和时间关系。
在这里插入图片描述

2、SOC中有哪些跨时钟域的问题?

problem1:亚稳态
problem2:快时钟域到慢时钟域数据保持的问题
problem3:重新聚合问题(Reconvergence of Synchronized Signals)(数据恢复问题)
problem4:多比特数据同步问题
problem5:异步复位 同步释放

solution1
(比如从AHB总线传输信号到APB总线,由于各个接口的时钟频率不同,因此可能会存在跨时钟域的问题)
产生原因:
在同步系统中,输入信号总是系统时钟同步,能够达到寄存器的时序要求,所以亚稳态不会发生。亚稳态问题通常发生在一些跨时钟域信号传输以及异步信号采集上。
1)在跨时钟域信号传输时,由于源寄存器时钟和目的寄存器时钟相移未知,所以源寄存器数据发出数据,数据可能在任何时间到达异步时钟域的目的寄存器,所以无法保证满足目的寄存器Tsu和Th的要求;
2)在异步信号采集中,由于异步信号可以在任意时间点到达目的寄存器,所以也无法保证满足目的寄存器Tsu和Th的要求;
在这里插入图片描述
在这里插入图片描述
solution2
将快时钟域的数据延迟相应的拍数(快时钟域比慢时钟域快的频率),如problem2图中,clkA是clkB的2倍,那么就要将数据A扩展成两个周期,即加入一个寄存器。

在这里插入图片描述

solution3
产生原因:
如果多个信号从一个时钟域进入另外一个时钟域,然后这些信号在目标时钟域中又聚合到一起,那么就有可能因为信号 的重新聚合导致电路功能上的异常。如图,一旦同步完成,同步器之外的结构仍然很重要。设计必须确保同步信号不重新聚合(若聚合会产生功能错误),后同步逻辑可能会导致DB信号出现Glitch。原本IN1和IN2转换时钟域后,期望得到的值是2’b00和2’b11,但由于IN1和IN2到达CLKB时钟域的时间有差异,实际得到的值是2’b00、2’b10和2’b11,最终导致后继电路功能出现问题。
在这里插入图片描述
在这里插入图片描述

信号X和信号Y进行跨时钟域传输两者同时从0变1,由于delay A和delayB的不同,可能在目的时钟域的第一个寄存器采样X为1,采样Y为0,第二个周期时,第一个寄存器采样X为1,Y为1,那么打两拍之后,X比Y提前一个周期为1的状态就会一直传递下去(如图),但实际上在原时钟域X和Y是同时从0到1翻转的。所以在跨时钟域传输多bit数据时,一次我们只允许数据的1bit发生翻转。不允许多bit发生翻转

solution4
Handshake:(MUX同步)即源时钟域发出一个1bit的请求信号(req),然后经过同步化处理后,将源时钟域的信号传输至目的时钟域,然后目的时钟域接受到数据后,反馈出一个完成信号(res)。多bit数据同步仅将一个信号a_en做两级同步,使得输出的b_en作为使能信号,若为1,才将多比特数据d[0]-d[7]传输过去,若为0,就不传输,这样就不用每一个比特都加两级触发器了。
在这里插入图片描述

FIFO:适用于大数量的多比特数据传输
在这里插入图片描述

solution5
异步复位同步释放优缺点:
同步复位:当时钟上升沿检测到复位信号,执行复位操作(有效的时钟沿是前提)。always @ ( posedge clk );
优点:
a、有利于仿真器的仿真;
b、可以使所设计的系统成为 100% 的同步时序电路,有利于时序分析,而且可综合出较高的 Fmax;
c、由于只在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的复位毛刺。
缺点:
a、复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑诸如 clk skew 、组合逻辑路径延时 、复位延时等因素(所以复位信号有时需要脉冲展宽,用以保证时钟有效期间有足够的复位宽度);
b、由于大多数的逻辑器件的目标库内的 DFF 都只有异步复位端口,所以,倘若采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样就会一方面额外增加FPGA内部的逻辑资源,另一方面也增加了相应的组合逻辑门时延。
异步复位:它是指无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。always @ ( posedge clk or negedge rst_n );
优点:
a、大多数目标器件库的 DFF 都有异步复位端口,那么该触发器的复位端口就不需要额外的组合逻辑,这样就可以节省资源;
b、设计相对简单;
c、异步复位信号识别方便(电路在任何情况下都能复位而不管是否有时钟出现)。
缺点:
a、最大的问题在于它属于异步逻辑,问题出现在复位释放时,而不是有效时,如果复位释放接近时钟有效沿,则触发器的输出可能进入亚稳态(此时 clk 检测到的 rst_n 的状态就会是一个亚稳态,即是0是1是不确定的),从而导致复位失败。参考CDC详解问题五。
b、可能因为噪声或者毛刺造成虚假复位信号(比如以前的游戏机玩到一半突然复位)(注意:时钟端口、清零和置位端口对毛刺信号十分敏感,任何一点毛刺都可能会使系统出错,因此判断逻辑电路中是否存在冒险以及如何避免冒险是设计人员必须要考虑的问题);
c、静态定时分析比较困难。
d、对于 DFT (Design For Test可测性设计)设计,如果复位信号不是直接来自于 I/O 引脚,在 DFT 扫描和测试时,复位信号必须被禁止,因此需要额外的同步电路。
总结:推荐使用异步复位、同步释放的方式,并且复位信号为低电平有效。
电路图:
在这里插入图片描述

1)电路解释:是指复位信号到来的有效与否与 clk 无关,而且复位信号的撤除也与 clk 无关,但是复位信号的撤除是在下一个 clk 来到后才起的作用。
2)电路目的:为了防止复位信号撤除时,可能产生的亚稳态。
3)电路详解:异步复位:复位信号 rst_sync_n 由高拉低时实现异步复位。同步释放:这个是关键,即当复位信号 rst_async_n 撤除时(由低拉高),由于双缓冲电路(双寄存器)的作用,rst_sync_n 不会随着 rst_async_n 的撤除而撤除。假设 rst_async_n 撤除时发生在 clk 上升沿,如果不加此电路则可能发生亚稳态事件,但是加上此电路以后,假设第一级 D 触发器 clk 上升沿时 rst_async_n 正好撤除,(第一个DFF 此时是出于亚稳态的;假设此时识别到高电平;若是识别到低电平,则增加一个 Delay)则 DFF1 输出高电平,此时第二级触发器也会更新输出,但是输出值为前一级触发器 clk 来之前时的 Q1 输出状态,显然 Q1 之前为低电平,所以第二级触发器输出保持复位低电平,直到下一个 clk 来之后,才随着变为高电平,即同步释放。
代码:
在这里插入图片描述

module reset_gen ( output rst_sync_n, input clk, rst_async_n);
 reg        rst_s1, rst_s2;
 wire       rst_sync_n ;

always @ (posedge clk or negedge rst_async_n) begin
    if (!rst_async_n) begin   
        rst_s1 <= 1'b0;  
        rst_s2 <= 1'b0;  
    end  
    else begin  
        rst_s1 <= 1'b1;  
        rst_s2 <= rst_s1;  
    end  
end

assign rst_sync_n = rst_s2;  
 
endmodule