【CDC跨时钟域信号处理】单bit_快时钟域到慢时钟域

这篇具有很好参考价值的文章主要介绍了【CDC跨时钟域信号处理】单bit_快时钟域到慢时钟域。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

快时钟域到慢时钟域分两种情况:
1、允许采样丢失:直接采用同步器即可。
2、不允许采样丢失:原理是保证快时钟域的信号宽度满足一定的条件,使得慢时钟域有足够的时间采样到。
对于情况2有两种方法解决:①信号展宽+边沿检测②握手,且①比②要优先被选择。因为握手资源消耗较大,一般不用。

方法一:

脉冲信号展宽+边沿检测,脉冲信号转换成电平信号再进行边沿检测

  • 电路图:
    【CDC跨时钟域信号处理】单bit_快时钟域到慢时钟域
  • 代码:(verilog是描述电路的语言,所以要心中有电路,代码就好写了)
module pulse_detect(
    input              clk_fast    , 
    input              clk_slow    ,   
    input              rst_n       ,
    input               data_in     ,
    output           dataout
);
  reg data_in_fast;
  reg [2:0] data_slow;
  //将脉冲信号在快时钟域展平为电平信号。即展宽脉冲信号。在两次脉冲信号之间为电平信号。
  always@(posedge clk_fast or negedge rst_n)begin
      if(!rst_n)
          data_in_fast<= 0;
      else
          data_in_fast<= data_in ? (~data_in_fast) : data_in_fast;
  end
  //将展宽的脉冲信号在慢时钟域打两拍,并检测边沿。
  always@(posedge clk_slow or negedge rst_n)begin
      if(!rst)
          data_slow <= 3'b0;
      else
          data_slow <= {data_slow[1:0],data_in_fast};
  end   
  
  assign dataout = data_slow[2] ^ data_slow[1]; 
endmodule

  • 波形
    【CDC跨时钟域信号处理】单bit_快时钟域到慢时钟域

方法二

握手+边沿

  • 电路图:
    【CDC跨时钟域信号处理】单bit_快时钟域到慢时钟域
  • 代码1:
module pulse_detect(
  input         clk_fast  , 
  input         clk_slow  ,   
  input         rst_n    ,
  input        data_in    ,

  output         dataout
);
    //握手方式
    reg fast_req;//fast时钟域的请求信号
    reg slow_ack;//slow时钟域的应答信号
    reg [2:0] slow_req;//slow时钟域的请求信号
    reg [2:0] fast_ack;//fast时钟域的应答信号
    
    //fast时钟域
    
    //将slow时钟域的应答信号打三拍,送到fast时钟域
    always@(posedge clk_fast or negedge rst_n)begin
        if(!rst_n)
            fast_ack <= 3'd0;
        else
            fast_ack <= {fast_ack[1:0],slow_ack};
    end
    
    //生成请求信号fast_req
    always@(posedge clk_fast or negedge rst_n)begin
        if(!rst_n)
            fast_req <= 0;
        else if(data_in)
            fast_req <= 1'b1;
        else
            //快时钟域中没有输入数据时
            //如果慢时钟域应答了,01x,则快时钟域此时不请求,否则,快时钟域的请求信号维持上一时钟的状态
            fast_req <= ((fast_ack[1]) & (~fast_ack[2])) ? 1'b0 : fast_req;        
    end
    
    //slow时钟域
    
    //将fast时钟域的请求信号打三拍,送到slow时钟域
    always@(posedge clk_slow or negedge rst_n)begin
        if(!rst_n)
            slow_req <= 0;
        else
            slow_req <= {slow_req[1:0],fast_req};
    end
    
    //生成应答信号slow_ack
    always@(posedge clk_slow or negedge rst_n)begin
        if(!rst_n)
            slow_ack <= 0;
        else if(slow_req[1] & (~slow_req[2])) 
            //如果快时钟域的请求信号由0变为1,01x,即发出请求信号,则慢时钟域进行应答
            slow_ack <= 1'b1;
        else
            //如果slow请求信号10x,即慢时钟域请求信号无效时,慢时钟域不应答
            //否则慢时钟域应答信号不变
            slow_ack <= (slow_req[2]&(~slow_req[1])) ? 1'b0 : slow_ack;
    end
    //当慢时钟域01x,发出请求信号时,输出为1.
    assign dataout = (~slow_req[2]) & (slow_req[1]);
    
endmodule
  • 代码2:
