亚稳态及信号跨时钟域处理


一、亚稳态简介

  亚稳态的产生:一个信号在一个时钟域变化,并在另一个时钟域被采样,就会导致输出成为亚稳态。
本质上是由于违背了触发器的建立和保持时间产生的;
  亚稳态的危害:导致逻辑判断错误、亚稳态传播(下一级电路同样产生亚稳态)

在这里插入图片描述
  建立时间(Tsu,set up time):时钟有效边沿到来前,要求数据保持稳定的最小时间;
  保持时间(Th, hold time):时钟有效边沿到来后,要求数据保持稳定的最小时间;
  输出延迟值(Tco):规定的时钟到输出的延迟值;
  决断时间(Tmet):亚稳态输出恢复到稳态所超出tco的额外的时间;

  亚稳态导致触发器在原有的输出延迟tco上多出一段决断时间tmet,在这段时间之后,触发器最终由亚稳态转向稳态;
  一般来说,触发器会在一个或两个时钟周期内返回稳态;

二、亚稳态窗口

  具有特定时间长度的窗口,在这段时间内,输入数据与时钟均应该保持不变;
在这里插入图片描述
  亚稳态窗口越大,进入亚稳态的概率越高;


三、平均无故障时间(MTBF)

  单级触发器的平均无故障时间
  MTBF1 = e(tr/τ)/W·fc·fd
  tr : 允许超出器件正常传输延迟时间的解析时间
  τ: 触发器的亚稳态解析时间常数
  W: 亚稳态窗口
  fc: 时钟频率
  fd: 异步信号边沿频率
  两级触发器的平均无故障时间
  MTBF2 = e(tr1/τ)/W·fc·fd × e(tr2/τ)

  若单级同步器的MTBF为40s,则两级同步器的MTBF为40 × 40 = 26.6min
  可见信号经过两级触发器后,平均无故障时间明显增加,这也是多级同步器的原理;


四、亚稳态产生场景

亚稳态产生:违背时序要求
  1.输入信号为异步(中断、复位)
  2.时钟偏移、时钟抖动,高于容限值
  3.信号在两个不同频率或者相同频率但相位、偏移不同的时钟下工作(跨时钟域)
  4.组合逻辑延迟使得触发器的数据输入在亚稳态窗口内发生变化


五、解决亚稳态的技术

5.1 单比特信号跨时钟域

5.1.1 多级同步器

  多级同步器的原理可参考第三节平均无故障时间的计算;
  使用一个完整的时钟周期来降低亚稳态发生的概率(不能解决);
  应用场景:
  单/多比特数据,从慢时钟域进入到快时钟域(频率差2倍),此时不会丢失数据;
  若处理的数据从快时钟域到慢时钟域 ,可能会发生数据丢失(漏采样);
  输出会有Lantency,视级数而定(1级-1Lantency 2级-2Lantency);

module Multiple_stage_synchronizermodule#(
        parameter integer DFF_LEVEL  = 2,
        parameter integer DATA_WIDTH = 1
)(
        input wire                     clk,
        input wire [DATA_WIDTH - 1:0]  din,
        input wire [DATA_WIDTH - 1:0] dout,
        input wire                    nrst
    );

    reg [DATA_WIDTH - 1:0] din_buff [DFF_LEVEL-1:0];
    assign dout = din_buff[DFF_LEVEL-1];
    integer i;

    always @(posedge clk or negedge nrst) begin
        if (~nrst) begin
            // reset
            for(i=0;i<DFF_LEVEL;i=i+1)
            begin
                din_buff[i] <= 'b0;
            end
        end
        else begin
            for(i=1;i<DFF_LEVEL;i=i+1)
            begin
                din_buff[i] <= din_buff[i-1];
            end
                din_buff[0] <= din;
        end
    end
    
endmodule

综合电路
在这里插入图片描述

5.1.2 另一种多级同步器

普通多级同步器存在的问题
  要求异步信号的脉宽必须大于时钟周期(采样不到);
  要求异步信号的时钟域1时钟频率小于时钟域2(漏采);

同步器B模式
  可以从快时钟域采样信号;
  不需要异步信号的脉宽大于时钟周期;
  常用于中断信号、复位信号的同步;

module Multiple_stage_synchronizermoduleB(  
        input     wire      din,
        input     wire    s_clk,
        input     wire       en,
        input     wire     nrst,
        output    wire     dout
    );
    
    wire    Q1_Clr;//µÚÒ»¼¶´¥·¢Æ÷¸´Î»ÐźÅ
    reg     Q1_out,Q2_out,Q3_out;
    assign Q1_Clr = ~din & dout;
    assign dout = Q3_out;
    always@(posedge din,posedge Q1_Clr)
    begin
        if(Q1_Clr)
        begin
            Q1_out <= 1'b0;
        end
        else
        begin
            Q1_out <= 1'b1;
        end
    end
    
    always@(posedge s_clk)
    begin
        if(~nrst)
        begin
            Q2_out <= 1'b0;
            Q3_out 
