You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

异步信号场景下,采用与门阻断时钟的设计方案是否可接受?

问题描述

我需要判断异步的BLOCK信号是否早于5个clk周期到来,由于两者异步,无法使用如下经典结构:

always(posedge clk)
if(cnt==4 && !BLOCK)
flag<=1;
else 
flag<=0;
//只有当BLOCK信号未在5个clk周期前到来时,flag才会被置1

always(posedge clk)
cnt <= cnt + 1;

我尝试通过在BLOCK信号到来时阻断clk,使其停止为flag模块提供时钟,避免flag被置1,对应的设计代码如下:

wire clk_flag = clk & !BLOCK;

always(posedge clk_flag)
if(cnt==4)
flag<=1;
else 
flag<=0;

//只有当BLOCK信号未在5个clk周期前到来时,flag才会被置1

always(posedge clk)
cnt <= cnt + 1;

请问这种通过与门组合信号作为时钟的设计方式是否可接受?

回答

这种用与门组合生成时钟的方式绝对不可接受,核心问题如下:

  • 毛刺触发风险:BLOCK是异步信号,和clk通过与门组合时,极易产生时钟毛刺。这些毛刺会被寄存器识别为有效时钟沿,导致flag出现无规律的错误翻转,直接破坏电路功能。
  • 时序分析失效:FPGA/ASIC的时序分析工具无法对这类组合时钟进行准确的时序检查,建立时间、保持时间等关键参数无法验证,后期调试和时序收敛会陷入极大困境。
  • 时钟树破坏:芯片内部的时钟树会对时钟信号做延迟均衡处理,保证时钟到达各寄存器的时间一致。而组合生成的时钟绕开了时钟树,会导致时钟偏移(skew)过大,进一步恶化时序问题。

正确的实现思路是:

  1. 先对异步的BLOCK信号做两级寄存器同步,将其纳入clk时钟域,避免亚稳态问题。
  2. 在clk域内用同步后的BLOCK信号控制计数器和flag逻辑,比如当同步后的BLOCK信号到来时,立即复位计数器或阻止flag置1。

参考代码如下:

// 异步BLOCK信号同步到clk域
reg BLOCK_sync1, BLOCK_sync2;
always(posedge clk) begin
    BLOCK_sync1 <= BLOCK;
    BLOCK_sync2 <= BLOCK_sync1;
end

reg [2:0] cnt;
reg flag;
always(posedge clk) begin
    if(BLOCK_sync2) begin
        cnt <= 3'd0;
        flag <= 1'b0;
    end else begin
        if(cnt == 3'd4) begin
            flag <= 1'b1;
            cnt <= cnt; // 计数到5个周期后保持状态
        end else begin
            cnt <= cnt + 1'b1;
            flag <= 1'b0;
        end
    end
end

该方案既解决了异步信号的同步问题,又规避了组合时钟带来的各类风险,同时能被时序分析工具正常识别,便于后续调试和优化。

内容的提问来源于stack exchange,提问作者den251

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:01:04