《数字IC: Verilog》4.2 跨时钟域传输:慢到快

本文探讨了在数字IC设计中,如何处理跨时钟域传输的问题,重点介绍了延迟打拍法和延迟采样法。延迟打拍法通过两级触发器缓存异步信号,减少亚稳态问题,而延迟采样法则针对多位宽数据传输,确保在安全时刻采集信号。当慢时钟域数据使能信号无效或一直有效时,需要对边沿进行检测以避免问题。
摘要由CSDN通过智能技术生成

理论上讲,快时钟域的信号总会采集到慢时钟域传输来的信号,如果存在异步可能会导致采样数据出错,所以需要进行同步处理。此类同步处理相对简单,一般采用延迟打拍法,或延迟采样法。


延迟打拍法

最常用的同步方法是双级触发器缓存法,俗称延迟打拍法。异步信号从一个时钟域进入另一个时钟域之前,将该信号用两级触发器连续缓存两次,可有效降低因为时序不满足而导致的亚稳态问题。电路示意图如下。

在这里插入图片描述

一般设计中使用两级触发器进行缓存即可满足设计时序需求。大量实验表明,三级触发器缓存可解决 99% 以上的此类异步时序问题。

两级触发器延迟打拍并检测信号上升沿的 Verilog 描述如下:

module delay_clap(
    input       clk1,  //异步慢时钟
    input       sig1,  //异步信号

    input       rstn,  //复位信号
    input       clk2,  //目的快时钟域市政
    output      sig2); //快时钟域同步后的信号

   reg [2:0]    sig2_r ;   //3级缓存,前两级用于同步,后两节用于边沿检测
   always @(posedge clk2 or negedge rstn) begin
     if (!rstn) sig2_r  <= 3'b0 ;
     else       sig2_r  <= {sig2_r[1:0], sig1} ;  //缓存
   end
  
Verilog中,跨时钟域信号传输可以通过使用双向异步FIFO(First-In-First-Out)实现。以下是一个例子: 首先,定义一个模块,包含两个时钟域的输入信号和一个双向异步FIFO: ```verilog module clock_domain_crossing ( input clk_fast, // 时钟域 input clk_slow, // 慢时钟域 input reset, input data_in, output reg data_out ); reg [7:0] fifo [0:255]; // 双向异步FIFO reg wr_en, rd_en; reg [7:0] wr_ptr, rd_ptr; // 定义一个计数器,用于跟踪FIFO中的条目数 reg [7:0] count = 0; // 定义一个状态机来控制读写操作 // 在时钟域下,每个时钟周期只执行一次操作 reg [1:0] state = 2'b00; always @(posedge clk_fast) begin case (state) 2'b00: begin // 空闲状态 wr_en <= 0; rd_en <= 0; if (reset) begin wr_ptr <= 0; rd_ptr <= 0; count <= 0; state <= 2'b00; end else if (data_in && count < 256) begin wr_en <= 1; wr_ptr <= wr_ptr + 1; count <= count + 1; state <= 2'b01; end else if (count > 0) begin rd_en <= 1; rd_ptr <= rd_ptr + 1; count <= count - 1; state <= 2'b10; end else begin state <= 2'b00; end end 2'b01: begin // 写入状态 wr_en <= 0; state <= 2'b00; end 2'b10: begin // 读取状态 data_out <= fifo[rd_ptr]; rd_en <= 0; state <= 2'b00; end endcase end // 在慢时钟域下,每个时钟周期只执行一次操作 always @(posedge clk_slow) begin if (reset) begin wr_ptr <= 0; rd_ptr <= 0; count <= 0; end else if (wr_en) begin fifo[wr_ptr] <= data_in; end else if (rd_en) begin data_out <= fifo[rd_ptr]; end end endmodule ``` 在上面的代码中,状态机控制了读写操作,并且在时钟域下使用了一个双向异步FIFO来缓存数据。在慢时钟域下,数据从FIFO中读取或写入。由于双向异步FIFO可以同时处理读和写操作,因此可以实现跨时钟域信号传输。 需要注意的是,由于跨时钟域信号传输涉及到时序问题,因此需要特别小心。在实现时,应该尽可能使用同步方式,避免异步时序问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值