任意时钟频率的单bit跨时钟域设计(海思巴龙)

题目描述        

        两个时钟域传单bit数据,输入A持续一个cycle,要求输出B一个cycle。两个时钟域的时钟是任意的。

题目分析

        对于慢时钟到快时钟的单bit传输,我们通常采用的方式是打两拍。对于快时钟到慢时钟的单bit传输,我们通常采用的方式是脉冲展宽,但通常这种单bit传输的目的是去传输边沿,譬如rstn信号的单bit传输,它持续低有效的时间足够长,所以我们异步释放在目的时钟域打两拍可以传递下降沿。

        但这里题目要求:第一、A、B时钟的频率是未知的,所以我们写的设计必须与频率无关;第二、A输出一个cycle,B也输出一个cycle。也就是说A时钟域的数据传输到B时钟域,数据个数不能变,数据不能错。我们可以使用多bit跨时钟域的handshake方法来做这个东西。

解题思路

        使用多bit跨时钟域的handshake方法,来实现数据的握手。

①:当A时钟域的A拉高1周期时,我们令A有效一直为高(快到慢时,脉冲展宽用。)

②:把A_en信号在B时钟域打两拍之后,在B时钟域检测A_en_two的上升沿,若检测到了,则B输出1周期高。满足题意的同时,其实是代表B时钟域看到了A时钟域的信号

③:把A_en_tre再在A时钟域打两拍,得到B_en_two,当B_en_two等于1时,我们就可以把A_en信号拉低,代表我在A时钟域看到了B时钟域已经接受了我的信号。

        当A是慢时钟域,B是快时钟域时,容易推断得到:也能满足上面的波形。

代码

module one_bit_cdc(
    input   rstn    ,
    input   clk_A   ,
    input   A       ,
    input   clk_B   ,
    output  B   
);
reg A_en,A_en_one,A_en_two,A_en_tre;
reg B_en_one,B_en_two;

always @(posedge clk_A)begin
    if(!rstn)begin
        A_en <= 1'b0;
    end
    else if(A)begin
        A_en <= 1'b1;
    end
    else if(B_en_two)begin
        A_en <= 1'b0;
    end
end

always @(posedge clk_B)begin
    if(!rstn)begin
        A_en_one <= 1'b0;
        A_en_two <= 1'b0;
        A_en_tre <= 1'b0;
    end
    else begin
        A_en_one <= A_en;
        A_en_two <= A_en_one;
        A_en_tre <= A_en_two;
    end
end
assign B = A_en_two && (!A_en_tre);

always @(posedge clk_A)begin
    if(!rstn)begin
        B_en_one <= 1'b0;
        B_en_two <= 1'b0;
    end
    else begin
        B_en_one <= A_en_tre;
        B_en_two <= B_en_one;
    end
end

endmodule

testbench

module tb();

wire B;
reg rstn,clk_A,clk_B,A;
initial begin
    rstn <= 1'b0;
    clk_A <= 1'b0;
    clk_B <= 1'b0;
    A <= 1'b0;
    #20
    rstn <= 1'b1;
    #15
    A <= #1 1'b1;
    #10 
    A <= #1 1'b0;
    #300
    $finish();
end

initial begin
    forever #5 clk_A <= ~clk_A;
end

initial begin
    forever #10 clk_B <= ~clk_B;
end

one_bit_cdc u_one_bit_cdc(
    .rstn   (rstn   ),
    .clk_A  (clk_A  ),
    .A      (A      ),
    .clk_B  (clk_B  ),
    .B      (B      )
);

initial begin
    $fsdbDumpfile("one_bit_cdc.fsdb");
    $fsdbDumpvars(0);
end

endmodule

波形图

快时钟域A到慢时钟域B

 慢时钟域A到快时钟域B

波形和我们设计之前画的预想波形一致。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃葱的酸菜鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值