FPGA学习笔记——跨时钟域(CDC)设计之单bit信号同步

FPGA学习笔记——跨时钟域(CDC)设计

  跨时钟域(Clock Domain Crossing,CDC)是指设计中存在着两个或两个以上异步时钟域,跨时钟域设计问题目前是逻辑设计者经常面临的问题,解决这类问题的方法被称为CDC技术,即跨时钟域技术。
  在跨时钟域边界传递信号时,可能出现两种情况,确定属于哪种情况对设计非常重要:
  (1).允许在时钟域之间传递时丢失数据。
  (2).必须对在时钟域之间传递的每个信号进行采样。
  第一种情况:有时不需要对每个值进行采样,但采样值必须准确。一个例子是标准异步FIFO设计中使用的格雷码计数器集。在适当设计的异步FIFO模型中,同步格雷码计数器不需要捕获来自相反时钟域的每个合法值,但至关重要的是,采样值必须准确,以识别何时发生满和空情况。
  第二种情况:在允许对CDC信号进行更改之前,必须正确识别或识别并确认CDC信号。
  在这两种情况下,CDC信号将需要某种形式的同步进入接收时钟域。
  异步信号的跨时钟域同步问题。一般分为单bit的控制信号同步,以及多bit的数据信号同步。多bit的信号同步会使用保持寄存器和握手或异步FIFO完成,而单bit的信号同步,又是时钟无缝切换电路以及异步FIFO电路的设计基础,这里先介绍单bit信号同步处理。

单比特信号同步

一、电平同步器

  最常见的同步器就是使用两级寄存器,即使用寄存器打两拍的方式进行同步,也就是所谓的电平同步器。如下图所示
在这里插入图片描述
  在电平同步器中,跨时钟域的信号在接收域中要保持高电平或低电平两个时钟周期以上。同步之后的信号是电平的形式,而该电平所维持的时钟周期个数是其在跨时钟域期间被上升沿检测到的次数。每次同步完,输入信号要恢复到无效状态。所以,如果是从快到慢,信号很有可能被滤除。适用于慢时钟域向快时钟域。
在这里插入图片描述
  两级触发器可防止亚稳态传播的原理:假设第一级触发器的输入不满足其建立保持时间,它在第一个脉冲沿到来后输出的数据就为亚稳态,那么在下一个脉冲沿到来之前,其输出的亚稳态数据在一段恢复时间后必须稳定下来,而且稳定的数据必须满足第二级触发器的建立时间,如果都满足了,在下一个脉冲沿到来时,第二级触发器将不会出现亚稳态,因为其输入端的数据满足其建立保持时间。
  更确切地说,输入脉冲宽度必须大于同步时钟周期与第一级触发器所需的保持时间之和。最保险的脉冲宽度是两倍同步时钟周期。 所以,这样的同步电路对于从较慢的时钟域来的异步信号进入较快的时钟域比较有效,对于进入一个较慢的时钟域,则没有作用。
  当然,仍然有可能级联的第二个寄存器输出还会表现为非稳定状态,但是这种双寄存同步器已经可以解决大部分这类亚稳态问题。总的来讲,就是一级概率很大,三级改善不大。如果再加上第三级寄存器,由于第二级寄存器对于亚稳态的处理已经起到了很大的改善作用,第三级寄存器在很大程度上可以说只是对于第二级寄存器的延拍,所以意义是不大的。
在设计这种同步器的时候应当注意遵循以下原则:
1.级联的寄存器必须使用同一个采样时钟。
2.发送端时钟域寄存器输出和接收端异步时钟域级联寄存器输入之间不能有任何其他组合逻辑。
3.同步器中级联的寄存器中除了最后一个寄存器外所有的寄存器只能有一个扇出,即其只能驱动下一级寄存器的输人。

电平同步器代码

