Skip to content

【必备基础——数字IC流程、专业术语】CDC跨时钟域处理及相应的时序约束【set_clock_groups】【set_max_delay】

  • Version
    • linhuangnan
    • 2024-03-07
    • FPGA原型验证
    • review

Info

  • 数字IC设计流程;
  • FPGA设计流程

多bit跨时钟域

(大疆2020数字芯片)下列关于多bit数据跨时钟域的处理思路,错误的有()

A. 发送方给出数据,接收方用本地时钟同步两拍再使用;

B. 发送方把数据写到异步fifo,接收方从异步fifo里读出;

C. 对于连续变化的信号,发送方转为格雷码发送,接收方收到后再转为二进制;

D. 发送方给出数据,发送方给出握手请求,接收方收到后回复,发送方撤销数据。

答案:A

解析:多bit跨时钟域不能简单使用打两拍,打拍后可能数据错乱;

Note

跨时钟域传输多比特信号(比如一个数据总线)不能简单依靠“打两拍”(在目标时钟域对输入信号进行两级触发器同步)的方法,主要因为存在以下难题:

位间偏斜(Bit Skew):当多个比特同时从一个时钟域传输到另一个时钟域时,由于走线延迟和布局差异,各个比特之间可能会存在时间上的偏移。这种情况下,即使每个比特都使用了两级同步触发器,也可能无法保证所有比特同时更改状态。这可能导致目标时钟域接收到部分更新的数值,造成数据错误。

亚稳态风险:单个比特还有一定几率从亚稳态恢复至稳定态,但多个比特同时进行同步时,整组信号从亚稳态恢复的概率会大大降低。即使某个比特成功同步,其他比特可能仍处于亚稳态,这会导致数据的不一致性。

数据一致性:对于多比特信号,重要的是保持数据总线上所有比特的一致性。任何一位的错误或延迟都可能导致错误的数据解释,从而影响系统的正确性。

因此,为了安全地在时钟域之间传输多比特数据,通常采用如下技术:

双向握手协议:通过请求和确认信号来确保数据稳定地传输到目标域。 异步FIFO:FIFO缓冲区能够在写入时钟域和读取时钟域之间提供一个可靠的界面,确保数据的完整性和顺序。

灰码编码:在时钟域之间传输时使用灰码编码可以确保连续的数值只改变一位,从而减小误差的可能性。

这些方法能够有效地管理多比特信号的跨时钟域传输问题,减少数据损坏和信号不一致的风险。

CDC(Clock Domain Conversion)

跨时钟域分单bit和多bit传输,其中:

1. 单bit(慢时钟域到快时钟域):用快时钟打两拍,直接采一拍大概率也是没问题的,两拍的主要目的是消除亚稳态;

其中:

(1)为了更长的平均无故障时间 MTBF( Mean Time Between Failures),需要配合一个 ASYNC_REG 的约束,把用作简单同步器的多个寄存器放入同一个 SLICE,以降低走线延时的不一致和不确定性。

(* ASYNC_REG = "TRUE" *) reg rst_reg_0;
(* ASYNC_REG = "TRUE" *) reg rst_reg_1;

(2)或者:直接在约束文件里进行约束

set_property ASYNC_REG TRUE [get_cells [list rst_reg_0 rst_reg_1]] 

Tip

ASYNC_REG = "TRUE" 是一种在FPGA设计中使用的特殊约束,用于指示工具链(如综合和布局布线工具),某些寄存器被用作异步信号的同步化。这意味着这些寄存器用来缓解由于时钟域之间的转换引起的亚稳态问题。将此约束应用于一组寄存器,告诉FPGA布局工具将它们放置在距离很近的物理位置上,通常是在相同的逻辑单元内,即一个SLICE。

一个SLICE是FPGA内的一个基本逻辑单元,它包含了几个可配置的逻辑块(比如LUTs,逻辑查找表)和寄存器(触发器)。把用作同步器的寄存器放在同一个SLICE内可以保证它们有相似的电气特性和最小化的走线延迟,这对于提高设计的可靠性和稳定性至关重要。

2. 单bit(快时钟域到慢时钟域)

握手(脉冲展宽)、异步FIFO、异步双口RAM;快时钟域的信号脉宽较窄,慢时钟域不一定能采到,可以通过握手机制让窄脉冲展宽,慢时钟域采集到信号后再“告诉”快时钟域已经采集到信号,确保能采集到;

Tip

握手(脉冲展宽)机制通常是在不同时钟域之间传输信号时使用的一种技术,尤其是当从一个快速时钟域向一个慢速时钟域传送单个比特信号时。以下是实现此机制的步骤:

脉冲产生与检测

在快时钟域中,当需要传送的事件发生时,会生成一个短暂的脉冲信号。 由于慢时钟域的周期更长,因此可能无法在一个时钟周期内检测到这个短暂的脉冲。

脉冲展宽

为了确保慢时钟域能够稳定地采集到这个信号,脉冲被"展宽"至少一个完整的慢时钟周期,从而形成一个足够宽的脉冲。 展宽可以通过在快时钟域中将信号通过一系列触发器(用于同步目的)来实现,或者通过设置标志位,在慢时钟域中维持直到确认信号已被接收。

确认与复位

慢时钟域采集到展宽后的信号,并产生一个确认信号,反馈给快时钟域,表明信号已经被成功采集。 确认信号也是一个经过同步处理的信号,确保它能被快时钟域正确识别。 快时钟域接收到确认信号后,清除或复位原始的传送请求,完成整个握手过程。 这种握手机制确保了即使在快慢时钟频率相差较大的情况下,也能可靠地传输信号。这个方法常用于避免由于时钟频率差异导致的数据丢失或亚稳态问题。

3. 多bit跨时钟域:

异步FIFO、异步双口RAM、握手、格雷码;

(1)使用异步FIFO的IP

实际上是用 FPGA 内部的 BRAM 来搭建,所有的控制逻辑都在 BRAM 内部,是推荐的 FIFO 实现方式。

时序约束简单,进行时序例外约束,只需要 set_clock_groups 将读写时钟约束为异步时钟组即可,简单高效。

set_property -asynchronous  -group [get_clocks write_clock] \
                            -group [get_clocks read_clock]

(2)自己写外部控制逻辑的FIFO

格雷码做异步 FIFO 的跨时钟域处理,计数器和读写控制逻辑在 BRAM 或者 RAM 的外部,除了代码的合理设计以外,还需要进行额外的时序例外约束,不能简单使用 set_clock_groups 约束异步时钟组,还需要考虑外部的读写逻辑的约束。

Xilinx建议这里设置set_max_delay来约束跨时钟域路径,约束的原则是:最大路径延时等于或者略小于目的时钟的一个周期。

写逻辑从cell1到cell2的约束中,cell2的驱动时钟周期为5,如下所示,读逻辑约束进行相应约束。

set_max_delay 5 from [get_cells cell1] to [get_cells cell2] datapath_only 

多bit中,强烈推荐使用异步FIFO的IP来实现