• 跨时钟域设计【三】—— 数据同步


    前面介绍了项目中用到的脉冲同步的基本方法,其基本功能是从某个时钟域取出一个单时钟宽度脉冲,然后在新的时钟域中建立另一个单时钟宽度的脉冲,但在实际应用中,需要同步的往往不止是脉冲信号,数据总线、地址总线和控制总线都有可能跨域传输。握手协议,RAM和FIFO是最基本的方法,但如果FPGA资源成为关键因素时,这些方法不一定是最好的方法。这里介绍另外一种方法——Toggle法(已经在项目中运用),适合快时钟域到慢时钟域传输数据。

    假如Data是时钟域clkA(20MHz)的数据,需要同步到时钟域clkB(80MHz),我们可以在时钟域A产生一个Toggle信号,为clkA的2分频,然后把Toggle信号同步到clkB,并且在Toggle的上升沿和下降沿去捕获数据,这样能够保证Toggle信号的上升沿和下降沿采集到的是相邻的两个数据,并且数据不会丢失。该方法的Verilog HDL如下:

    module DataSync(
    input rst_n,
    input clkA,
    input clkB,
    input [7:0] Data,

    output reg [7:0] Data_sync
    );

    reg toggle;
    reg toggle_d;
    reg toggle_dd;
    reg toggle_ddd;
    wire toggle_edge;

    always @ (posedge clkA or negedge rst_n)
       if(!rst_n)
          toggle <= 1'b0;
       else
          toggle <= ~toggle;
        
    always @ (posedge clkB or negedge rst_n)
       if(!rst_n)
       begin
          toggle_d <= 1'b0;
          toggle_dd <= 1'b0;
          toggle_ddd <= 1'b0;
       end
       else
       begin
          toggle_d <= toggle;
          toggle_dd <= toggle_d;
          toggle_ddd <= toggle_dd;
       end
       
    always @ (posedge clkB or negedge rst_n)
       if(!rst_n)
          Data_sync <= 8'h00;
       else if(toggle_dd ^ toggle_ddd)
          Data_sync <= Data;
          
    endmodule
     这种方法应用范围有限,实际应用中还得具体问题具体分析。 

  • 相关阅读:
    网络编程初探
    MY GOAL
    推荐一个网站:编程资料网 http://www.ourdev.net/
    端午时节, 嘿嘿, 用论文砸自己一把
    Requirement for My Job
    MVC 才是正道, say bye to naive
    linux下的top命令参数说明 (virt,res,shr,data 的意义)
    Linux中线程与CPU核的绑定
    linux多线程域名解析函数导致的内存空间占用增长
    MD5简介
  • 原文地址:https://www.cnblogs.com/hfyfpga/p/4379833.html
Copyright © 2020-2023  润新知