【Verilog-CBB】开发与验证(2)——单比特信号CDC同步器



引言

多时钟域的设计中,CDC处理的场景还是蛮多的。单比特信号在CDC时,为保证信号采样的安全性,降低亚稳态,必须要对信号做同步处理。CDC从时钟的快慢关系来说分为两种case:快到慢、慢到快。对于脉冲型的控制信号,在以上两种case中都需要满足如下条件才能保证控制信号CDC的安全性:

源端控制信号的脉冲宽度>1.5倍目的端时钟周期 (即 ”三时钟沿“ 要求)。

一般建议以上条件中1.5增大为2。

在设计同步器时需要注意,源端控制信号必须为寄存器输出。否则组合逻辑的毛刺可能会影响目的端的采样。

CBB设计源码

这个功能相对来说比较简单,就不扯框图和原理了,直接上代码。

// ==================-------------------------------------------------------=====================
//                                        在路上-正出发
//                                    Common Building Block
// ==================-------------------------------------------------------=====================

//                 ________          ________          ________                                                               
//                |\   ____\        |\   __  \        |\   __  \                                                              
//                \ \  \___|        \ \  \|\ /_       \ \  \|\ /_                                                             
//                 \ \  \            \ \   __  \       \ \   __  \                                                            
//                  \ \  \____        \ \  \|\  \       \ \  \|\  \                                                           
//                   \ \_______\       \ \_______\       \ \_______\                                                          
//                    \|_______|        \|_______|        \|_______|  

// ==================-------------------------------------------------------=====================
//                                        在路上-正出发
//                                    Common Building Block
// ==================-------------------------------------------------------=====================                                                                                                              
                                                                                                                                                                                                                                                                                                         
// CBB Module Name    :CBB_PULSE_SYNCHRONIZER
// CBB Created Date   :2024-08-02
// CBB Module Function:单比特脉冲信号跨时钟域处理
// Usage Limitation   :
// Author             :在路上-正出发
// -----------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------

`timescale 1ns/1ps


module  CBB_PULSE_SYNCHRONIZER #(
// ---- parameter define
parameter P_EXTEN_EN		= "ENABLE",  //"ENABLE" or "DISABLE"
parameter P_EXTEN_MULT 		= 3,	     //2 or larger
parameter P_SYNC_STAGE 		= 2,	     //2 or larger
parameter P_PULSE_WIDTH     = "CARE-1"   //"CARE-1" or "NOTCARE"
)(
// ---- port define 
input 							i_clk_src,
input 							i_rstn_src,
input 							i_pulse_src,//must be register output(source clk)

input 							i_clk_dst,
input 							i_rstn_dst,
output 							o_pulse_dst

);

reg [P_EXTEN_MULT-2:0] 			r_pluse_src_dly;
reg 				   			r_pulse_exten;
reg [P_SYNC_STAGE-1:0]			r_pulse_sync;

generate
	if(P_EXTEN_EN == "ENABLE")
	begin
		if(P_EXTEN_MULT <= 2)
		begin
			always @(posedge i_clk_src or negedge i_rstn_src) begin : proc_pulse_exten1
				if(~i_rstn_src) begin
					 r_pluse_src_dly <= {(P_EXTEN_MULT-1){1'b0}};
				end else begin
					 r_pluse_src_dly <= {i_pulse_src};
				end
			end
			always @(posedge i_clk_src or negedge i_rstn_src) begin : proc_pulse_exten2
				if(~i_rstn_src) begin
					 r_pulse_exten <= 1'b0;
				end else begin
					 r_pulse_exten <= |{r_pluse_src_dly,i_pulse_src};
				end
			end
			always @(posedge i_clk_dst or negedge i_rstn_dst) begin : proc_pulse_sync
				if(~i_rstn_dst) begin
					 r_pulse_sync <= {(P_SYNC_STAGE){1'b0}};
				end else begin
					 r_pulse_sync <= {r_pulse_sync[P_SYNC_STAGE-2:0],r_pulse_exten};
				end
			end			
	    end
	    else
	    begin
			always @(posedge i_clk_src or negedge i_rstn_src) begin : proc_pulse_exten
				if(~i_rstn_src) begin
					 r_pluse_src_dly <= {(P_EXTEN_MULT-1){1'b0}};
				end else begin
					 r_pluse_src_dly <= {r_pluse_src_dly[P_EXTEN_MULT-3:0],i_pulse_src};
				end
			end
			always @(posedge i_clk_src or negedge i_rstn_src) begin : proc_pulse_exten2
				if(~i_rstn_src) begin
					 r_pulse_exten <= 1'b0;
				end else begin
					 r_pulse_exten <= |{r_pluse_src_dly,i_pulse_src};
				end
			end
			always @(posedge i_clk_dst or negedge i_rstn_dst) begin : proc_pulse_sync
				if(~i_rstn_dst) begin
					 r_pulse_sync <= {(P_SYNC_STAGE){1'b0}};
				end else begin
					 r_pulse_sync <= {r_pulse_sync[P_SYNC_STAGE-2:0],r_pulse_exten};
				end
			end
	    end
	end
	else
	begin
		always @(posedge i_clk_dst or negedge i_rstn_dst) begin : proc_pulse_sync
			if(~i_rstn_dst) begin
				 r_pulse_sync <= {(P_SYNC_STAGE){1'b0}};
			end else begin
				 r_pulse_sync <= {r_pulse_sync[P_SYNC_STAGE-2:0],i_pulse_src};
			end
		end		
	end
endgenerate

generate
	if(P_PULSE_WIDTH == "CARE-1")
	begin
		assign o_pulse_dst = r_pulse_sync[P_SYNC_STAGE-2] & (~r_pulse_sync[P_SYNC_STAGE-1]); 
	end
	else
	begin
		assign o_pulse_dst = r_pulse_sync[P_SYNC_STAGE-1];
	end
endgenerate

endmodule

CBB使用说明

P_EXTEN_EN:需要进行脉冲展宽时,将使能开关打开;

P_EXTEN_MULT:表示脉冲在源时钟域被展宽的倍数,这个倍数需要使用者根据上述1.5或2倍关系折算。

P_SYNC_STAGE:表示目的时钟域打拍的级数。

P_PULSE_WIDTH:"CARE-1"表示,目的侧时钟域输出的脉冲宽度为1个时钟周期;“NOTCARE”则表示目的侧打拍直接输出,不取边沿。

【注意】输入信号i_pulse_src必须为寄存器输出。

CBB验证

CASE1:快—>慢(使能脉冲展宽,3倍)

CASE2:慢—>快(不使能脉冲展宽)

验证代码

// ==================-------------------------------------------------------=====================
//                                        在路上-正出发
//                                    Common Building Block
// ==================-------------------------------------------------------=====================

//                 ________          ________          ________                                                               
//                |\   ____\        |\   __  \        |\   __  \                                                              
//                \ \  \___|        \ \  \|\ /_       \ \  \|\ /_                                                             
//                 \ \  \            \ \   __  \       \ \   __  \                                                            
//                  \ \  \____        \ \  \|\  \       \ \  \|\  \                                                           
//                   \ \_______\       \ \_______\       \ \_______\                                                          
//                    \|_______|        \|_______|        \|_______|  

// ==================-------------------------------------------------------=====================
//                                        在路上-正出发
//                                    Common Building Block
// ==================-------------------------------------------------------=====================                                                                                                              
                                                                                                                                                                                                                                                                                                         
// CBB Module Name    :TB_PULSE_SYNCHRONIZER
// CBB Created Date   :2024-08-03
// CBB Module Function:
// Usage Limitation   :
// Author             :在路上-正出发
// -----------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------

`timescale 1ns/1ps

