Verilog--CDC跨时钟域处理(快时钟域到慢时钟域)


今天先写单比特信号从快时钟域到慢时钟域的方法,后续继续填坑

CDC问题

单比特信号的跨时钟域问题

从快时钟域到慢时钟域

设计思想

  从慢时钟域到快时钟域通常使用打两拍的方法,这也适用于从快时钟域到慢时钟域时,但是如果当单比特信号持续时间小于快时钟域的一个周期时,需要用展宽信号再打两拍的方法。

设计相关代码

module Sync_Pulse
(
    input   clka,           //快时钟域
    input   clkb,			//慢时钟域
    input   rst_n,
    input   pulse_ina,      //脉冲或电平信号都可以
    output  pulse_outb,     //脉冲信号
    output  signal_outb     //电平信号
);
//--------------------------------------------------------
reg         signal_a;
reg         signal_a_r1;
reg         signal_a_r2;
reg         signal_b;
reg         signal_b_r1;
//--------------------------------------------------------
//--    a时钟域生成展宽信号
//--------------------------------------------------------
always @(posedge clka or negedge rst_n)begin
    if(!rst_n)begin
        signal_a <= 1'b0;
    end
    else if(pulse_ina) begin        //检测到脉冲
        signal_a <= 1'b1;           //拉高
    end
    else if(signal_a_r2) begin      //同步到b后同步回a
        signal_a <= 1'b0;           //拉低,展宽使命完成
    end
end
//--------------------------------------------------------
//--    展宽信号同步到b时钟域再同步回a时钟域
//--------------------------------------------------------
always @(posedge clkb or negedge rst_n)begin
    if(!rst_n)begin
        signal_b    <= 1'b0;
        signal_b_r1 <= 1'b0;
    end
    else begin
        signal_b    <= signal_a;
        signal_b_r1 <= signal_b;
    end
end

always @(posedge clka or negedge rst_n)begin
    if(!rst_n)begin
        signal_a_r1 <= 1'b0;
        signal_a_r2 <= 1'b0;
    end
    else begin
        signal_a_r1 <= signal_b_r1;
        signal_a_r2 <= signal_a_r1;
    end
end
//--------------------------------------------------------
//--    脉冲信号输出,上升沿检测
//--------------------------------------------------------
assign pulse_outb = ~signal_b_r1 & signal_b;
//--------------------------------------------------------
//--    电平信号输出,b时钟域展宽信号
//--------------------------------------------------------
assign signal_outb = signal_b_r1;


endmodule

tb文件

`timescale 1ns/100ps
module tb_cdc_f2s ();
    
reg clka;
reg clkb;
reg rst_n;
reg pulse_ina;
wire pulse_outb;
wire signal_outb;


initial begin
    clka = 0;
    clkb = 0;
    rst_n = 0;
    #10
    rst_n = 1;
end

initial begin
    pulse_ina = 0;
    #30 
    pulse_ina = 1;
    #2
    pulse_ina = 0;
    #218 
    pulse_ina = 1;
    #2
    pulse_ina = 0;
end

always #10 clka = ~clka;
always #20 clkb = ~clkb;

cdc_f2s u_cdc_f2s(
    .clka           (clka),
    .clkb           (clkb),
    .rst_n          (rst_n),
    .pulse_ina      (pulse_ina),
    .pulse_outb	    (pulse_outb),
    .signal_outb    (signal_outb)
);
endmodule

Modelsim仿真结果
在这里插入图片描述

从慢时钟域到快时钟域

多比特信号的跨时钟域问题

异步FIFO

可以看我这一篇
https://blog.csdn.net/weixin_44425619/article/details/115406095

握手协议

DMUX

格雷码+双D触发器

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值