数字IC笔面基础,面试100%涉及——跨时钟域处理(CDC相关知识点梳理和Verilog范例)

写在前面的话

跨时钟域处理真的是个非常综合的话题,涉及到很多方式,多时钟域的处理对于设计工程师是个富有挑战的话题。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问题的处理方式 ,然后在实际项目中对这些方法进行实践。

跨时钟域处理格雷码是指在不同时钟域之间进行格雷码的转换和处理Verilog语言提供了一些机制来实现这样的跨时钟域处理。 首先,Verilog中可以使用时钟使能(clock enable)来控制时钟域切换时的格雷码转换。通过将格雷码生成逻辑放置在与时钟同步的时钟域中,然后通过时钟使能来控制格雷码转换的触发。例如,当时钟使能信号为高电平时,才允许进行格雷码转换。这样可以确保在不同的时钟域之间进行同步的格雷码处理。 其次,Verilog中也可以使用寄存器来存储并传递格雷码数据。在不同的时钟域之间,可以使用寄存器来进行数据的缓存和同步。通过在时钟域切换的边缘上,将新的格雷码数据写入到寄存器中,并在另一个时钟域的相应边缘上,将寄存器中的格雷码数据读取出来。这样可以确保在跨时钟域处理过程中,数据传递的正确性和可靠性。 最后,需要注意跨时钟域处理的时延问题。由于不同时钟域之间存在时钟延迟,因此需要合理的时序设计来保证跨时钟域处理的正确性。可以使用合适的时钟域切换信号和时钟域边缘触发机制,来确保时序的正确性和时延的合理性。 总而言之,通过合理的时钟使能控制、寄存器存储和时序设计,可以实现跨时钟域处理格雷码的Verilog设计。这样可以确保在不同的时钟域之间进行格雷码转换和处理的正确性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值