FPGA|CPLD|ASIC论坛
直播中

无量寿经

11年用户 373经验值
擅长:嵌入式技术 控制/MCU
私信 关注
[问答]

异步时钟同步疑惑

在SDRAM的代码中,有的模块工作频率50MHz,有的100MHz,不同时钟域间的数据同步太难理解了,请各位前辈指点。代码如下所示。
//同步SDRAM初始化完成信号
always @(posedge clk_50m or negedge rst_n) begin
    if(!rst_n) begin
        init_done_d0 <= 1'b0;
        init_done_d1 <= 1'b0;
    end
    else begin
        init_done_d0 <= sdram_init_done;
        init_done_d1 <= init_done_d0; // 用init_done_d1判断是否初始化完成
    end
end   
     我知道这段代码是通过打2拍实现步时钟信号同步,但始终不明白,如果直接采样,即使采样时钟上升沿撞上数据跳变沿,采样结果可能是0,也可能是1,0的话后面写计数器不启动,1则立即启动写计数器,看起来也没啥问题,即使打2拍,当采样时钟上升沿撞上数据跳变沿,采样结果同样可能是0,也可能是1,好像也没真正起啥作用,如果不使用这段代码到底会有什么后果?也就是采样异步时钟域信号时不打拍有什么后果?

     另外,当高速时钟采样慢速上升沿或下降沿时,采样结果抖动怎么处理?比如DS18B20长线驱动时,波形上升沿和下降沿被长线的线间电容牵制导致波形边沿变化缓慢 ,采用打2拍方式能否有用?
     此图采样到缓慢上升沿时,采样结果抖动波形。
225646aj9y1ccejsuepxtc.jpg

回帖(2)

杨秀英

2023-9-21 09:36:50
e_d0;        init_done_d1 <= init_done_d0;    end  end  //异步时钟同步SDRAM数据读取always @(posedge clk_100m or negedge rst_n) begin    if(!rst_n) begin        data_out <= 'd0;    end    else begin        if(init_done_d1) begin           data_out <= sdram_data[i];        end        end  end在这段代码中,异步时钟的同步是通过两个时钟域之间的寄存器转换实现的。在同步SDRAM初始化完成信号的代码中,init_done_d0和init_done_d1之间被连接成了一个双向的同步寄存器。这样,在两个时钟域之间进行数据同步时,可以通过这个同步寄存器来实现。在异步时钟同步SDRAM数据读取的代码中,同样使用了一个寄存器(data_out)来实现时钟域间的数据同步。在这个代码段中,当init_done_d1为高电平时,即SDRAM初始化完成时,将读取SDRAM的数据给寄存器data_out,实现了异步时钟同步。
举报

此间hqfj

2024-1-19 17:39:03
打拍的好处可以避免对后级逻辑的影响。如果不进行同步,后面使用这个信号作为触发信号,恰好触发的是高位宽的数据,则会影响每一位的时序,可能会出现有的采集到是高有的采集到是低。时序分析的时候,大面积违例。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分