单bit数据跨时钟域信号处理

CDC单bit数据跨时钟域处理(慢到快&&快到慢)

一.慢时钟域到快时钟域

1.1 基础知识点

------后者为本时钟域,从慢时钟域来的信号是本时钟域的异步信号;慢到快首先能够保证慢时钟的脉冲序列或电平能够被快时钟采到,但是不一定能满足本时钟域的建立时间保持时间,由此可能会导致电路出现不确定状态:亚稳态,甚至是亚稳态的传播,因此需要加入两级同步器进行同步,减少亚稳态发生概率。

------如果两级同步器第一级不满足其建立保持时间,则Register1输出很可能产生不确定的抖动状态,但是大概率会在第二个Register2的建立时间之前稳定下来,以至于电路实现同步时序的效果。典型0.25um ASIC≈2.01(day)出现亚稳态,使用双寄存器法后,平均9.57*10^9年才出现亚稳态,MTBF(一个衡量亚稳态的公式,越大越不容易出现亚稳态)足够大。

------本处只是打两拍直接承接慢时钟域信号,如果只需检测脉冲信号即还原单时钟域脉冲,则在register2和CDC_SF_out后接一个与门,其中CDC_SF_out端口输出要加个非门,既能有效检测脉冲并还原单时钟脉冲信号。

1.2 Verilog实现及仿真验证

1.21 Verilog实现
`timescale 1ns/1ps
module CDC_SF			
(        
	input					clk_s,      //slow
	input					clk_f,		//fast
	input					rst_n,
	input 					CDC_SF_in,
	
	output reg				CDC_SF_out
);
	//************Register definition***************
	reg Register_a;
	reg Register_1;
	reg Register_2;
	
	//*************clk_s circutry********************
	always@( posedge clk_s or negedge rst_n ) begin
		if( !rst_n )
			Register_a <= 0;
		else
			Register_a <= CDC_SF_in;
	end
	
	//*************clk_f circutry********************
	//打两拍
	always@( posedge clk_f or negedge rst_n ) begin
		if( !rst_n ) begin
			Register_1 <= 0;
			Register_2 <= 0;
		end
		else begin
			Register_1 <= Register_a;
			Register_2 <= Register_1;
		end
	end
	//clk_2 Clock recive steady data input 
	always@( posedge clk_f or negedge rst_n ) begin
		if( !rst_n ) 
			CDC_SF_out <= 0;
		else 
			CDC_SF_out <= Register_2;
	end
endmodule
1.22 testbench
`timescale 1ns/1ps
`define clock_period 20
module CDC_SF_tb();
    //parameter definition
    reg clk_s;
    reg clk_f;
    reg rst_n;
    reg CDC_SF_in;
    wire CDC_SF_out;
    //DUT
    CDC_SF CDC_SF0
    (
        .clk_s(clk_s),
        .clk_f(clk_f),
        .rst_n(rst_n),
        .CDC_SF_in(CDC_SF_in),

        .CDC_SF_out(CDC_SF_out)
    );
    
    //Clock
    initial begin
        clk_s = 1;
        clk_f = 1;
    end
    always#(`clock_period/2) begin 
        clk_s = ~clk_s;
    end
    always#(`clock_period/4) begin 
        clk_f = ~clk_f;
    end
    
    //Siginal generation
    initial begin
       rst_n = 0;
       CDC_SF_in = 0;
       #(`clock_period*10 + 1);
       rst_n = 1;
       #(`clock_period/2);
       CDC_SF_in = 1;
       #(`clock_period*10);
       $stop;
    end
    
    initial begin
        $vcdpluson;
    end
endmodule
1.23 仿真结果

如图1所示,从慢时钟域clk_s传到快时钟域clk_f后在快时钟域打两拍,然后输出给CDC_SF_out作为稳态数据。
在这里插入图片描述
图1

二.快到慢的两种实现方法

2.1 基础知识点

-----同样是跨时钟域信号同步类型,即需满足当前时钟域的建立保持时间,但快到慢的CDC将更加的苛刻,比如快时钟一个周期的脉冲不加处理下在慢时钟域很可能漏采,则需要扩宽脉冲宽度,对应方案有翻转电路法和结绳法,另还有兼容慢到快以及快到慢锁存器法(电平检测法),但容易受毛刺影响,少用或者不用锁存器法这种方法;
-----翻转电路基本功能:从本时钟域取出一个单时钟宽度脉冲,然后在新的时钟中建立另一个单时钟宽度的脉冲。但是输入脉冲时间必须至少保持两个接收时间宽度,否则无法恢复脉冲。

2.2 Verilog示例1(时域延长翻转电路法)及其仿真

2.21 Verilog实现
module CDC_FS(
	input					clk_f,           //fast
	input					clk_s,           //slow
	input					rst_n,
	input					CDC_FS_in,
	
	output					CDC_FS_out
);
	//parameter definition
	reg toggle;
	reg register_1;
	reg register_2;
	reg register_3;
	
	//*************************Main*******************************
	//Return circuit
	always@( posedge clk_f or negedge rst_n ) begin
		if( !rst_n )
			toggle <= 0;
		else if( CDC_FS_in == 1 )
			toggle <= ~toggle;
		else
			toggle <= toggle;	
    end
	//Two state later
	always@(posedge clk_s or negedge rst_n) begin
		if( !rst_n ) begin
			register_1 <= 0;
			register_2 <= 0;
		end
		else begin
			register_1 <= toggle;
			register_2 <= register_1;
		end
	end
	//Reback and output
	always@( posedge clk_s or negedge rst_n ) begin
		if( !rst_n )
			register_3 <= 0;
		else
			register_3 <= register_2;
	end
	
	assign CDC_FS_out = register_2^register_3;
endmodule
2.22 testbench
`timescale 1ns/1ps
`define clock_period 20
module CDC_FS_tb();
    //parameter definition
    reg clk_f;
    reg clk_s;
    reg rst_n;
    reg CDC_FS_in;
    wire CDC_FS_out;

    //DUT
    CDC_FS CDC_FS0
    (
        .clk_f(clk_f),
        .clk_s(clk_s),
        .rst_n(rst_n),
        .CDC_FS_in(CDC_FS_in),

        .CDC_FS_out(CDC_FS_out)
    );

    //Clock
    initial begin
        clk_f = 1;
        clk_s = 1;
    end

    always#(`clock_period/2) begin 
        clk_s = ~clk_s;
    end
    always#(`clock_period/4) begin 
        clk_f = ~clk_f;
    end
    
    //Siginal generation
    initial begin
       rst_n = 0;
       CDC_FS_in = 0;
       #(`clock_period*10 + 1);
       rst_n = 1;
       #(`clock_period/2);
       CDC_FS_in = 1;
       #(`clock_period/2);
       CDC_FS_in = 0;
       #(`clock_period*2);
       CDC_FS_in = 1;
       #(`clock_period/2);
       CDC_FS_in = 0;
       #(`clock_period*10);
       $stop;
    end
    
    initial begin
        $vcdpluson;
    end
endmodule
2.23 仿真结果

-----如下图2所示,快时钟域的两个脉冲信号在慢时钟域(本)恢复成了两个脉冲信号,即恢复成功。
在这里插入图片描述
图2

2.3 Verilog示例2(结绳法待补充)

-----脉冲同步过程为结绳和解绳过程。

三.握手通信方法(兼容快到慢和慢到快)

-----如RS232串口通信方式,收发双方根据统一的波特率进行传输,实现数据的有效传送,但如果每次传输为多bit数据,那么延迟较大,不推荐以上单bit传输方式:打拍、锁存器法、翻转电路法和结绳法。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值