module    Level_Sync(Clk_fast, Clk_slow,Rst_n, Data_in,Data_out);

    /********************参数定义********************/

    /*********************IO 说明********************/

	input    wire        Clk_slow  ;//发送域时钟
	input    wire        Clk_fast  ;//接收域时钟
	input    wire        Rst_n ;    //异步复位
	input    wire        Data_in;   //发送域数据输入
	output   reg         Data_out;  //接收域数据输出
	/********************** 内部信号声明 **********************/   
    reg   Data_in_Q;
	reg   Data_out_Q;

	/*************************功能定义*************************/

	always@(posedge Clk_slow or negedge Rst_n)
	begin
	    if(!Rst_n)
		    Data_in_Q <= 1'b0;
      	else 
		    Data_in_Q <= Data_in;
	end

	always@(posedge Clk_fast or negedge Rst_n) 
    begin
        if(!Rst_n)
		begin
		    Data_out_Q <= 1'b0;
			Data_out <= 1'b0;
		end
		else
		begin
		    Data_out_Q <= Data_in_Q;
			Data_out <= Data_out_Q;
		end
    end	
endmodule

二、边沿同步器

  边沿检测同步器在电平同步器的输出端增加了一个触发器和逻辑门,如下图所示。
在这里插入图片描述

在这里插入图片描述

  新增触发器的输出经反相后和电平同步器的输出进行与操作。这一电路会检测同步器输入的上升沿,产生一个与时钟周期等宽、高电平有效的脉冲。如果将与门的两个输入端交换使用,就可以构成一个检测输入信号下降沿的同步器。将与门改为与非门可以构建一个产生低电平有效脉冲的电路。
  边沿同步器与电平同步器类似,即输入脉冲的宽度必须大于同步时钟周期与第一个同步触发器所需保持时间之和。最保险的脉冲宽度是同步器时钟周期的两倍。如果输入是一个单时钟宽度脉冲进入一个较慢的时钟域,则这种同步器没有作用,在这种情况下,就要采用脉冲同步器。

边沿同步器代码

/* ======================== *\
*    Filename     : Edge_Sync.v
*    Author       : 你我山巅自相逢
*    Description  : 边沿同步器
*    Called by    :
*    Target Device:	EP4CE10F17C8
*    Tool versions:	Quartus Prime 19.1
*    Create Date  : 2022/5/3
*    Revision     : 1.0 
*    Email        : 
*    Company      : 
*    Copyright(c) 2022,
\* ========================= */

module    Edge_Sync(Clk_fast, Clk_slow,Rst_n, Data_in,Data_out);

    /********************参数定义********************/

    /*********************IO 说明********************/

	input    wire        Clk_slow  ;//发送域时钟
	input    wire        Clk_fast  ;//接收域时钟
	input    wire        Rst_n ;    //异步复位
	input    wire        Data_in;   //发送域数据输入
	output   wire        Data_out;  //边沿输出
	/********************** 内部信号声明 **********************/   
    reg   Data_in_Q;
	reg   Data_out_Q1;
    reg   Data_out_Q2;
	reg   Data_out_Q3;
	/*************************功能定义*************************/
    
	always@(posedge Clk_slow or negedge Rst_n)
	begin
	    if(!Rst_n)
		    Data_in_Q <= 1'b0;
      	else 
		    Data_in_Q <= Data_in;
	end

	always@(posedge Clk_fast or negedge Rst_n) 
    begin
        if(!Rst_n)
		begin
		    Data_out_Q1 <= 1'b0;
			Data_out_Q2 <= 1'b0;
			Data_out_Q3 <= 1'b0;
			
		end
		else
		begin
		    Data_out_Q1 <= Data_in_Q;
			Data_out_Q2 <= Data_out_Q1;
			Data_out_Q3 <= Data_out_Q2;
		end
    end	
	
	assign    Data_out = ~Data_out_Q3 & Data_out_Q2;    //检测上升沿
//	assign    Data_out = Data_out_Q3 & ~Data_out_Q2;    //检测下升沿
//	assign    Data_out = Data_out_Q3 ^  Data_out_Q2;    //检测下升沿和下降沿
endmodule

三、脉冲同步器

  脉冲同步器的基本功能是从某个时钟域取出一个单时钟宽度脉冲,然后在新的时钟域中建立另一个单时钟宽度的脉冲。如下图所示:
在这里插入图片描述
在这里插入图片描述
  脉冲同步器也有一个限制,即输入脉冲之间的最小间隔必须等于两个同步器时钟周期。如果输入脉冲相互过近,则新时钟域中的输出脉冲也紧密相邻,结果是输出脉冲宽度比一个时钟周期宽。
  当输入脉冲时钟周期大于两个同步器时钟周期时,这个问题更加严重。这种情况下,如果输入脉冲相邻太近,则同步器就不能检测到每个脉冲。

