异步电路中,不同时钟域下的信号同步--慢时钟域到快时钟域和快时钟域到慢时钟域

信号在进行跨时钟传输时,同步是不可避免的。

慢时钟域信号同步到快时钟域时,一般的做法都是打两拍(单bit传输)

module time_dff (

    clk_a,clk_b,rst,d_in,d_out
);
    input clk_a;
    input clk_b;
    input rst;
    input d_in;
    output d_out;
    reg d_in_1;
    reg d_out_2;
    reg d_out_1;
    always @(posedge clk or negedge rst) begin
        if(!rst) begin
            d_in_1 <= 1'b0;
        end
        else begin
            d_in_1 <= d_in;
        end
    end
    always @(posedge clk or negedge) begin
        if(!rst) begin
            d_out_1 <= 1'b0;
            d_out_2 <= 1'b0;
        end
        else begin
            d_out_1 <= d_in_1;
            d_out_2 <= d_out_1;
        end
    end
    assign d_out = d_out_2;
endmodule

通过电路图很容易就能理解程序的书写。

  首先有个问题:为什么在clk_a时钟域内需要打一拍? 因为不能直接将组合逻辑的输出做两级同步,需要将组合逻辑的输出通过原始时钟打

一拍后载进行两级同步。

  还有一个问题:为什么要打两拍,而不是打三拍或者是打一拍?首先打一拍很简单,首先在clk_b时钟域内,当从clk_a过来的信号不满足b时

钟域第一个寄存器的建立保持时间,则会出现亚稳态,因此一拍肯定是不行的。但是可以确定的是,第一拍出来的信号是满足第二个寄存器的建立

保持时间,可将出现亚稳态的几率大大降低。因为第二拍已经对亚稳态的出现进行较大的改善,此时再进行第三拍,实际上也是对第二拍的延续。

又因为亚稳态并不能完全消除,只能降低其发生概率,所以一拍概率很大,二拍提高可靠性,降低其发生概率,三拍改善不大。

  当针对与多bit慢时钟域同步到快时钟域:加入交互信号(添加使能信号,对使能信号进行两级同步)

当快时钟域脉冲信号同步到慢时钟域时:

解决方法1:拓宽快时钟域的脉冲信号

  1、如果两个时钟频率相差不大,如下电路。即快时钟域脉冲信号时间间隔必须大于clk_b的时钟周期

具体代码实现:https://www.cnblogs.com/shadow-fish/p/13514353.html

2、如果clk_a频率比clk_b频率大于2倍小于3倍,则需要在拓展脉冲电路中多加一级寄存器,同时将或门换成三输入与门,使输入信号脉宽

拓展3倍。clk_a频率为clk_b的4倍,则打4拍,延迟3个clk_a时钟周期。

解决方式2:

  握手交互,额外添加一个保持寄存器和握手信号,将快时钟域的信号同步到慢时钟域,然后将同步后的信号通过另一个同步器返回到快时钟域

作为应答信号,这种方法具有相当大的延迟。具体握手流程:当数据发出,快时钟域产生一个req请求信号,经过两级同步后到达慢时钟域,向慢时

钟域表明数据已经准备好,可以进行读取,读取接结束后慢时钟域会产生一个确认信号ack,经过两级同步后告诉快时钟域,数据已经读取完了,当

快时钟域检测到同步过来的有效ack信号后,拉低req信号,而后慢时钟域检测到同步过来的无效req信号,也会拉低ack信号。至此一次握手结束。

详细代码链接:https://www.cnblogs.com/shadow-fish/p/13526345.html

posted @ 2020-08-07 15:14  影-fish  阅读(4646)  评论(0编辑  收藏  举报