面试100%涉及——跨时钟域处理

[TOC]

写在前面的话

跨时钟域处理真的是个非常综合的话题,涉及到很多方式,多时钟域的处理对于设计工程师是个富有挑战的话题。CDC(Clock Domain Conversion)不仅涉及理论学习,还要求具备实践经验。只会书本上的知识点,而不去实践,很难彻底理解CDC方法,在面试中简单的几个问题就会露馅。
例如:系统有几个时钟?每个时钟频率和相位是什么关系?哪些模块涉及到跨时钟处理?单bit还是多bit?关键路径在哪里? 等等

这里对大家的要求是最严格的,不仅要学会CDC理论知识,还要涉及到项目中的实践,了解时序分析并实际做过时序约束和时序报告处理相关的工作,也是前端设计工程师最后的重要工作,综合。

一篇博客真的很难理清所有知识点,强烈建议大家多学习,不管是书本、博客还是实际代码,只要之前没涉及,都可以了解了解。平常也多温习CDC相关的知识点,多尝试实践,理解每种方法的实现过程,优缺点,以及最重要的一点,将理论用于实际项目,真正搞好一个跨时钟域处理的工作,这样在面试中肯定有话题可以讲。

CDC相关知识点梳理

下面这张图是我在笔记中找到的,里面涉及到的关键词,感兴趣的同学可以多去了解了解

CDC基础知识(要求必须会)

单bit 慢到快

先看实现方法:
慢时钟到快时钟,为了避免亚稳态,最常用的方法是两级D触发器,也就是常说的“打两拍”。其基本原理是,当第一个触发器处于亚稳态时,仍有一个时钟周期用来恢复亚稳态。
同步器示意图:

除了上述这种,利用两个触发器处理慢时钟到快时钟的亚稳态,有些时候,我们需要采样慢时钟的变沿跳变,这时候就利用三个触发器加上边沿检测电路,电路示意图如下:

边沿检测同步器:

两个触发器用于同步信号,逻辑门用于检测边沿。

再看Verilog代码:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2022 All rights reserved
// -----------------------------------------------------------------------------
// Author : HFUT904  1320343336@qq.com
// 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 快到慢

快时钟到慢时钟的单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  1320343336@qq.com
// 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(会使用IP并手撕经典代码)

在做多bit数据的CDC处理时,也可以按照信号类型分类,电平信号可以按照延迟打拍进行同步处理。要是数据变化速度快,可以采用异步FIFO来完成跨时钟域的处理。
无论是慢时钟到快时钟,还是快时钟到慢时钟,都可以使用异步FIFO处理

异步FIFO的相关知识可以看我之前的博客:
链接: link

项目实践最重要

CDC是需要在实际项目中体会的,最简单的就是UART协议。平时用的最多的是两级触发器、异步FIFO、握手协议这三种。感兴趣的同学可以自己找一个项目练练手,后续我也会分享个人简历里的项目,主要是两个大部分,一个是SDRAM控制及其衍生的相关项目,第二个主要的就是CNN加速器。

注:
(1)SDRAM控制器相关的我会共享出来,毕竟这个算是很基础的东西,网上也能找到很多相关的资源,我个人的这个小项目是在研一的时候用来参加比赛的,完成了SDRAM最高频率166MHz的实际测试(网上很多是100Mhz,133Mhz,频率相对低一点。)

(2)CNN加速器是我个人花了大半年的时间完成的,经过下板测试的,目前也正在整理相关的资料,考虑到时间和精力成本,会采取收费的方式。感兴趣的同学可以私聊,后续完成资料整理后我会分享出来,供大家学习。

总结

多时钟域电路会产生亚稳态、建立和保持时间违背方面的问题。跨时钟域问题作为笔面中的必考题,短短一篇博客根本讲不完,大家可以多搜索相关博客和书本知识。 先学习基础知识,了解单bit、多bit、快到慢、慢到快这几种CDC问题的处理方式 ,然后在实际项目中对这些方法进行实践。