跨时钟域处理真的是个非常综合的话题,涉及到很多方式,多时钟域的处理对于设计工程师是个富有挑战的话题。CDC(Clock Domain Conversion)不仅涉及理论学习,还要求具备实践经验。只会书本上的知识点,而不去实践,很难彻底理解CDC方法,在面试中简单的几个问题就会露馅。
例如:系统有几个时钟?每个时钟频率和相位是什么关系?哪些模块涉及到跨时钟处理?单bit还是多bit?关键路径在哪里? 等等
这里对大家的要求是最严格的,不仅要学会CDC理论知识,还要涉及到项目中的实践,了解时序分析并实际做过时序约束和时序报告处理相关的工作,也是前端设计工程师最后的重要工作,综合。
一篇博客真的很难理清所有知识点,强烈建议大家多学习,不管是书本、博客还是实际代码,只要之前没涉及,都可以了解了解。平常也多温习CDC相关的知识点,多尝试实践,理解每种方法的实现过程,优缺点,以及最重要的一点,将理论用于实际项目,真正搞好一个跨时钟域处理的工作,这样在面试中肯定有话题可以讲。
下面这张图是我在笔记中找到的,里面涉及到的关键词,感兴趣的同学可以多去了解了解
先看实现方法:
慢时钟到快时钟,为了避免亚稳态,最常用的方法是两级D触发器,也就是常说的“打两拍”。其基本原理是,当第一个触发器处于亚稳态时,仍有一个时钟周期用来恢复亚稳态。
同步器示意图:
除了上述这种,利用两个触发器处理慢时钟到快时钟的亚稳态,有些时候,我们需要采样慢时钟的变沿跳变,这时候就利用三个触发器加上边沿检测电路,电路示意图如下:
边沿检测同步器:
两个触发器用于同步信号,逻辑门用于检测边沿。
再看Verilog代码:
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2022 All rights reserved
// -----------------------------------------------------------------------------
// Author : HFUT904 [email protected]
// File : syn_s2f.v
// Create : 2022-11-09 15:50:52
// Revise : 2022-11-09 15:50:52
// Editor : HFUT Integrated Circuit Design & Research Center
// Verdion: V1.0
// Description: CDC同步器 慢时钟到快时钟
// -----------------------------------------------------------------------------
module syn_s2f (
input clk , // Fast Clock
input rst_n , // Asynchronous reset active low
input din , // Signal to be synchronized
output dout , // After synchronization signal
output up_down // edge
);
reg [2:0 ] din_t ;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
din_t <= 3'b0;
end
else begin
din_t <= {din_t[1:0],din};
end
end
//edge
assign up_down = din_t[1] && (~din_t[2] ); //posedge
endmodule
注意:一般设计中使用两级触发器就可以满足时序,三级触发器则是可以避免绝大部分的亚稳态,但是不能消除亚稳态的产生。亚稳态只能降低发生概率,不能完全消除。
快时钟到慢时钟的单bit同步。分为三种情况:
(1)第一种,信号本身变化很慢,以至于快时钟域产生的信号可以被慢时钟采集到,这种称为电平信号。处理方法和同步器一样,采用两级触发器就ok。
(2)第二种,信号变化比慢时钟快,直接用慢时钟采样会漏掉,这种信号称为脉冲信号。处理方法是“在快时钟展宽,慢时钟同步打拍”
(3)第三种,信号兼顾电平信号和脉冲信号的特点,这时候需要用到握手协议。
这里考的比较多的就是第二种和第三种,第二种脉冲展宽也是用到了握手处理相关的方法。
握手处理这里就不介绍了,后面会单独出一篇博客,握手也是经常考的一个知识点,除了用在
先看实现思路
(1)在快时钟检查脉冲信号,检测成功输出高电平信号a,等待慢时钟反馈信号。
(2)慢时钟对信号a进行延迟打拍。
(3)慢时钟检测到信号a为高电平时,输出反馈信号给快时钟。
(4)快时钟接收到反馈信号,则拉低信号a。
ps:这里就是利用信号a,延迟打拍后重新反馈,类似握手处理。
再看Verilog代码:快时钟展宽,慢时钟延迟打拍:
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2022 All rights reserved
// -----------------------------------------------------------------------------
// Author : HFUT904 [email protected]
// File : syn_f2s.v
// Create : 2022-11-10 16:15:28
// Revise : 2022-11-10 16:15:28
// Editor : HFUT Integrated Circuit Design & Research Center
// Verdion: v1.0
// Description: CDC 单bit 快到慢 快时钟展宽,慢时钟延迟
// -----------------------------------------------------------------------------
module syn_f2s #(
parameter Pulse = 1'b0
)(
input rst_n , // Asynchronous reset active low
input clk_f , // Fast clock
input ple_f , // Fast clock pulse
input clk_s , // Slow clock
output ple_s // Slow clock pulse
);
wire clr_n ;
reg ple_f_r ;
reg [1:0] ple_f2s_r ;
reg [1:0] ple_s2f_r ;
//Fast clock
always @(posedge clk_f or negedge rst_n) begin
if(~rst_n) begin
ple_f_r <= Pulse ;
end
else if(~clr_n) begin
ple_f_r <= 1'b0 ;
end
else if(ple_f) begin
ple_f_r <= 1'b1 ;
end
else begin
ple_f_r <= ple_f_r ;
end
end
//Slow Clock
always @(posedge clk_s or negedge rst_n) begin
if(~rst_n) begin
ple_f2s_r <= 2'b0 ;
end
else begin
ple_f2s_r <= {ple_f2s_r[0],ple_f_r };
end
end
//Feedback
always @(posedge clk_f or negedge rst_n) begin
if(~rst_n) begin
ple_s2f_r <= 2'b0;
end
else begin
ple_s2f_r <= {ple_s2f_r[0],ple_s};
end
end
//assign
assign ple_s = ple_f2s_r[1] ;
assign clr_n = ~(~ple_f && ple_s2f_r[1]) ;
endmodule
在做多bit数据的CDC处理时,也可以按照信号类型分类,电平信号可以按照延迟打拍进行同步处理。要是数据变化速度快,可以采用异步FIFO来完成跨时钟域的处理。
无论是慢时钟到快时钟,还是快时钟到慢时钟,都可以使用异步FIFO处理
异步FIFO的相关知识可以看我之前的博客:
链接: link
CDC是需要在实际项目中体会的,最简单的就是UART协议。平时用的最多的是两级触发器、异步FIFO、握手协议这三种。感兴趣的同学可以自己找一个项目练练手,后续我也会分享个人简历里的项目,主要是两个大部分,一个是SDRAM控制及其衍生的相关项目,第二个主要的就是CNN加速器。
注:
(1)SDRAM控制器相关的我会共享出来,毕竟这个算是很基础的东西,网上也能找到很多相关的资源,我个人的这个小项目是在研一的时候用来参加比赛的,完成了SDRAM最高频率166MHz的实际测试(网上很多是100Mhz,133Mhz,频率相对低一点。)
(2)CNN加速器是我个人花了大半年的时间完成的,经过下板测试的,目前也正在整理相关的资料,考虑到时间和精力成本,会采取收费的方式。感兴趣的同学可以私聊,后续完成资料整理后我会分享出来,供大家学习。
多时钟域电路会产生亚稳态、建立和保持时间违背方面的问题。跨时钟域问题作为笔面中的必考题,短短一篇博客根本讲不完,大家可以多搜索相关博客和书本知识。 先学习基础知识,了解单bit、多bit、快到慢、慢到快这几种CDC问题的处理方式 ,然后在实际项目中对这些方法进行实践。