以牛客网问题为例: 从A时钟域提取一个单时钟周期宽度脉冲,然后在新的时钟域B建立另一个单时钟宽度的脉冲。A时钟域的频率是B时钟域的10倍;A时钟域脉冲之间的间隔很大,无需考虑脉冲间隔太小的问题。电路的接口如下图所示。data_in是脉冲输入信号,data_out是新的脉冲信号;clk_fast是A时钟域时钟信号,clk_slow是B时钟域时钟信号;rst_n是异步复位信号。
在这里插入图片描述
代码:

module    Pulse_Sync(Clk_fast, Clk_slow,Rst_n, Data_in,Data_out);

    /********************参数定义********************/

    /*********************IO 说明********************/

	input    wire        Clk_slow  ;//接收域时钟
	input    wire        Clk_fast  ;//发送域时钟
	input    wire        Rst_n ;    //异步复位
	input    wire        Data_in;   //发送域数据输入
	output   wire        Data_out;  //边沿输出
	/********************** 内部信号声明 **********************/   
    reg   Data_in_Q;
	reg   Data_out_Q1;
    reg   Data_out_Q2;
	reg   Data_out_Q3;
	/*************************功能定义*************************/
    /*脉冲信号转电平信号*/
	always@(posedge Clk_fast or negedge Rst_n)
	begin
	    if(!Rst_n)
		    Data_in_Q <= 1'b0;
      	else 
		    Data_in_Q <= Data_in? ~Data_in_Q:Data_in_Q;
	end
    
	/*电平信号打两拍再转为脉冲信号*/
	always@(posedge Clk_slow or negedge Rst_n) 
    begin
        if(!Rst_n)
		begin
		    Data_out_Q1 <= 1'b0;
			Data_out_Q2 <= 1'b0;
			Data_out_Q3 <= 1'b0;
			
		end
		else
		begin
		    Data_out_Q1 <= Data_in_Q;
			Data_out_Q2 <= Data_out_Q1;
			Data_out_Q3 <= Data_out_Q2;
		end
    end	
	
	assign    Data_out = Data_out_Q3 ^ Data_out_Q2;    
endmodule

四、总结

在这里插入图片描述
同步器设计推荐的做法:
同步器单独成模块,引入两个独立时钟
其他模块都设计为单一时钟模块,完全同步模块
以时钟域作为信号命名的前缀
静态时序分析的时候,对同步器模块异步输入信号的设定false path:
用通配符(.* 通配符,对相同名字自动匹配,属于systemverilog语法)

  • 19
    点赞
  • 150
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
FPGA自学笔记——设计与验证JMB FPGA(可编程逻辑门阵列)是一种可编程的硬件平台,可以实现各种数字电路的设计与验证。本文将简要介绍使用FPGA自学设计与验证JMB(低功耗、高效能、集成度高的多媒体芯片)的过程。 首先,我们需要了解JMB的功能和特性。JMB是一种面向多媒体应用的芯片,具备低功耗、高效能和高集成度的优势。我们需要详细研究JMB的硬件架构和内部模块,包括处理器核、存储器模块、图像和音频处理模块等。 接下来,我们可以使用FPGA开发板来设计和验证JMB。首先,我们需要熟悉FPGA设计工具,例如Vivado或Quartus等。这些工具提供了图形化界面和硬件描述语言(HDL)等设计方法。我们可以使用HDL编写JMB的功能模块,并将其综合为FPGA可执行的位流文件。 在设计完成后,我们需要验证JMB的功能和性能。我们可以使用仿真工具(例如ModelSim或ISE Simulator)来模拟JMB在不同情况下的行为。通过设计测试程序并运行仿真,我们可以验证JMB的各个模块是否正确地工作,是否满足设计要求。 在验证完成后,我们可以将位流文件下载到FPGA开发板中进行智能芯片的物理实现和测试。通过与外部设备的连接以及相关测试程序的运行,我们可以验证JMB在实际硬件中的功能和性能。 总结起来,学习FPGA设计与验证JMB,我们需要熟悉JMB的硬件架构和内部模块,并使用FPGA开发工具进行设计与验证。通过仿真和物理实现测试,我们可以验证JMB的功能和性能。这些过程需要理论知识和实践经验的结合,希望这些笔记能够给你提供一些参考和指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值