大疆题解:跨时钟域脉冲信号处理—脉冲同步器(快到慢)
我的学记|刘航宇的博客

大疆题解:跨时钟域脉冲信号处理—脉冲同步器(快到慢)

刘航宇
2年前发布 /正在检测是否收录...
温馨提示:
本文最后更新于2023年12月11日,已超过438天没有更新,若内容或图片失效,请留言反馈。

问题描述

sig_a 是 clka(300M)时钟域的一个单时钟脉冲信号(高电平持续一个时钟clka周期),请设计脉冲同步电路,将sig_a信号同步到时钟域 clkb(100M)中,产生sig_b单时钟脉冲信号(高电平持续一个时钟clkb周期)输出。请用 Verilog 代码描述。
clka时钟域脉冲之间的间隔很大,无需考虑脉冲间隔太小的问题。
电路的接口如下图所示:
图片[1] - 大疆题解:跨时钟域脉冲信号处理—脉冲同步器(快到慢) - 我的学记|刘航宇的博客

题解

1.1 电路波形图

图片[2] - 大疆题解:跨时钟域脉冲信号处理—脉冲同步器(快到慢) - 我的学记|刘航宇的博客
如上图所述,aclk快时钟域发送的信号signal_a,慢时钟域的时钟bclk根本就采集不到,此时不能使用打两拍的方式,要想办法转换思路, 如果能够让同步于快时钟域aclk下的脉冲信号signal_a变长到可以让慢时钟域bclk检测到,那么这个问题就可以完美解决了。

所以先将快时钟域clka下的脉冲信号signal_a,在快时钟域clka的作用下,变为沿信号,产生一个名为adata的中间变量来作为脉冲信号signal_a的沿信号。如上图所示,每当快时钟域aclk检测到signal_a脉冲信号为高时,让adata信号取反,使得signal_a的第一个脉冲变为adata信号的上升沿,signal_a的第二个脉冲变为adata信号的下降沿,后面如果Signal_a信号还有脉冲依然是变为adata信号的上升沿和下降沿。

巧妙的利用将“脉冲信号”转化为“沿信号”的思想就可以使慢时钟域的时钟bclk检测到同步于快时钟域aclk且将脉冲信号signal_a转化为沿信号adata, 相当于是把同步于快时钟域aclk的脉冲信号signal_a进行了展宽处理,这样我们就把快时钟域aclk的脉冲信号signal_a通过adata信号“沿”的形式在慢时钟域bclk中得到了保留。

接着,我们再对adata信号做打两拍的处理就可以将adata信号同步到慢时钟域clkb中了。bdata0信号是adata信号在慢时钟域bclk下打的第一拍,bdata1信号是adata信号在慢速时钟域bclk下打第二拍,bdata1就是同步于慢速时钟域bclk的稳定信号。

最后,采用 边沿检测 的方法,将变为bdata1信号的“沿”再转化为脉冲信号,这里我们使用的方法是采用异或门。需要注意的是不能直接使用bdata0和bdata1来产生沿标志信号,因为bdata0信号的不稳定性可能会导致产生的沿信号也不稳定,所以需要将bdata1信号再打一拍,产生signal_b信号。

1.2 代码

//快时钟数据同步
module pulse_detect(
    input                 clka    , 
    input                 clkb    ,   
    input                 rst_n        ,
    input                sig_a        ,

    output               sig_b
);
    wire sig_a;
    reg    adata;
    reg bdata0;
    reg bdata1;
    reg bdata2;

    always @(posedge clka or negedge rst_n) begin
        if(~rst_n) begin
            adata <= 1'd0;
        end
        else begin
            adata <= adata ^ sig_a;
        end
    end
    
    always @(posedge clkb or negedge rst_n) begin
        if(~rst_n) begin
            bdata0 <= 1'd0;
            bdata1 <= 1'd0;
            bdata2 <= 1'd0;
        end
        else begin
            bdata0 <= adata;
            bdata1 <= bdata0;
            bdata2 <= bdata1;
        end
    end

    assign sig_b = bdata1 ^ bdata2;
endmodule

注意

signal_a是两个脉冲,但是使用“脉冲同步”同步到bclk时钟域确只有一个脉冲了,在使用“脉冲同步”时应注意这一点。所以,脉冲同步一般适用于单比特信号从快时钟域传递慢时钟域的场景。

© 版权声明
THE END
喜欢就支持一下吧
点赞 2 分享 赞赏
评论 抢沙发
取消