module Sync_Pulse (
                input  src_clk,
                input  dst_clk,
                input  rst_n,
                input  src_pulse,
   
                output  dst_pulse
                  );
  
    reg req_state_dly1, req_state_dly2,dst_req_state,src_sync_req;
    reg ack_state_dly1,src_sync_ack;
    wire dst_sync_ack;
     
    always @ (posedge src_clk or negedge rst_n) begin
            if (rst_n == 1'b0)
                src_sync_req <= 1'b0;
            else if (src_pulse)           
                src_sync_req <= 1'b1;
            else if (src_sync_ack)           
                src_sync_req <= 1'b0;
            else;
     end
    
   
    always @ (posedge dst_clk or negedge rst_n) begin
            if (rst_n == 1'b0)
            begin
                req_state_dly1 <= 1'b0;
                req_state_dly2 <= 1'b0;
                dst_req_state <= 1'b0;
            end else begin
                req_state_dly1 <= src_sync_req;
                req_state_dly2 <= req_state_dly1;        
                dst_req_state <= req_state_dly2;
             end
    end
    
    assign dst_sync_ack = req_state_dly2;
    
    always @ (posedge src_clk or negedge rst_n) begin
            if (rst_n == 1'b0) begin
                    ack_state_dly1 <= 1'b0;
                    src_sync_ack <= 1'b0;
            end
            else begin
                     ack_state_dly1 <= dst_sync_ack;
                     src_sync_ack <= ack_state_dly1;
            end
     end
 
    assign  dst_pulse =   dst_req_state & (~req_state_dly2);
 
endmodule

对上述代码增加同步失败的指示信号

module handshake_pulse_sync
(
        input src_clk , //source clock
        input src_rst_n, //source clock reset (0: reset)
        input src_pulse , //source clock pulse in
       
        output src_sync_fail , //source clock sync state: 1 clock pulse if sync fail.
        input dst_clk , //destination clock
        input dst_rst_n , //destination clock reset (0:reset)
        output dst_pulse //destination pulse out
);
        //INTER DECLARATION        
        wire dst_pulse ;
        wire src_sync_idle ;
        reg src_sync_fail ;
        reg src_sync_req ;
        reg src_sync_ack ;
        reg ack_state_dly1, ack_state_dly2 ;
        reg req_state_dly1, req_state_dly2 ;
        reg dst_req_state ;
        reg dst_sync_ack ;
              
        assign src_sync_idle = ~(src_sync_req | src_sync_ack );
        
        //report an error if src_pulse when sync busy ;
        always @(posedge src_clk or negedge src_rst_n) begin
            if(src_rst_n == 1'b0)
                    src_sync_fail <= 1'b0 ;
            else if (src_pulse & (~src_sync_idle))
                    src_sync_fail <= 1'b1 ;
            else
                    src_sync_fail <= 1'b0 ;
        end
        
        
        //set sync req if src_pulse when sync idle ;
        always @(posedge src_clk or negedge src_rst_n) begin
                if(src_rst_n == 1'b0)
                        src_sync_req <= 1'b0 ;
                else if (src_pulse & src_sync_idle)
                        src_sync_req <= 1'b1 ;
                else if (src_sync_ack)
                        src_sync_req <= 1'b0 ;
        end
                
        always @(posedge src_clk or negedge src_rst_n) begin
                if(src_rst_n == 1'b0) begin
                        ack_state_dly1 <= 1'b0 ;
                        ack_state_dly2 <= 1'b0 ;
                        src_sync_ack <= 1'b0 ;
                end
                else begin
                        ack_state_dly1 <= dst_sync_ack ;
                        ack_state_dly2 <= ack_state_dly1 ;
                        src_sync_ack <= ack_state_dly2 ;
                end
        end
        
        always @(posedge dst_clk or negedge dst_rst_n) begin
                if(dst_rst_n == 1'b0) begin
                        req_state_dly1 <= 1'b0 ;
                        req_state_dly2 <= 1'b0 ;
                        dst_req_state <= 1'b0 ;
                end
                else begin
                        req_state_dly1 <= src_sync_req ;
                        req_state_dly2 <= req_state_dly1 ;
                        dst_req_state <= req_state_dly2 ;
                end
        end
        
        //Rising Edge of dst_state generate a dst_pulse;
        assign dst_pulse = (~dst_req_state) & req_state_dly2 ;
        //set sync ack when src_req = 1 , clear it when src_req = 0 ;
        
        always @(posedge dst_clk or negedge dst_rst_n) begin
                if(dst_rst_n == 1'b0)
                        dst_sync_ack <= 1'b0;
                else if (req_state_dly2)
                        dst_sync_ack <= 1'b1;
                else
                        dst_sync_ack <= 1'b0;
        end
endmodule

电路分析:
将src时钟域的脉冲信号打一拍之后,在dst时钟域内打三拍进行同步,其中第二拍的结果作为dst时钟域的应答信号,第二拍和第三拍的结果做边沿检测,以保证在dst时钟域输出接收到的脉冲信号。

其中第二拍的应答信号,在src时钟域经过两级同步作为src的应答信号,当输入脉冲信号时,src的请求信号有效。当src的应答信号有效时,请求信号无效。

缺点:上述操作无法检测到脉冲连续输入时产生的错误,即无法检测同步失败。如:在当前脉冲信号同步过程中又发出了新的脉冲信号的情况。

快时钟域至少展宽脉冲宽度到大于慢时钟域的周期长度。文章来源地址https://www.toymoban.com/news/detail-468440.html

到了这里,关于【CDC跨时钟域信号处理】单bit_快时钟域到慢时钟域的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数字信号处理8:利用Python进行数字信号处理基础

    我前两天买了本MATLAB信号处理,但是很无语,感觉自己对MATLAB的语法很陌生,看了半天也觉得自己写不出来,所以就对着MATLAB自己去写用Python进行的数字信号处理基础,我写了两天左右,基本上把matlab书上的代码全部用Python实现了,所以,今天贴的代码和图有些多, 要用到的

    2024年02月13日
    浏览(28)
  • 信号处理中简单实用的方法——对信号进行平滑处理

    从现实环境采集到的数据中经常混叠有微弱噪声,其中包括由于系统不稳定产生的噪声,也有周围环境引入的毛刺,这些弱噪声都需要在处理信号之前尽可能地消除或减弱。这一工作往往作为预处理的一部分。下面将介绍几种简单又实用的平滑处理方法:五点三次平滑法、

    2024年02月07日
    浏览(42)
  • Linux进程信号【信号处理】

    ✨个人主页: 北 海 🎉所属专栏: Linux学习之旅 🎃操作环境: CentOS 7.6 阿里云远程服务器 从信号产生到信号保存,中间经历了很多,当操作系统准备对信号进行处理时,还需要判断时机是否 “合适”,在绝大多数情况下,只有在 “合适” 的时机才能处理信号,即调用信号

    2024年02月11日
    浏览(30)
  • 信号系统之连续信号处理

    1 Delta 函数 连续信号可以分解为缩放和移位的增量函数,就像处理离散信号一样。不同之处在于,连续 delta 函数比其离散函数复杂得多,在数学上也抽象得多。我们不是用它是什么来定义连续 delta 函数,而是用它所具有的特征来定义它。 一个思想实验将展示它是如何工作的

    2024年02月22日
    浏览(42)
  • Linux进程信号 | 信号处理

    前面的文章中我们讲述了信号的产生与信号的保存这两个知识点,在本文中我们将继续讲述与信号处理有关的信息。 之前我们说过在收到一个信号的时候,这个信号不是立即处理的,而是要得到的一定的时间。从信号的保存中我们可以知道如果一个信号之前被block,当解除

    2024年02月09日
    浏览(33)
  • 【非欧几里得域信号的信号处理】使用经典信号处理和图信号处理在一维和二维欧几里得域信号上应用低通滤波器研究(Matlab代码实现)

     💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 2.1 算例1 2.2 算例2 2.3 算例3  2.4 算例4 

    2024年02月13日
    浏览(41)
  • 【lesson51】信号之信号处理

    信号产生之后,信号可能无法被立即处理,一般在合适的时候处理。 1.在合适的时候处理(是什么时候? ) 信号相关的数据字段都是在进程PCB内部。 而进程工作的状态一般如下: 在内核态中,从内核态返回用户态的时候,进行信号检测和处理! 我们为什么会进入内核态?

    2024年02月22日
    浏览(34)
  • 现代信号处理——盲信号分离(盲信号分离的基本理论)

    一、背景 盲信号分离的研究源自Jutten与Herault于1991年发表的论文。Comon于1994年提出盲信号分离的独立分量分析方法。正是他们的开拓性工作极大地推动了盲信号分离的研究,使得盲信号分离成为近30多年来信号处理界、机器学习界与神经计算界的一个研究热点。以广泛的应用

    2024年02月13日
    浏览(35)
  • 【FPGA】跨时钟域问题(二)(单bit信号跨时钟域 1. 电平同步器 2. 边沿同步器 3. 脉冲检测器)

    作者:安静到无声 个人主页 作者简介:人工智能和硬件设计博士生、CSDN与阿里云开发者博客专家,多项比赛获奖者,发表SCI论文多篇。 Thanks♪(・ω・)ノ 如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦! o( ̄▽ ̄)d ლ(°◕‵ƹ′◕ლ)希望在传播知

    2024年02月16日
    浏览(33)
  • 【信号】信号处理与进程通信:快速上手

    目录 0. 信号概述 1. 产生信号的方式: 1.1 当用户按某些终端键时,将产生信号。 1.2 硬件异常将产生信号。 1.3 软件异常将产生信号。 1.4 调用kill函数将发送信号。 1.5 运行kill命令将发送信号。 2. 信号的默认(缺省)处理方式 2.1 终止进程: 2.2 缺省出来: 2.3 停止进程: 2.

    2024年02月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包