精华内容
下载资源
问答
  • 单bit电平信号以及脉冲信号跨时钟域处理
    2022-03-04 10:19:54


    前言

    单bit信号的跨时钟域处理,可以分为电平信号的跨时钟域处理和脉冲信号的跨时钟域处理。

    一、电平信号的跨时钟域处理

    电平信号,就是说clka下的信号signal_a在clkb看来,是一个很宽的信号,会保持多个clkb的时钟周期,一定能被clkb采到。这种情况,只需要在clkb时钟域下用至少两级DFF将signal_a打两拍即可。

    特别需要强调的是,此时signal_a必须是clka下的寄存器信号。如果signal_a是clka下的组合逻辑信号,一定要先在clka下用DFF打一拍,再使用两级DFF向clkb传递。这是因为clka下的组合逻辑信号会有毛刺,在clka下使用时会由setup/hold时间保证毛刺不会被clka采到,但由于异步相位不确定,组合逻辑的毛刺却极有可能被clkb采到。

    具体代码如下:

    module level_signal_sync(
            input    wire   clk_b,
            input    wire   rst_n,
            input    wire   levl_a,
            output   wire   levl_b,
            output   wire   levl_b_pos,
            output   wire   levl_b_neg              
                            );
    reg   levl_b_syn1, levl_b_syn2, levl_b_syn3;
    
    always @(posedge clk_b, negedge rst_n) begin
        if(rst_n == 1'b0) begin
            levl_b_syn1 <= #1 1'b0;
            levl_b_syn2 <= #1 1'b0;
            levl_b_syn3 <= #1 1'b0;
        end
        else begin
            levl_b_syn1 <= #1 levl_a;
            levl_b_syn2 <= #1 levl_b_syn1;
            levl_b_syn3 <= #1 levl_b_syn2;
        end
    end
    assign levl_b = levl_b_syn2;
    assign levl_b_pos = levl_b_syn2 && (~levl_b_syn3);
    assign levl_b_neg = (~levl_b_syn2) && levl_b_syn3;
    endmodule
    

    上面三个输出分别是经过同步之后,clkb下可以使用的电平信号、0变1脉冲信号以及1变0脉冲信号。再次强调:levl_a必须是clka的DFF信号!

    二、脉冲信号的跨时钟域处理

    下面是更常见的,clka下的脉冲信号,同步到clkb时钟域下,它对于clka与clkb的时钟频率关系没有任何限制,快到慢,慢到快都可以。其主要原理就是先把脉冲信号在clka下展宽,变成电平信号,再向clkb传递,当确认clkb已经“看见”信号同步过去之后,再清掉clka下的电平信号。
    具体代码如下:

    module pulse_signal_sync(
           input   wire   clk_a,
           input   wire   clk_b,
           input   wire   rst_n,
           input   wire   puls_a,
           output  wire   puls_b,
           output  wire   levl_b
                            );
    reg   levl_a;
    reg   levl_b_syn1, levl_b_syn2, levl_b_syn3;
    reg   levl_b2a_syn1, levl_b2a_syn2;
    
    //生成clka时钟域的脉冲展宽信号
    always @(posedge clk_a, negedge rst_n) begin
        if(rst_n == 1'b0) begin
            levl_a <= #1 1'b0;
        end
        else if(puls_a) begin
            levl_a <= #1 1'b1;
        end
        else if(levl_b2a_syn2) begin
            levl_a <= #1 1'b0;
        end
        else begin
            levl_a <= #1 levl_a;
        end
    end
    
    //在clkb时钟域采样展宽后的信号
    always @(posedge clk_b, negedge rst_n) begin
        if(rst_n == 1'b0) begin
            levl_b_syn1 <= #1 1'b0;
            levl_b_syn2 <= #1 1'b0;
            levl_b_syn3 <= #1 1'b0;
        end
        else begin
            levl_b_syn1 <= #1 levl_a;
            levl_b_syn2 <= #1 levl_b_syn1;
            levl_b_syn3 <= #1 levl_b_syn2;
        end
    end
    
    //在clka时钟域内同步clkb时钟域内的展宽信号,以生成反馈信号
    always @(posedge clk_a, negedge rst_n) begin
        if(rst_n == 1'b0) begin
            levl_b2a_syn1 <= #1 1'b0;
            levl_b2a_syn2 <= #1 1'b0;
        end
        else begin
            levl_b2a_syn1 <= #1 levl_b_syn2;
            levl_b2a_syn2 <= #1 levl_b2a_syn1;
        end
    end
    
    assign puls_b = levl_b_syn2 && (~levl_b_syn3);
    assign levl_b = levl_b_syn2;
    endmodule
    

    总结:
    1、慢时钟域到快时钟域的单bit信号,一般可以直接通过打两拍的方式来处理。
    2、快时钟域到慢时钟域的脉冲信号,由于脉冲宽度较窄,采用打两拍的方式在慢时钟域内有可能采样不到,因此需要采用握手的方式处理。

    3、首先是在快时钟域下将脉冲展宽(快时钟域下脉冲信号到来时将电平信号拉高,慢时钟域下的反馈信号到来后将电平信号拉低)。
    4、展宽后的电平信号在慢时钟域下打两拍,结果作为电平输出信号。
    5、慢时钟域下的电平输出信号在快时钟域下打两拍,结果作为反馈信号。
    6、在慢时钟域下采用边沿检测的方式,可以生成脉冲输出信号。

    更多相关内容
  • 1.电平检测 ...注意跨时钟域同步的时候输出的脉冲必须是寄存器信号,如果需要被同步的脉冲是通过组合逻辑产生的,那么在同步之前一定要在本时钟域下用寄存器抓一拍。比如,clka下通过计数器产生了脉冲信号pls

    1.电平检测

    从慢时钟到快时钟

    用触发器打两拍,降低亚稳态的影响。
    在这里插入图片描述
    限制条件:(data数据变化间隔)>(慢时钟域周期)+2*(快时钟域周期)+(路径延时)
    确保所有数据的变化都能被采集到。

    2.边沿检测

    从慢时钟到快时钟
    由慢时钟域到快时钟域的边沿同步电路结构相对简单。慢时钟域的脉冲信号在快时钟域来看就是电平信号。注意跨时钟域同步的时候输出的脉冲必须是寄存器信号,如果需要被同步的脉冲是通过组合逻辑产生的,那么在同步之前一定要在本时钟域下用寄存器抓一拍。比如,clka下通过计数器产生了脉冲信号pls_a = (cnt==4’d5),如果要将pls_a同步到另外一个时钟域,首先在clka下将pls_a打一拍,避免组合逻辑产生的毛刺,这一点是异步信号处理的基本原则。
    在这里插入图片描述

    如图3所示,pls_slow是来自慢时钟域的脉冲信号被同步到快时钟域clk_fast,在pls_slow经过2级DFF处理后的信号认为是稳定的,将该信号取反并和下一拍的信号作与逻辑,即可在clk_fast时钟域产生脉冲信号neg_b(下降沿脉冲检测),同理将该信号与下一拍的取反信号作与逻辑可产生pos_b(上升沿脉冲检测)。

    下面展示一些 内联代码片

    module plus_s2f(
       input clka,   //慢时钟
       input clkb,   //快时钟
       input rstn,
       input pls_a,
       output pls_b
    );
    
    reg pls_b_1;
    reg pls_b_2;
    reg pls_b_3;
    always@(posedge clkb)begin
      if(!rstn) begin
        pls_b_1 <= 1'b0;
        pls_b_2 <= 1'b0;
        pls_b_3 <= 1'b0;
      end
      else begin
        pls_b_1 <= pls_a;
        pls_b_2 <= pls_b_1;
        pls_b_3 <= pls_b_2; 
      end
    end
    
    assign pls_b = pls_b_3 &(~pls_b_2);
    
    endmodule
    

    3.脉冲同步

    从快时钟到慢时钟
    基本功能:从某个时钟域取出一个单时钟宽度脉冲,然后在新的时钟域中建立另一个单时钟宽度脉冲。
    在这里插入图片描述
    在这里插入图片描述
    step1: 由于快时钟的时钟频率比慢时钟高,慢时钟域采样快时钟的脉冲很可能会采不到。通过toggle电路将快时钟域前后间隔较多个周期的两个有效脉冲进行了有效的标定,形成图中toggle波形
    step2: 在慢时钟域clk2通过同步电路将这个toggle信号进行同步,形成引脚A的波形XOR(A)
    step3:通过触发器将同步电路输出信号再次经过一个触发器,使得B引脚的波形比A引脚的波形晚一个时钟周期,如图XOR(B)所示
    step4:逻辑门对AB信号进行逻辑运算,得到了慢时钟域下两个有效的单周期脉冲output

    module plus_syn(
       input clka,   //快时钟
       input clkb,   //慢时钟
       input i_data,
       output o_data
     );
     wire D_in;
     wire Q_a1; 
     reg Q_a0 = 1'b0;
     reg Q_b0 = 1'b0;
     reg Q_b1 = 1'b0;
     reg Q_b2 = 1'b0; 
      
     assign D_in = i_data?Q_a1 :Q_a0 ;
     assign Q_a1 = ~Q_a0;  
    
     always@(posedge clka)begin
       Q_a0 <= D_in;
     end
    
    always@(posedge clkb)begin
       Q_b0 <= Q_a0 ;
       Q_b1 <= Q_b0 ;
       Q_b2 <= Q_b1 ;
    end
    
    assign o_data =  Q_b2 ^ Q_b1;
    endmodule
    

    4.结绳法

    从快时钟域到慢时钟域

    **结绳法原理:**将快时钟的脉冲周期延长,等到慢时钟同步后再解绳
    结绳的方式有两种:1.利用脉冲的边沿做时钟
    2.利用脉冲电平做选择器选择信号
    解绳的方式有两种:1.利用采集到的脉冲做异步复位信号
    2.利用采集到的脉冲做握手响应信号

    举例1:结绳、解绳均采用方式1:
    利用数据的边沿作为时钟(可以将脉冲无限延长,直到可以采集到数据,然后复位,要考虑产生数据的频率)
    将快时钟信号的脉冲周期延长,等到慢时钟同步采样后再“解绳”,还原为原来的脉冲周期宽度
    在这里插入图片描述
    2、功能分析
    step1: 当数据有上升沿时,寄存器1的输出将会稳定在高电平,此时等待ClkB采样。
    step2: clk的同步器完成采样后,寄存器4会输出高电平,该信号同时会反馈回第一个寄存器。
    step3:若此时输入的数据Din_clkA为低电平,与反馈信号一同经过与门逻辑运算激活异步复位,开始下一次采样等待。
    3、结绳法限制
    在慢时钟采样快时钟域时,结绳法适合采样数据较少(即脉冲间隔较大>3CLKB)的控制信号;即等待3个clkB时钟后,完成复位,才允许下一个输入脉冲。
    举例2:结绳、解绳均采用方式2:
    要将快时钟域的脉冲信号同步到慢时钟域的信号常采用握手的机制实现,所以该电路又常被称为握手电路,其设计思路为:首先在慢时钟域下将快时钟域的脉冲转换为电平信号,然后把电平信号同步到快时钟域,同步完成后的信号要反馈回快时钟域,快时钟域接收到该信号后给控制信号,原来的电平信号被拉低。
    在这里插入图片描述

    module pls_f2s(
       input clka,  //快时钟
       input clkb,  //慢时钟
       input rstn,
       input pls_a,  //快时钟脉冲
       output pls_b   //慢时钟脉冲
    );
    
    reg reg_pls_level;
    reg reg_pls_a1;
    reg reg_pls_a2;
    reg reg_pls_b1;
    reg reg_pls_b2;
    reg reg_pls_b3;
    always@(posedge clka)begin    
      if(!rstn)
        reg_pls_level <= 1'b0; 
      else if(pls_a)              //快时钟域下脉冲信号展宽
        reg_pls_level <= 1'b1;
      else if(reg_pls_a2)        //握手信号
        reg_pls_level <= 1'b0;
      else
        reg_pls_level <= reg_pls_level;
    end
    
    always@(posedge clkb)begin  //慢时钟域下打拍
      if(!rstn)begin
       reg_pls_b1 <= 1'b0;
       reg_pls_b2 <= 1'b0;
       reg_pls_b3 <= 1'b0;   
      end
      else begin
       reg_pls_b1 <= reg_pls_level ;
       reg_pls_b2 <= reg_pls_b1;
       reg_pls_b3 <= reg_pls_b2;
      end
    end
    
    always@(posedge clka)begin    //快时钟域下打拍 
      if(!rstn)begin
        reg_pls_a1 <= 1'b0;
        reg_pls_a2 <= 1'b0;
      end
      else begin
        reg_pls_a1 <= reg_pls_b2;
        reg_pls_a2 <= reg_pls_a1 ;
      end
    end
    
    assign pls_b = reg_pls_b2 &(~reg_pls_b3);  //边沿信号检测
    
    展开全文
  • 单bit信号跨时钟域的三种方法,电平同步器+边沿同步器+脉冲同步器 包含设计代码与测试代码,欢迎反馈
  • 缓变的单BIT信号进行跨时钟域转换常采用两级及以上D触发器打拍的方式解决,但为了保证编译器能够遵守编程者的意愿,跨时钟域转换代码编写往往需要一些编程技巧,下面以Xilinx的应用平台为例进行介绍。 一、RTL实现...

    异步信号同步化,是FPGA使用中独有的特点,也是逻辑工程时在进行代码编写时,应该特别需要注意的地方。本文章只介绍单比特缓变信号的跨时钟域转换。

    前言

    所谓的缓变信号是指满足奈圭斯特采样定律的信号。

    缓变的单BIT信号进行跨时钟域转换常采用两级及以上D触发器打拍的方式解决,但为了保证编译器能够遵守编程者的意愿,跨时钟域转换代码编写往往需要一些编程技巧,下面以Xilinx的应用平台为例进行介绍。

    一、RTL实现方式

    module async_in (
    	 input	wire		src_in          
    	,input	wire		dest_clk
    	,output	wire		dest_out
    );
    //==============================================================================================
    //======                                  define signal                                 ========
    //==============================================================================================
    	(* ASYNC_REG="TRUE" *)		reg	[2:0]	sreg	;
    //==============================================================================================
    //======                                  initial	                                 	========
    //==============================================================================================
    	initial begin
    		sreg = 3'b000;
    	end
    //==============================================================================================
    //======                                  behave of RTL                                 ========
    //==============================================================================================
    
    	always@(posedge dest_clk)begin
    		sreg <= {sreg[1:0], src_in};
    	end
    
    	assign dest_out = sreg[2];
      
    endmodule   
    

    说明:ASYNC_REG 是影响 Vivado 工具流程中许多进程的属性。 该属性的目的是通知工具,某个寄存器能够在 D 输入引脚中接收相对于源时钟的异步数据,或者该寄存器是同步链中的同步寄存器。 Vivado 综合,遇到这种情况时 属性将其视为 DONT_TOUCH 属性并将 ASYNC_REG 属性在网表中向前推送。 此过程可确保具有 ASYNC_REG 属性的对象不会被优化掉,并且流程中稍后的工具会收到该属性以正确处理它。

    “ASYNC_REG”属性对实现的影响

    在这里插入图片描述
    可以看到有“ASYNC_REG”属性时,综合工具实现后,与我们预期的目标设计相同。

    二、使用原语实现

    module async_cdc(
    	 input 	wire	src_in
    	,input	wire	dest_clk
    	,output	wire	dest_out
    );
    //==============================================================================================
    //======                                  define signal                                 ========
    //==============================================================================================
    	(* keep = "TRUE" *)wire 	data_sync1;
    	(* keep = "TRUE" *)wire 	data_sync2;
    //==============================================================================================
    //======                                  behave of RTL                                 ========
    //==============================================================================================
    	(* ASYNC_REG *) 
    	(* BOX_TYPE = "PRIMITIVE" *) 
    	(* SHREG_EXTRACT = "no" *) 
    	(* XILINX_LEGACY_PRIM = "FD" *) 
    	FDRE #(
    		.INIT		(1'b0		)
    	)data_sync_reg1(
    		 .C			(dest_clk	)
            ,.CE		(1'b1		)
            ,.D			(src_in		)
            ,.Q			(data_sync1	)
            ,.R			(1'b0		)
    	);
    	//---------------------------------------------------------//
    	(* ASYNC_REG *) 
    	(* BOX_TYPE = "PRIMITIVE" *) 
    	(* SHREG_EXTRACT = "no" *) 
    	(* XILINX_LEGACY_PRIM = "FD" *) 
    	FDRE #(
    		.INIT		(1'b0		)
    	)data_sync_reg2(
    		 .C			(dest_clk	)
            ,.CE		(1'b1		)
            ,.D			(data_sync1	)
            ,.Q			(data_sync2	)
            ,.R			(1'b0		)
    	);
    	//---------------------------------------------------------//
    	(* ASYNC_REG *) 
    	(* BOX_TYPE = "PRIMITIVE" *) 
    	(* SHREG_EXTRACT = "no" *) 
    	(* XILINX_LEGACY_PRIM = "FD" *) 
    	FDRE #(
    		.INIT		(1'b0		)
    	)data_sync_reg3(
    		 .C			(dest_clk	)
            ,.CE		(1'b1		)
            ,.D			(data_sync2	)
            ,.Q			(dest_out	)
            ,.R			(1'b0		)
    	);
    
    endmodule
    

    使用该模块时,可以在XDC文件中约束一下异步时钟路径,约束语法如下:

    set_false_path -to [get_cells -hierarchical -filter {NAME =~ *data_sync_reg1}]
    

    三、使用Xilinx原语xpm_*

    xilinx强大的生态环境,给FPGA用户提供了许多库函数,其中包括用于异步信号同步化的XPM_CDC库,其中包括:
    在这里插入图片描述
    注意:
    XPM_CDC_SYNC_RSTXPM_CDC_ASYNC_RST不同,两个模块均用于复位的同步化,但XPM_CDC_ASYNC_RST输出的复位信号在断言时,与目标时钟域是异步的,释放是同步的;而XPM_CDC_SYNC_RST的复位断言和释放均与目标时钟域同步。

    以下为Verilog下XPM_CDC_*模块例化的模板:

    	//-----------------------------------------------------------//
    	// xpm_cdc_async_rst: Asynchronous Reset Synchronizer
    	//-----------------------------------------------------------//	
    	xpm_cdc_async_rst #(
    		.DEST_SYNC_FF		(4),
    		.INIT_SYNC_FF		(0),
    		.RST_ACTIVE_HIGH	(0)
    	)
    	xpm_cdc_async_rst_inst (
    		.src_arst			(power_reset	),
    		//-------------------------------------//
    		.dest_clk			(clk_300m		),	
    		.dest_arst			(sync_reset		)
    	);
    
    //----------------------------------------------//
    // xpm_cdc_single: Single-bit Synchronizer
    //----------------------------------------------//   
       xpm_cdc_single #(
    		.DEST_SYNC_FF		(4				), // DECIMAL; range: 2-10
    		.INIT_SYNC_FF		(0				), // DECIMAL; 0=disable simulation init values, 1=enable simulation init values
    		.SIM_ASSERT_CHK		(0				), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
    		.SRC_INPUT_REG		(1				)  // DECIMAL; 0=do not register input, 1=register input
       ) xpm_cdc_sync_inst0 (
    		.src_clk			(src_clk		),
    		.src_in				(src_in			),
    		//-------------------------------------//
    		.dest_clk			(dest_clk		),
    		.dest_out			(dest_out		)
       ); 
    
    //----------------------------------------------//
    // xpm_cdc_array_single: Single-bit Array Synchronizer
    //----------------------------------------------//    
    	xpm_cdc_array_single #(
    		.DEST_SYNC_FF		(4				),// DECIMAL; range: 2-10
    		.INIT_SYNC_FF		(0				),// DECIMAL; 0=disable simulation init values, 1=enable simulation init values
    		.SIM_ASSERT_CHK		(0				),// DECIMAL; 0=disable simulation messages, 1=enable simulation messages
    		.SRC_INPUT_REG		(1				),// DECIMAL; 0=do not register input, 1=register input
    		.WIDTH				(2				) // DECIMAL; range: 1-1024
    	)xpm_cdc_array_single_inst (
    		.src_clk			(src_clk		),
    		.src_in				(src_in			),
    		//-------------------------------------//
    		.dest_clk			(dest_clk		),   
    		.dest_out			(dest_out		)
    	);
    
    //----------------------------------------------//
    // xpm_cdc_handshake: Bus Synchronizer with Full Handshake
    //----------------------------------------------//
    	xpm_cdc_handshake #(
    		.DEST_EXT_HSK		(0				),// DECIMAL; 0=internal handshake, 1=external handshake
    		.DEST_SYNC_FF		(4				),// DECIMAL; range: 2-10
    		.INIT_SYNC_FF		(0				),// DECIMAL; 0=disable simulation init values, 1=enable simulation init values
    		.SIM_ASSERT_CHK		(0				),// DECIMAL; 0=disable simulation messages, 1=enable simulation messages
    		.SRC_SYNC_FF		(4				),// DECIMAL; range: 2-10
    		.WIDTH				(1				) // DECIMAL; range: 1-1024
    	)xpm_cdc_handshake_inst (
    		.src_clk			(src_clk		),//input 					
    		.src_send			(src_send		),//input
    		.src_in				(src_in			),//input
    		.src_rcv			(src_rcv		),//output
    		
    		.dest_clk			(dest_clk		),//output
    		.dest_req			(dest_req		),//output
    		.dest_out			(dest_out		),//output
    		.dest_ack			(dest_ack		),//input
       );
    
    展开全文
  • 今天看了跨时钟域信号处理,就总结一下,今天主要写一下快时钟域到慢时钟域处理,因为慢到快的比较简单,就通过常规的打拍操作就可完成。 1、为什么对跨时钟域信号进行处理跨时钟域信号,容易造成亚稳态,对...

    今天看了跨时钟域信号处理,就总结一下,今天主要写一下快时钟域到慢时钟域的处理,因为慢到快的比较简单,就通过常规的打拍操作就可完成。

    1、为什么对跨时钟域信号进行处理?

            跨时钟域信号,容易造成亚稳态,对设计危害较大。

    2、为什么不能直接和慢到快这种情况一样采用两级寄存器打拍的方式?

            快时钟域信号变化快,慢时钟域信号采样时容易造成采样丢失,或者直接采不到,例如对快时钟域的脉冲检测。如果不经特殊处理,极有可能就采不到信号。

            正如下图所示,由于aclk信号宽度较窄,使得bclk采样时,正好采到adat的下降沿上,容易造成亚稳态,如果aclk的频率再快一点,就会出现bclk采样不到的现象。

    3、如何处理这种跨时钟的单bit信号?

    •      对脉冲进行展开,通常遵循三时钟沿”要求,也就是要持续3个时钟沿以上(上升沿和下降沿都算)。这个被称为:“三时钟沿”要求。
    •     通过“握手”的方式来保证数据被采样到

                 如下图发送端信号会在任何时刻发生变化,接收端采样时,会出现采不到或者不满足时序要求,出现亚稳态,因此采用握手信号避免这种问题。

    • 下图就是采用握手信号的方式

             

              只需要对双方的握手信号(req和ack)分别使用脉冲检测方法进行同步。在具体实现中,假设req、ack、data总线在初始化时都处于无效状态,发送域先把数据放入总线,随后发送有效的req信号给接收域。接收域在检测到有效的req信号后锁存数据总线,然后回送一个有效的ack信号表示读取完成应答。发送域在检测到有效ack信号后撤销当前的req信号,接收域在检测到req撤销后也相应撤销ack信号,此时完成一次正常握手通信。此后,发送域可以继续开始下一次握手通信,如此循环。

              该方式能够使接收到的数据稳定可靠,有效的避免了亚稳态的出现,但控制信号握手检测会消耗通信双方较多的时间

    4、脉冲展宽的verilog实现及仿真结果

    module cdc(
    	input wire clka,
    	input wire rst_n,
    	input wire pulse_a,//a 时钟域的脉冲信号
    	input wire clkb,
    	output wire out_pulse,//b时钟域检测到的脉冲输出
    	output wire singal_out
    	);
    
    reg ext_pulse_a;
    reg [1:0] ext_pulse_b;
    reg [1:0] ext_pulse_a_b;
    reg [1:0] pos_pulse_b;//检测同步过来的pulse_b的上升沿
    
    assign singal_out = pos_pulse_b[1];
    
    //在a时钟域下对脉冲信号进行展宽
    always @(posedge clka or negedge rst_n)
    	if(!rst_n)
    		ext_pulse_a <= 1'b0;
    	else if(pulse_a)
    		ext_pulse_a <= 1'b1;
    	else if(ext_pulse_a_b[1])
    		ext_pulse_a <= 1'b0;
    	else 
    		ext_pulse_a <= ext_pulse_a;
    
    
    //将展宽信号同步到b时钟域
    always @(posedge clkb or negedge rst_n) begin
    	if (!rst_n) 
    		ext_pulse_b <= 2'b0;
    	else
    		ext_pulse_b <= {ext_pulse_b[0],ext_pulse_a}; 
    end
    
    //将ext_pulse_b同步回a
    always @(posedge clka or negedge rst_n) begin
    	if (!rst_n) 
    		ext_pulse_a_b <= 2'b0;
    	else
    		ext_pulse_a_b <= {ext_pulse_a_b[0],ext_pulse_b[1]};
    end
    
    
    
    //检测ext_pulse_b上升沿
    always @(posedge clkb or negedge rst_n) begin
    	if (!rst_n) 
    		pos_pulse_b <= 2'b0;
    	else
    		pos_pulse_b <= {pos_pulse_b[0],ext_pulse_b[1]}; 
    		
    end
    
    assign  out_pulse = (pos_pulse_b[0] & ~pos_pulse_b[1]);
    
    endmodule

    脉宽展开的tb文件

    `timescale 1ns/1ps
    module tb_cdc();
    
    reg clka;
    reg clkb;
    reg pulse_a;
    wire out_pulse;
    reg rst_n;
    wire singal_out;
    
    initial begin
    	clka =0;
    	clkb =0;
    	rst_n =0;
    	pulse_a =0;
    	#100
    	rst_n =1;
    	# 100;
    	pulse_a =1'b1;
    	#10;
    	pulse_a = 1'b0;	
    	#100;
    	pulse_a =1'b1;
    	#10;
    	pulse_a = 1'b0;	
    
    end
    
    always #5 clka =~clka;
    always #10 clkb = ~clkb;
    
    
    cdc cdc_inst(
    	.clka(clka),
    	.rst_n(rst_n),
    	.pulse_a(pulse_a),//a 时钟域的脉冲信号
    	.clkb(clkb),
    	.out_pulse(out_pulse),//b时钟域检测到的脉冲输出
    	.singal_out(singal_out)
    	);
    
    
    endmodule

    仿真结果:

    5、基于握手信号的verilog实现及仿真  

                 今天先写到这吧,改天补充

     

    展开全文
  • 单bit信号跨时钟域(1)

    千次阅读 多人点赞 2019-08-13 21:54:57
    单bit信号跨时钟域最为简单的方法就是通过寄存器打两拍进行同步,也就是所谓的电平同步器。给出电路图: 为了使同步器正常工作,从原时钟传来的信号应该先通过原时钟上的一个触发器,以消除所带的毛刺,而后不经过...
  • 这篇文章可能帮助您:1、了解什么是跨时钟域设计(CDC);2、如何进行单bit信号跨时钟域传输。
  • CDC单bit数据跨时钟域处理(慢到快&&快到慢) 一.慢时钟域到快时钟域 1.1 基础知识点 ------后者为本时钟域,从慢时钟域来的信号是本时钟域的异步信号;慢到快首先能够保证慢时钟的脉冲序列或电平能够被快时钟采到,...
  • 文章目录影响单bit信号的...不同时钟域下的信号传递就涉及到跨时钟域信号处理,因为相互之间的频率、相位不一样,如果不做处理或者处理不当,如下图所示的时钟域CLK_A的数据信号A可能无法满足时钟域CLK_B的setup/hol
  • 之所以需要进行数字信号跨时钟域处理,主要是因为当信号进入异步时钟域时,如果信号进行跳变的时刻处于异步时钟域中触发器的建立时间和保持时间内,触发器无法确定采集到的信号究竟是高还是低,所以输出端会出现不...
  • 2 握手同步 场景:带en脉冲信号的多比特数据做跨时钟域 本质上和bit握手同步一样,A_EN和B_EN就是单bit信号。当B_EN同步之后,Data也就同步了。不同之处在于CLKB的ACK信号由B2_q换成了下图中的ACK,显然是因为...
  • 跨时钟域信号处理(一)--Verilog比特信号

    万次阅读 多人点赞 2019-03-16 16:19:31
    网上有很多的跨时钟域信号处理的相关文章,主要分为三种: 比特信号--打两拍或打更多拍(使用触发器); 多比特信号--异步双口块RAM或者异步FIFO; 格雷码转换。 这次就主要说第1种情况,适用于单比特信号。 1...
  • 1、前言 常用的多bit信号跨时钟域处理方法有两种: ①使用异步FIFO进行数据同步。 ②采用握手方式进行数据同步。
  • 这篇文章可能帮助您:1、了解什么是跨时钟域设计(CDC);2、如何进行多bit信号跨时钟域传输。
  • 单bit信号跨时钟域

    2021-08-17 22:51:26
    单bit信号跨时钟域 1.电平同步器 单bit信号跨时钟域最为简单的方法就是通过寄存器打两拍进行同步,也就是所谓的电平同步器。给出电路图: 为了使同步器正常工作,从原时钟传来的信号应该先通过原时钟上的一个触发器...
  • 单bit信号跨时钟域(2)

    千次阅读 2019-08-15 16:48:03
    上篇文章中,我们基本了解了单bit信号跨时钟域的三种同步器,在最后一种脉冲同步器中,实现了要求较为苛刻的从慢时钟域到快时钟域的跨越,并输出了与新时钟周期等宽的脉冲信号。但在功能仿真中可以看到,要跨越时钟...
  • 跨时钟域处理比特信号(1) 1.跨时钟域的基本概念: 比特信号需要从时钟域a同步到时钟域b中,由于ab时钟域的时钟可能不同,就需要进行跨时钟域处理。 亚稳态: 每一个触发器都有其规定的建立(setup)和保持...
  • 首先使用快时钟对数据进行两级采样同步,之后对得到的长信号进行边沿检测,得到长为一个快时钟周期的高电平信号。 代码如下: module slow2fast_EdgeDetect( input wire clk_slow, input wire clk_fast, input ...
  • 比特信号跨时钟域

    2021-03-18 22:23:33
    Signal_a是clka(300M)时钟域的一个时钟脉冲信号,如何将其同步到时钟域clkb(100M)中,并产生出Signal_b同步脉冲信号。请用Verilog代码描述,并画出对应的时序波形图说明图。(大疆FPGA逻辑岗A卷) 分析: 一...
  • 讲述在IC设计中,跨时钟域信号同步方法6种
  • 单bit跨时钟域实现总结一、概述二、跨时钟域时序图三、verilog HDL实现代码及关键点(见代码注释)四、增加了握手机制五、实现过程 一、概述 在网上看到一篇单bit跨时钟域的verilog HDL实现代码,为便于以后查看归纳...
  • 跨时钟域电路设计——多bit信号&FIFO

    千次阅读 2020-04-16 19:43:15
    多个bit信号跨时钟域仅仅通过简单的同步器同步时不安全的。
  • FPGA跨时钟域处理方法

    2021-07-17 20:19:16
    前提条件是 快时钟域到慢时钟域,原因有两个,1)只有快时钟域到慢时钟域,才能保证慢时钟域的脉冲信号能被快时钟域采样到。2)两级寄存器的主要作用是消除亚稳态(不能完全消除亚稳态,但可以使亚稳态出现的概率...
  • 如上图,慢时钟下一个有效脉冲的最短周期为慢时钟的一个周期,站在快时钟的角度下,这个慢时钟域信号会在快时钟域下持续很多个周期。实际上,这个脉冲在慢时钟域只发生了一次,所以如果用快时钟去检查有效脉冲的.....
  • 文章目录比特信号跨时钟域传输1、时钟域2、亚稳态3、多级寄存器处理3.1 信号从B到A(慢到快)3.2 信号从A到B(快到慢) 比特信号跨时钟域传输 参考链接:...
  • 经典跨时钟域同步电路 各种异步处理 值得推荐
  • 1.什么是亚稳态? 触发器无法在某一个规定时间段内产生一个确定的状态。 原因:由于触发器的建立时间和保持时间不满足,当触发器进入亚稳态,使得无法预测该...(4)改善时钟质量,用边沿变化快速的时钟信号消除;
  • (大疆2020数字芯片)下列关于多bit数据跨时钟域处理思路,错误的有() A. 发送方给出数据,接收方用本地时钟同步两拍再使用; B. 发送方把数据写到异步fifo,接收方从异步fifo里读出; C. 对于连续变化的信号,...
  • 我们假定有两个时钟,CLK1 和 CLK2,还有一个信号叫 READ,CLK1 时钟频率快于 CLK2,现在我们需要将READ 信号同步到CLK2时钟域下。 1、方法一:展宽+打拍同步 READ_DLY1 信号是 READ 信号相对于 CLK1 时钟打一拍产生...
  • 跨时钟域单bit握手协议代码如下: ```haskell ```perl ```rust module handshake( input clk_1,//快时钟域 5ns一个周期 input clk_2,//慢时钟域 12ns一个周期 input rst_n,//低复位 input d_in,//快时钟域单...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,603
精华内容 3,441
关键字:

单bit信号跨时钟域处理

友情链接: Mobile Shop Management.rar