跨时钟域数据同步

跨时钟信号直接传输在信号跳变时违背本地时钟域的时序要求(建立时间约束,保持时间约束),容易产生亚稳态,无法确定亚稳态何时结束以及结束时保持在何种状态上。

用同步器抑制亚稳态的往下传播的概率,根据情况的不同需要不同的同步器,大致情况如下所示:

  • 跨同步时钟域下,快时钟域到慢时钟域 的控制信号传输;
  • 跨同步时钟域下,慢时钟域到块时钟域 的控制信号传输;
  • 跨同步时钟域下,快时钟域到慢时钟域 的数据信号传输;
  • 跨同步时钟域下,慢时钟域到块时钟域 的数据信号传输;
  • 跨异步时钟域下,快时钟域到慢时钟域 的控制信号传输;
  • 跨异步时钟域下,慢时钟域到块时钟域 的控制信号传输;
  • 跨异步时钟域下,快时钟域到慢时钟域 的数据信号传输;
  • 跨异步时钟域下,慢时钟域到块时钟域 的数据信号传输;

慢时钟域到快时钟域

理论上讲,快时钟域的信号总会采集到慢时钟域传输来的信号,如果存在异步可能会导致采样数据出错,所以需要进行同步处理。此类同步处理相对简单,一般采用延迟打拍法,或延迟采样法。

延迟打拍法(电平同步)

最常用的同步方法是双级触发器缓存法,俗称延迟打拍法,“打两拍法”。异步信号从一个时钟域进入另一个时钟域之前,将该信号用两级触发器连续缓存两次,可有效降低因为时序不满足而导致的亚稳态问题。电路示意图如下。

一般设计中使用两级触发器进行缓存即可满足设计时序需求。大量实验表明,三级触发器缓存可解决 99% 以上的此类异步时序问题。

两级触发器延迟打拍并检测信号上升沿的 Verilog 描述如下:

module delay_clap(
    input       clk1,  //异步慢时钟
    input       sig1,  //异步信号

    input       rstn,  //复位信号
    input       clk2,  //目的快时钟域市政
    output      sig2); //快时钟域同步后的信号

   reg [2:0]    sig2_r ;   //3级缓存,前两级用于同步,后两节用于边沿检测
   always @(posedge clk2 or negedge rstn) begin
     if (!rstn) sig2_r  <= 3'b0 ;
     else       sig2_r  <= {sig2_r[1:0], sig1} ;  //缓存
   end
   assign sig2 = sig2_r[1] && !sig2_r[2] ; //上升沿检测

如果两个时钟的频率相差较小,可能还需要对数据进行延迟缓存,以保证采集到的是当拍时钟的数据;

延迟采样法(脉冲同步器)

此方法主要针对多位宽的数据传输

例如当两个异步时钟频率比为 5 时,可以先用延迟打拍的方法对数据使能信号进行 2 级打拍缓存,然后再在快时钟域对慢时钟域的数据信号进行采集。

该方法的基本思想是保证信号被安全采集的时刻,而不用同步多位宽的数据信号,可节省部分硬件资源。对应慢时钟域到块时钟域 的控制信号传输

利用打拍的方法进行延迟采样的 Verilog 描述如下。

//同步模块工作时钟为 100MHz 的模块
//异步数据对来自工作时钟为 20MHz 的模块
module delay_sample(
    input               rstn,
    input               clk1,
    input [31:0]        din,
    input               din_en,

    input               clk2,
    output [31:0]       dout,
    output              dout_en);

   //sync din_en
   reg [2:0]    din_en_r ;
   always @(posedge clk2 or negedge rstn) begin
     if (!rstn) din_en_r  <= 3'b0 ;
     else       din_en_r  <= {din_en_r[1:0], din_en} ;
   end
   wire din_en_pos = din_en_r[1] && !din_en_r[2] ;

   //sync data
   reg [31:0]           dout_r ;
   reg                  dout_en_r ;
   always @(posedge clk2 or negedge rstn) begin
      if (!rstn)
        dout_r         <= 'b0 ;
      else if (din_en_pos)
        dout_r         <= din ;
   end
   //dout_en delay
   always @(posedge clk2 or negedge rstn) begin
      if (!rstn)        dout_en_r      <= 1'b0 ;
      else              dout_en_r      <= din_en_pos ;
   end
   assign       dout    = dout_r ;
   assign       dout_en = dout_en_r ;