### ✅ 什么是亚稳态(Metastability)? **亚稳态** 是数字电路(尤其是同步电路)中,当一个触发器(Flip-Flop)的输入信号在**建立时间(setup time)或保持时间(hold time)** 被违反时,导致输出进入一种既不是稳定高电平也不是稳定低电平的中间状态。这种状态可能持续一段时间,甚至传播到后续逻辑,造成系统错误。 --- #### 🔍 形象比喻: 想象你把一个球放在山顶上 —— 它理论上可以静止在那里,但任何微小扰动都会让它滚下山。这就是“亚稳态”: - 山顶 = 不稳定的中间电压(如1.5V) - 滚向左边/右边 = 最终稳定为0或1 这个过程需要时间,而如果系统在这个恢复完成前就读取了该值,就会读到错误结果。 --- ## 📌 为什么会发生亚稳态? ### 常见场景: | 场景 | 描述 | |------|------| | ❌ 跨时钟域传输(CDC) | 在一个时钟域采样另一个异步时钟域的信号(如 `clk_a` 采样来自 `clk_b` 的信号) | | ❌ 异步复位释放 | 复位信号在不同时钟边沿附近释放,导致不同寄存器退出复位的时间不一致 | | ❌ 输入信号来自外部设备(按键、传感器等) | 外部信号与内部时钟无固定相位关系 | --- ### 💥 典型代码问题(危险!) ```verilog // 危险:直接用异步信号作为同步逻辑输入 input async_signal; reg sync_reg; always @(posedge clk) begin sync_reg <= async_signal; // ⚠️ 可能引发亚稳态! end ``` > 如果 `async_signal` 在 `clk` 上升沿附近变化,则 `sync_reg` 可能进入亚稳态。 --- ## ✅ 如何解决亚稳态? ### ✅ 方法一:两级同步器(Two-Flop Synchronizer) 适用于 **单比特信号跨时钟域**(例如按钮、使能信号) ```verilog reg async_in_meta, async_in_stable; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin async_in_meta <= 1'b0; async_in_stable <= 1'b0; end else begin async_in_meta <= async_signal; // 第一级:捕获信号(可能亚稳) async_in_stable <= async_in_meta; // 第二级:等待第一级稳定 end end ``` > 经过两个周期后,`async_in_stable` 基本可认为是稳定的。 📌 注意:不能用于多比特信号(如总线),否则会出现**数据偏移**问题。 --- ### ✅ 方法二:使用 FIFO(异步 FIFO) 适用于 **多比特数据跨时钟域传输** - 使用双口 RAM + 空/满标志生成逻辑 - 读写指针通过格雷码(Gray Code)编码跨时钟域传递 ```verilog // 示例结构 async_fifo #( .DATA_WIDTH(8), .DEPTH(16) ) u_fifo ( .wr_clk(wr_clk), .rd_clk(rd_clk), .din(din), .wen(wen), .dout(dout), .ren(ren), .full(full), .empty(empty) ); ``` --- ### ✅ 方法三:握手协议(Handshaking) 两个时钟域之间通过 `valid` / `ack` 信号协调传输: ```text Domain A (Sender) Domain B (Receiver) valid ------------------> ack ------------------> ``` 只有当双方都确认后才更新数据,确保不会丢失。 --- ## ⚠️ 亚稳态无法完全消除,只能降低概率! 每个触发器都有一个 **平均故障间隔时间(MTBF)**,它取决于: - 时钟频率 - 信号切换速率 - 工艺温度 - 同步级数 添加第二级寄存器可显著提升 MTBF(例如从几秒提高到数千年)。 --- ## 🔧 Quartus / Vivado 中如何检查亚稳态风险? ### 工具支持: | 工具 | 功能 | |------|------| | **Quartus TimeQuest** | 使用 `set_clock_groups`, `set_false_path` 标记异步时钟 | | **Vivado Timing Analyzer** | 自动报告未约束的跨时钟域路径 | | **SpyGlass CDC** | 专业级亚稳态跨时钟域分析工具 | 📌 建议:对所有跨时钟域信号打标记: ```tcl # Tcl 示例(Quartus) set_clock_groups -asynchronous -group [get_clocks clk_a] -group [get_clocks clk_b] ``` --- ## ✅ 总结:亚稳态处理最佳实践 | 实践 | 说明 | |------|------| | ✅ 所有异步输入必须同步化 | 特别是按键、外部中断等 | | ✅ 使用双触发器同步单比特信号 | 最常用、最有效的方法 | | ✅ 多比特信号使用 FIFO 或握手 | 避免偏移问题 | | ✅ 不要用组合逻辑做时钟门控 | 易引起毛刺和亚稳 | | ✅ 异步复位必须同步释放 | 使用同步复位释放电路 | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

PPRAM

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

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

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

打赏作者

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

抵扣说明:

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

余额充值