// `define TC_FAST_2_LOW
`define TC_LOW_2_FAST

module TB_PULSE_SYNCHRONIZER ();
// ---- parameter define
parameter P_EXTEN_EN		= "DISABLE"; //"ENABLE" or "DISABLE"
parameter P_EXTEN_MULT 		= 3;	    //2 or larger
parameter P_SYNC_STAGE 		= 2;	    //2 or larger
parameter P_PULSE_WIDTH     = "CARE-1"; //"CARE-1" or "NOTCARE"

// ---- port define 
reg 							i_clk_src;
reg 							i_rstn_src;
reg 							i_pulse_src;//must be register output(source clk)

reg  							i_clk_dst;
reg  							i_rstn_dst;
wire 							o_pulse_dst;

// 产生时钟
`ifdef TC_FAST_2_LOW
initial i_clk_src = 1'b0;
always #5 i_clk_src = ~i_clk_src;
initial i_clk_dst = 1'b0;
always #10 i_clk_dst = ~i_clk_dst;
`endif

`ifdef TC_LOW_2_FAST
initial i_clk_src = 1'b0;
always #10 i_clk_src = ~i_clk_src;
initial i_clk_dst = 1'b0;
always #5 i_clk_dst = ~i_clk_dst;
`endif

// 
initial
begin
	i_rstn_src = 1'b0;
	i_rstn_dst = 1'b0;
	i_pulse_src = 1'b0;
	#100;
	i_rstn_dst = 1'b1;
	i_rstn_src = 1'b1;
	#50;
	@(posedge i_clk_src)
	i_pulse_src <= 1'b1;
	@(posedge i_clk_src)
	i_pulse_src <= 1'b0;

	@(negedge o_pulse_dst);
	#200;
	$finish;
end

CBB_PULSE_SYNCHRONIZER #(
		.P_EXTEN_EN(P_EXTEN_EN),
		.P_EXTEN_MULT(P_EXTEN_MULT),
		.P_SYNC_STAGE(P_SYNC_STAGE),
		.P_PULSE_WIDTH(P_PULSE_WIDTH)
	) U_CBB_PULSE_SYNCHRONIZER (
		.i_clk_src   (i_clk_src),
		.i_rstn_src  (i_rstn_src),
		.i_pulse_src (i_pulse_src),
		.i_clk_dst   (i_clk_dst),
		.i_rstn_dst  (i_rstn_dst),
		.o_pulse_dst (o_pulse_dst)
	);



endmodule


CBB电路综合

使能脉冲展宽

源时钟域下,控制信号经多拍延迟,源信号与延迟信号经过或门输出,输出的信号在源时钟域寄存输出,目的测时钟域对展宽的信号做打拍处理,取上升沿输出。

不使能脉冲展宽

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在路上-正出发

哈哈,多少是个心意

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值