endmodule

该方法时序结果图如下所示。

显然,在 clk2 时钟域,t2 时刻对数据进行采样缓存比 t1 时刻要安全的多。

但如果慢时钟域没有数据使能信号 din_en, 或数据使能信号一直有效,此时在快时钟域对数据使能信号进行上升沿检测的方法将会失效。因为数据使能信号一直有效,除了第一个数据,快时钟域将无法检测到后继数据的传输时刻。

解决方法就是,增加控制信号。

快时钟域到慢时钟域

信号从快时钟域传输到慢时钟域来时,需要根据信号的特点来进行同步处理。对于单 bit 信号,一般可按电平信号和脉冲信号来区分。

电平信号同步

同步逻辑设计中,电平信号是指长时间保持不变的信号。保持不变的时间限定是相对于慢时钟而言的。只要快时钟的信号保持高电平或低电平的时间足够长,以至于能被慢时钟在满足时序约束的条件下采集到,就可以认为该信号为电平信号。

既然电平信号能够被安全的采集到,所以从快时钟域到慢时钟域的电平信号也采用延迟打拍的方法做同步。

脉冲信号同步

同步逻辑设计中,脉冲信号是指从快时钟域输出的有效宽度小于慢时钟周期的信号。如果慢时钟域直接去采集这种窄脉冲信号,有可能会漏掉。

假如这种脉冲信号脉宽都是一致的,在知道两个时钟频率比的情况下,可以采用"快时钟域脉宽扩展(可选项)+慢时钟域延迟打拍"的方法进行同步。

具体思路,如果能够让同步于快速时钟域clka下的脉冲信号Signal_a变长到可以让慢速时钟域clkb检测到这个问题,就可以完美解决了。所以先将快速时钟域clka下的脉冲信号Signal_a,在快速时钟域clka的作用下,变为沿信号,产生一个名为src_state的中间变量来作为脉冲信号Signal_a变成的沿信号。如下图所示,每当快速时钟域clka检测到Signal_a脉冲信号为高时,让src_state信号取反,使得Signal_a的第一个脉冲变为src_state信号的上升沿,Signal_a的第二个脉变为src_state信号的下降沿,后面如果Signal_a信号还有脉冲依然是变为src_state信号的上升沿和下降沿。

最后一步需要做的那就是将变为state_dly2信号的“沿”再转化为脉冲信号。这就需要引入了另一个新的知识——边沿检测。边沿检测主要作用是能够准确的识别出信号的上升沿或下降沿,也就是希望当上升沿或下降沿来临时,能够产生一个唯一标识上升沿或下降沿的脉冲信号来告诉上升沿或下降沿来了,然后再根据这个脉冲信号启动下一级操作。如下图所示,对同一信号打一拍后在①位置处检测到上升沿,拉高一个时钟的脉冲;在②位置处检测到下降沿,拉高一个时钟的脉冲。边沿检测通常是两级寄存器缓存然后异或可以实现。

由前面的分析知道src_dtate信号在慢速时钟域clkb的采样下得到的state_dly1信号可能是不稳定的,而state_dly2信号是稳定的,不能直接用state_dly1和state_dly2来产生沿标志信号,因为state_dly1的不稳定性可能会导致产生的下降沿标志信号也不稳定,所以需要将state_dly2信号再打一拍,产生dst_state信号,用state_dly2信号和dst_state信号产生上升沿和下降沿标志信号还原脉冲,这就是为什么看到一共打了三拍的原因。还原后的波形如下所示

RTL代码如下所示:

module fast_to_slow(
     input  wire   clka       ,   //sourceclock
      input  wire   src_rst_n   , //sourceclock reset (0:reset)
      input  wire   Signal_a   ,   //sourceclock pulse in
      input  wire   clkb       ,   //destinationclock
      input  wire   dst_rst_n  ,   //destinationclock reset (0:reset)
    
      outputwire   Signal_b       //destinationpulse out
);

reg     src_state   ;
reg     state_dly1  ;
reg     state_dly2  ;
reg     dst_state   ;
 
//将脉冲信号转化为沿信号
always@(posedge clka ornegedge src_rst_n)
     if(src_rst_n ==1'b0)
         src_state<=1'b0;
     elseif(Signal_a ==1'b1)
         src_state<=~src_state;
 
  //将展宽的脉冲打三拍
always@(posedge clkb ornegedge dst_rst_n)
     if(dst_rst_n ==1'b0)begin
        state_dly1 <=1'b0;
         state_dly2 <=1'b0;
         dst_state  <=1'b0;
     end              
     elsebegin    
         state_dly1 <= src_state;
         state_dly2 <= state_dly1;
         dst_state  <= state_dly2;
     end
 
//上升沿和下降沿同时检测
assign Signal_b = dst_state ^ state_dly2;

endmodule

其实在使用的这种脉冲同步法来解决单比特信号从快速时钟域同步到慢速时钟域的问题是有一定缺陷的,比如输入脉冲的间隔至少是两个同步器时钟周期,这个时候就需要对沿信号进行展宽。

握手信号同步

如果有时窄脉冲信号又表现出电平信号的特点,即有时信号的有效宽度大于慢时钟周期而能被慢时钟采集到,那么对此类信号再进行脉冲扩展显然是不经济的。此时,可通过"握手传输"的方法进行同步。

假设脉冲信号的高电平期间为有效信号期间,其基本原理如下。

  • (1) 快时钟域对脉冲信号进行检测,检测为高电平时输出高电平信号 pulse_fast_r。或者快时钟域输出高电平信号时,不要急于将信号拉低,先保持输出信号为高电平状态。
  • (2) 慢时钟域对快时钟域的信号 pulse_fast_r 进行延迟打拍采样。因为此时的脉冲信号被快时钟域保持拉高状态,延迟打拍肯定会采集到该信号。
  • (3) 慢时钟域确认采样得到高电平信号 pulse_fast2s_r 后,再反馈给快时钟域。
  • (4) 快时钟域对反馈信号 pulse_fast2s_r 进行延迟打拍采样。如果检测到反馈信号为高电平,证明慢时钟域已经接收到有效的高电平信号。如果此时快时钟域自身逻辑不再要求脉冲信号为高电平状态,拉低快时钟域的脉冲信号即可。

此方法实质是通过相互握手的方式对窄脉冲信号进行脉宽扩展。

利用握手信号进行同步处理的 Verilog 模型描述如下。

//同步模块工作时钟大约为 25MHz 的模块
//异步数据对来自工作时钟为 100MHz 的模块
module pulse_syn_fast2s
  #( parameter          PULSE_INIT = 1'b0
   )
  (
   input                rstn,
   input                clk_fast,
   input                pulse_fast,
   input                clk_slow,
   output               pulse_slow);

   wire                 clear_n ;
   reg                  pulse_fast_r ;
   /**************** fast clk ***************/
   //(1) 快时钟域检测到脉冲信号时,不急于将脉冲信号拉低
   always@(posedge clk_fast or negedge rstn) begin
        if (!rstn)
           pulse_fast_r  <= PULSE_INIT ;
        else if (!clear_n)
           pulse_fast_r  <= 1'b0 ;
        else if (pulse_fast)
           pulse_fast_r  <= 1'b1 ;
   end

   reg  [1:0]           pulse_fast2s_r ;
   /************ slow clk *************/
   //(2) 慢时钟域对信号进行延迟打拍采样
   always@(posedge clk_slow or negedge rstn) begin
      if (!rstn)
        pulse_fast2s_r     <= 3'b0 ;
      else
        pulse_fast2s_r     <= {pulse_fast2s_r[0], pulse_fast_r} ;
   end
   assign pulse_slow = pulse_fast2s_r[1] ;

   reg [1:0]            pulse_slow2f_r ;
   /********* feedback for slow clk to fast clk *******/
   //(3) 对反馈信号进行延迟打拍采样
   always@(posedge clk_fast or negedge rstn) begin
      if (!rstn)
        pulse_slow2f_r  <= 1'b0 ;
      else
        pulse_slow2f_r  <= {pulse_slow2f_r[0], pulse_slow} ;
   end
   //控制快时钟域脉冲信号拉低
   assign clear_n = ~(!pulse_fast && pulse_slow2f_r[1]) ;

endmodule

仿真结果如下,由图可知:

  • (1) 快时钟域单个窄脉冲信号被慢时钟域采集到,但是同步后的信号延迟较长,脉冲宽度较大。信号延迟是因为延迟打拍和反馈清零决定的,无法避免。脉宽过大问题,可以通过延迟打拍进行边沿检测的方法处理。

  • (2) 两个紧临的窄脉冲信号同步后的信号脉宽与单个窄脉冲同步后的信号脉宽没有差异,也就是说,同步电路漏掉了第二个窄脉冲的检测。这也属于握手传输处理同步问题的特点,当快时钟域的脉冲信号变化速率过快时,该方法不能分辨相邻的脉冲。

  • (3) 当多个宽窄脉冲信号相邻较近时,虽然该同步方法不能分辨多个脉冲信号,但同步后的信号脉宽可能会相对大一些。

多位宽数据同步

当多位宽数据进行同步时,如果该数据各 bit 位都可以看作电平信号,即相对一段时间内各 bit 位数据均可以保持不变以至于能被慢时钟采集到,可以消耗一些触发器资源对多位宽数据进行简单的延迟打拍同步

如果是少量多位宽数据,使用握手信号同步或者展宽信号+脉冲信号同步的方式传输控制信号也是可以实现的。

但如果数据变化速率过快,就不能再使用延迟打拍采样的方法。因为此时数据各 bit 位不再是电平信号,变化的时间也参差不齐,用异步时钟进行打拍采样,可能会采集到因路径延迟不同而导致的错误数据。

解决此类异步问题的常用方法是采用异步 FIFO (First In First Out)。

除此之外,也可以进行分时读写(乒乓操作),

基本原理就是有两个存储单元,比较常用的存储单元为双口RAM(Dual RAM),SRAM,SDRAM,FIFO等。第一个存储周期对第一个存储单元进行写操作,第二个存储周期对第二个存储单元进行写操作,并与此同时对第一个存储单元进行读操作。第三个存储周期对第一个存储单元进行写操作,并对第二个存储单元进行读操作,循环往复。

乒乓操作的优点:

通过“输入数据选择单元”和“输出数据选择单元”按节拍、相互配合的切换,将经过缓冲的数据流没有停顿地送到“数据流运算处理模块”进行运算与处理。把乒乓操作模块当做一个整体,站在这个模块的两端看数据,输入数据流和输出数据流都是连续不断的,没有任何停顿,因此非常适合对数据流进行流水线式处理。所以乒乓操作常常应用于流水线式算法,完成数据的无缝缓冲与处理。

写数据的时钟远慢于读时钟,可以只使用一个存储单元,例如写时钟为10MHz,读时钟为100MHz,每当写入10个数据时,读已经可以读出100个数据了,此时就可以使用一个深度为128的FIFO,读写双方各自计数。我们保持写操作持续不断,每当写数据计数到100时,便开始读数据100个,当读完后便等待下一次写数据计数到100,此时最多同时占用110的深度,仍还有18个空余位置,所以读写操作不会产生冲突导致写数据时产生拥塞,导致数据丢失的问题,其实就等同于乒乓操作中的两个存储单元在同一FIFO中。

参考:IC设计中的多时钟域处理方法总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/24362.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

H3C IPSec IKE野蛮模式

这里使用H3C模拟器。 H3C IPSec IKE野蛮模式&#xff0c;又称为IKE Main Mode&#xff0c;主要是在第一阶段&#xff08;Phase 1&#xff09;的过程中提供身份保护。它主要用于VPN隧道建立过程中的密钥交换。以下是配置步骤&#xff1a; 创建IKE提案&#xff1a; system-view…

QT圆形进度条(QT桌面项目光照强度检测)

文章目录 前言一、编程思路二、核心代码实现总结 前言 本篇文章我们讲解QT实现圆形进度条&#xff0c;并实现动态的效果。 一、编程思路 实现QT圆形进度条其实是非常简单的&#xff0c;思路就是画两个圆弧。 这里大家就会觉得很奇怪了为什么画两个圆弧就能实现圆形进度条了呢…

轻NAS搭建 - 使用微力同步搭建私人云盘,无需公网IP也能远程访问

文章目录 1.前言2. 微力同步网站搭建2.1 微力同步下载和安装2.2 微力同步网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 私有云盘作为云存储概念的延伸&#xff0c;虽然谈不上多么新颖&#xff0c;但是其…

华为OD机试之不含101的整数(Java源码)

不含101的数 题目描述 小明在学习二进制时&#xff0c;发现了一类不含 101的数&#xff0c;也就是&#xff1a; 将数字用二进制表示&#xff0c;不能出现 101 。 现在给定一个整数区间 [l,r] &#xff0c;请问这个区间包含了多少个二进制不含 101 的整数&#xff1f; 输入描述…

2023全球最佳医院榜单及简要介绍

作为医学类的访问学者、博士后及联合培养博士们&#xff0c;都希望到世界知名医院进行临床研修交流及科研学习。2023 年世界最佳医院排行榜的发布为申请者提供了目标平台&#xff0c;现知识人网小编整理刊出。 近期&#xff0c;《新闻周刊》和全球数据公司 Statista 推出了2023…

Vue之MVVM模型

文章目录 前言一、简说MVVM模型二、走进MVVM总结 前言 Vue的创建者在创建Vue时没有完全遵守MVVM&#xff08;一种软件架构模式&#xff09;&#xff0c;但是Vue的设计受到了他它的启发。这也是为什么经常用vm&#xff08;ViewModel的缩写&#xff09;这个变量名表示Vue实例。 …

操作系统第三章——内存管理(中)

九月重楼二两&#xff0c;冬至蝉蜕一钱&#xff0c;煎入隔年雪煮沸&#xff0c;可治人间相思苦疾&#xff0c; 可是&#xff0c;重楼七叶一花&#xff0c;冬日何来蝉蜕&#xff0c;原是相思无解 殊不知 夏枯即为九叶重楼&#xff0c;掘地三尺寒蝉现&#xff0c;除夕子时雪&…

non-protected broadcast场景分析及解决

non-protected broadcast场景分析及解决 在两个app之间互相送消息使用BroadcastReceiver&#xff0c;有时在运行过程中在logcat工具中会发现大片的飘红消息。 要消除这些错误信息&#xff0c;需要在广播的 Sender 和 Receiver 做部分的修改。 错误信息分析 由于 发送端 的 M…

`JOB`的正确打开方式

文章目录 JOB的正确打开方式 简介工作原理使用场景使用方式注意事项启动JOB失败的情况JOB正确打开方式错误方式正确方式进阶方式终极方式 总结 JOB的正确打开方式 最近有一些小伙伴在使用JOB时&#xff0c;由于使用不当&#xff0c;引起一些问题。例如把license占满&#xff0c…

操作系统第四章——文件管理(下)

竹本无心&#xff0c;却节外生枝&#xff0c;藕却有孔&#xff0c;但出淤泥而不染&#xff0c;人生如梦&#xff0c;却却不随人愿&#xff0c;万般皆是命&#xff0c;半点不由人 文章目录 4.1.5 逻辑结构VS物理结构4.1.6 文件的基本操作知识总览创建文件删除文件打开文件关闭文…

【弹性分布式EMA】在智能电网中DoS攻击和虚假数据注入攻击(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

GPC_APDU_Transport_over_SPI-I2C_v1.0_PublicRelease

GPC_APDU_Transport_over_SPI-I2C_v1.0_PublicRelease.pdf 目录 1 简介 越来越多的设备&#xff0c;如移动设备、可穿戴设备或其他 IoT&#xff08;物联网&#xff09;设备现在正在使用焊接安全元件 (SE)。 这产生了支持 SPI 或 I2C 等物理接口的新需求&#xff0c;以代替以前…

Java 反序列化漏洞

反序列化漏洞是指程序在反序列化期间&#xff0c;通过特殊的调用链引发的一系列安全问题。编程语言中只要存在序列化&#xff0c;反序列化功能就可能存在反序列化的安全问题。这里只针对Java和PHP进行讨论。 序列化漏洞概述 序列化的存在主要是为了存储和传输&#xff0c;将这…

如何设置工业设备的振动监测阈值

工业设备的振动阈值设置是确保设备正常运行和及时维护的关键步骤。本文将介绍一些常见的方法和策略&#xff0c;帮助您正确设置工业设备的振动阈值。 1. ISO 10816 振动烈度表格&#xff1a; ISO 10816 是一项国际标准&#xff0c;提供了设备振动水平的参考值。该标准将设备按…

【移动计算技术(Android)】期末复习

目录 选择题 选择题知识点汇总 Activity Intent Broadcast BroadcastReceiver 如何自定义Receiver 如何注册接收器 Service SharedPreferences 三种访问模式 如何创建 如何存储/修改 如何读取 内部存储 openFileOutput openFileInput SD卡 资源文件 SQLite…

Java学习路线(13)——Collection集合类:List集合与Set集合

一、集合类体系结构 二、部分Collection类型对象 Collection集合特点 List系列集合是有序、可重复、有索引。 ArrayList&#xff1a;有序、可重复、有索引LinkedList&#xff1a;有序、可重复、有索引 Set系列集合是无序、不重复、无索引。 HashSet&#xff1a;无序、不重复…

下载YouTube视频的一种方法

文章目录 工具名称下载方法使用方法1.只下载音频2.下载音频转换成mp3&#xff08;加上-x –audio-format参数&#xff09;3.下载视频&#xff08;带音频&#xff09;ID&#xff1a;22 | EXT&#xff1a;mp4 | 1280*720 下载的数据集&#xff1a;YouCook2 工具名称 yt-dlp 下载…

ajax使用

说明&#xff1a;ajax是一门异步处理请求的技术&#xff1b;可以实现不重新加载整个页面的情况下&#xff0c;访问后台后服务&#xff1b;比如百度搜索引擎&#xff0c;输入关键字后&#xff0c;下面会实时出现待选项&#xff0c;这就是一种异步处理请求的技术。 原生Ajax 原…

chatgpt赋能python:Python中未定义变量的默认值

Python中未定义变量的默认值 在Python编程中&#xff0c;有时候我们会使用未经定义的变量。如果这些变量没有被定义&#xff0c;那么它们将没有任何值。在这篇文章中&#xff0c;我们将讨论Python中未定义变量默认值的问题&#xff0c;并深入研究为什么这些默认值如此重要。 …

如何保证三个线程按顺序执行?不会我教你

&#x1f468;‍&#x1f393;作者&#xff1a;bug菌 ✏️博客&#xff1a;CSDN、掘金、infoQ、51CTO等 &#x1f389;简介&#xff1a;CSDN|阿里云|华为云|51CTO等社区博客专家&#xff0c;历届博客之星Top30&#xff0c;掘金年度人气作者Top40&#xff0c;51CTO年度博主Top12…