zoukankan      html  css  js  c++  java
  • 关于FPGA异步时钟采样--结绳法的点点滴滴

    .典型方法

       典型方法即双锁存器法,第一个锁存器可能出现亚稳态,但是第二个锁存器出现亚稳态的几率已经降到非常小,双锁存器虽然不能完全根除亚稳态的出现(事实上所有电路都无法根除,只能尽可能降低亚稳态的出现),但是基本能够在很大程度上减小这种几率。最后的一个D触发器和逻辑电路组成的是一个采沿(上升沿,修改一下就能采集下降沿)电路,即当第二个锁存器的输出中出现1个上升沿,那么最后的逻辑输出就会产生1个clock的高电平脉冲

    .结绳法

     1.结绳法1:利用数据的边沿作时钟(例子中上升沿)。(可以将脉冲无限延长,直到可以采集到数据,然后复位,要考虑产生数据的频率)。

      实例1

     

     说明:这种结绳法的原理是,数据作为Din_clkA,即当数据有上升沿(0->1)时,寄存器1的输出将会稳定在高电平,此时等待clkB采样,当clkB完成采样后,寄存器4会输出高电平,若此时Din_clkA为高电平,那么即可完成复位,开始下一次采样等待。

           这里需要注意的是当数据来临(即上升沿)时,clkB域需要等待3个clkB才会在寄存器4输出并完成输入端的复位,所以Din如果变化较快

            即持续时间短于3个clkB,也就是clkA频率大于clkB的1/3,那么这时Din的变化将无法被采样到,因为clkB域需要3个clkB才能

            完成采样,并且此时Din必须是低电平才能复位,并且复位后的0也要延迟3个clkB才能到达输出端.

           因此说,在慢时钟采样快时钟的时候,结绳法适合采样数据较少(即脉冲间隔较大)的控制信号。即脉冲间隔Ta>3Tb;即等待3个clkB时钟后,完成复位,才允许下一个输入脉冲。

           

    实例2


        说明:与实例1的区别是,这种复位更迅速,不需要等到clkA为低电平,即可完成复位。复位后,经过3个clkB,寄存器2~4相继复位

     2结绳法2:利用数据作为异步复位,置位信号。(适合将不足时钟宽度的脉冲扩展1周期)

     实例1:输入高脉冲(clka域),输出高脉冲(clkb域)

         说明:当clkB因为太慢,没有采到din_clkA时,din_clkA的高电平脉冲会异步置位,即寄存器1从clkA的上升沿开始到clkB的下一个上升沿之间输出为高,寄存器2采样到高电平,并持续1个clkB,高电平持续时间为1个clkB多一点;

               当clkB足够快,其上升沿采到了din_clkA时,置位作用从clkA的上升沿开始,跨越了clkB的上升沿,那么输出高电平持续了2个clkB还多一点,因为寄存器1持续了1个周期多一点。

                

    实例2:输入高脉冲(clka域),输出低脉冲(clkb域)

        说明:同上

    实例3:输入低脉冲(clka域),输出低脉冲(clkb域)

        说明:同上

    实例4:输入低脉冲(clka域),输出高脉冲(clkb域)

        说明:同上 

    3结绳法3:输入作为数据输入,同样也是检测高有效后,输出一直为高,异步时钟域可以采集到数据后再复位。
    因为没有将输入作为时钟,或者作为异步set,reset,所以这类方便比较常用。

    参考代码:

    //================================================================================
    // Created by         : Ltd.com
    // Filename           : sync_clk1_clk2.v
    // Author             : Python_Wang
    // Created On         : 2009-02-27 22:47
    // Last Modified      : 2009-02-28 09:09
    // Description        : 
    //                      
    //                      
    //================================================================================
    module sync_clk1_clk2(
      clk1                       ,
      rst_n1                     ,
      clk2                       ,
      rst_n2                     ,
      data_clk1_i                ,
      data_clk2_o              
    );
    input        clk1            ;
    input        rst_n1          ;
    input        clk2            ;
    input        rst_n2          ;
    input        data_clk1_i     ;
    output       data_clk2_o     ;
    
    reg          data_clk1_q1    ;
    reg          data_clk1_q2    ;
    
    reg          data_clk2_q1    ;
    reg          data_clk2_q2    ;
    reg          data_clk2_q3    ;
    reg          data_clk2_q4    ;
    reg          data_clk2_q5    ;
    
    wire         data_clk1       ;
    
    assign  data_clk1 = data_clk1_i | ( !data_clk2_q5 & data_clk1_q1) ;
    
    always@(posedge clk1 or negedge rst_n1)
    begin
      if(!rst_n1) begin
        data_clk1_q1  <= #1 'b0;
        data_clk1_q2  <= #1 'b0;
      end
      else begin
        data_clk1_q1  <= #1 data_clk1   ;
        data_clk1_q2  <= #1 data_clk1_q1;
      end
    end
    
    always@(posedge clk2 or negedge rst_n2)
    begin
      if(!rst_n2) begin
        data_clk2_q1  <= #1 'b0;
        data_clk2_q2  <= #1 'b0;
        data_clk2_q3  <= #1 'b0;
      end
      else begin
        data_clk2_q1  <= #1 data_clk1_q1;
        data_clk2_q2  <= #1 data_clk2_q1;
        data_clk2_q3  <= #1 data_clk2_q2;
      end
    end
    
    always@(posedge clk1 or negedge rst_n1)
    begin
      if(!rst_n1) begin
        data_clk2_q4  <= #1 'b0;
        data_clk2_q5  <= #1 'b0;
      end
      else begin
        data_clk2_q4  <= #1 data_clk2_q2;
        data_clk2_q5  <= #1 data_clk2_q4;
      end
    end
    
    assign data_clk2_o = data_clk2_q2 & ~data_clk2_q3 ;
    
    endmodule


    仿真:

    4.结绳法3:利用握手协议:(可以将脉冲无限延长,直到可以采集到数据,然后复位,要考虑产生数据的频率)。

                   Pulse2Toggle                             Synchronization                    Toggle2Pluse

     

                   Toggle2Pluse                             Synchronization                      Pluse2Toggle       


             说明:        结绳模块(Pluse2Toggle): 负责延长待采样信号

                               同步模块(Synchronization):负责双触发器锁存

                               解绳模块(Toggle2Pluse):  负责将长信号转换成脉冲信号 

        

     

    参考代码:

    //================================================================================
    // Created by         : Ltd.com
    // Filename           : handover.v
    // Author             : Python_Wang
    // Created On         : 2009-02-19 19:31
    // Last Modified      : 2009-02-20 08:38
    // Description        : 
    //                      
    //                      
    //================================================================================
    module handover(
    rst_n                        ,
    ClkA                         ,
    Req_ClkA                     ,
    Ack_ClkA                     ,
    ClkB                         ,
    Dvld_ClkB                   
    );
    input        rst_n           ;
    input        ClkA            ;
    input        Req_ClkA        ;
    input        ClkB            ;
    output       Ack_ClkA        ;
    output       Dvld_ClkB       ;
    reg          Dvalid_ClkB     ;
    reg          Q_Dvalid_ClkB   ;
    
    
    reg          Dvalid_ClkA     ;
    always@(posedge ClkA) 
    begin
      if(!rst_n) begin
        Dvalid_ClkA <= #1 1'b0;
      end
      else if(Req_ClkA) begin
        Dvalid_ClkA <= #1 ~Dvalid_ClkA ;
      end
    end
    
    
    reg          Q1_ClkB         ;
    reg          Q2_ClkB         ;
    reg          Q3_ClkB         ;
    always@(posedge ClkB) 
    begin
      if(!rst_n) begin
        Q1_ClkB <= #1 'b0;
        Q2_ClkB <= #1 'b0;
        Q3_ClkB <= #1 'b0;
      end
      else begin
        Q1_ClkB <= #1 Dvalid_ClkA ;
        Q2_ClkB <= #1 Q1_ClkB     ;
        Q3_ClkB <= #1 Q2_ClkB     ;
      end
    end
    
    wire Req_ClkB = Q2_ClkB ^ Q3_ClkB ;
    
    
    always@(posedge ClkB) 
    begin
      if(!rst_n) begin
        Dvalid_ClkB   <= #1 'b0;
        Q_Dvalid_ClkB <= #1 1'b0;
      end
      else if(Req_ClkB) begin
        Dvalid_ClkB   <= #1 ~Dvalid_ClkB ;
        Q_Dvalid_ClkB <= #1 Dvalid_ClkB  ;
      end
    end
    
    always@(posedge ClkB) 
    begin
      if(!rst_n) begin
        Q_Dvalid_ClkB <= #1 1'b0;
      end
      else begin
        Q_Dvalid_ClkB <= #1 Dvalid_ClkB  ;
      end
    end
    
    
    reg          Q1_ClkA         ;
    reg          Q2_ClkA         ;
    reg          Q3_ClkA         ;
    always@(posedge ClkA) 
    begin
      if(!rst_n) begin
        Q1_ClkA <= #1 'b0 ;
        Q2_ClkA <= #1 'b0 ;
        Q3_ClkA <= #1 'b0 ;
      end
      else begin
        Q1_ClkA <= #1 Dvalid_ClkB ;
        Q2_ClkA <= #1 Q1_ClkA     ;
        Q3_ClkA <= #1 Q2_ClkA     ;
      end
    end
    
    assign  Ack_ClkA = Q2_ClkA ^ Q3_ClkA ;
    assign  Dvld_ClkB = Dvalid_ClkB & ~Q_Dvalid_ClkB;
    
    endmodule

    仿真:

    另外对于为了提高速度和准确度的握手操作中,可以将设置一定的握手模块(n>2(clk1+clk2)/Trd),流水操作

    结绳就是将单脉冲延长,以方便采集到数据。

    结绳的方法归结为2类:

    1.利用脉冲的边沿做时钟;

    2.利用脉冲的电平(部分场合要求最小脉冲宽度)做选择器或者异步复位,置位。

     

    另外的关键点就是什么时候结绳结束(采集到了数据就要让对方回到初始状态),

    这里的操作也有2种方法:

    1.利用采集到的脉冲做异步复位,置位。

    2.利用采集到的脉冲再次结绳采集做握手响应信号。

     

    处理的时候应该选择对应的方法。

  • 相关阅读:
    Nginx 提示host not found in upstream 错误解决方法
    使用Vmware CLI 6.5控制虚拟机,并做快照
    在 Windows服务器中启用/禁用SMBv1、SMBv2和SMBv3的方法
    使用python调用wps v9转换office文件到pdf
    Tomcat延迟启动
    配置frp
    PowerDesigner逆向生成MYSQL数据库表结构总结
    windows下载安装MariaDB10.2.17 绿色版
    Mosquitto --topic
    Jmeter也能IP欺骗!
  • 原文地址:https://www.cnblogs.com/hfyfpga/p/4281369.html
Copyright © 2011-2022 走看看