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

FSM时钟沿切换(下降沿改上升沿)导致计数器计数异常问题

上升沿触发test1模块导致计数器多计数1次的原因分析

问题背景

设计了如下Verilog模块test1,功能是仅让clk信号通过2个时钟周期,之后out_clk输出低电平:

module test1(
    input                               en,
    input                               clk,
    input                               burst,
    output                              out_clk
);

reg [1:0] cpt = 0;

localparam burst_beg = 0;
localparam burst_end = 1;
localparam burst_init = 2;

reg [0:1] state = burst_init;

assign out_clk = (cpt <= 1) &&  state != burst_init ? clk : 1'b0;

always @(negedge clk) begin
    if (en) begin
        case (state)
            burst_init: begin
                if (burst) begin
                    state <= burst_end;
                    cpt <= 2;
                end
            end
            burst_beg: begin
                if (!burst) begin
                    state <= burst_end;
                    cpt <= 2;
                end
                else if (cpt == 1) begin
                    cpt <= 2;
                end
                else if (cpt != 2)begin
                    cpt <= 1;
                end
            end 
            burst_end: begin
                if (burst) begin
                    state <= burst_beg; 
                    cpt <= 0;
                end
            end
            default: ;
        endcase
    end
end
endmodule

同时设计了上升沿触发的计数器模块test2,每来一个时钟上升沿计数加1,顶层将test1的out_clk作为test2的时钟输入。预期每次burst时计数器增加2,但将test1的always块触发沿从negedge clk改为posedge clk后,计数器多增加了1次,需解析原因。

原因解析

  • 触发沿切换导致时序对齐冲突
    当test1用下降沿触发时,状态机和cpt的更新发生在clk下降沿,此时out_clk的组合逻辑赋值基于更新前的状态,下一个clk上升沿到来时out_clk已经是稳定的有效电平,test2只会捕获到2个有效上升沿。
    改为上升沿触发后,状态机和cpt的更新与clk上升沿同步,out_clk作为组合逻辑会立即跟随状态变化。这就导致在同一个clk上升沿,test2先捕获到out_clk的上升沿(此时还是前一状态的有效电平),随后状态更新让out_clk立刻变化,额外产生的电平跳变被test2误判为有效沿,导致多计数。

  • 组合逻辑输出的时序毛刺
    out_clk是直接将clk通过组合逻辑选通输出,当test1在clk上升沿更新状态和cpt时,out_clk会在同一个时钟周期内发生电平切换。比如当cpt从1更新为2时,out_clk会立刻从clk跳转为0,这个跳变如果发生在clk上升沿之后、下降沿之前,test2的时钟输入会出现额外的高低电平变化,被误捕获为上升沿。

  • 状态切换与时钟沿的重叠干扰
    若burst信号变化与clk上升沿同步,状态机的切换会和时钟沿完全重叠。比如从burst_end切换到burst_beg时,cpt被设为0,out_clk立即允许clk通过,这个变化刚好发生在clk上升沿时刻,会让test2多捕获一次当前的上升沿,最终总计数比预期多1次。

总结

核心问题是上升沿触发的状态机更新与组合逻辑输出的out_clk在时序上重叠,导致test2的时钟输入出现额外有效沿或毛刺,最终多计数1次。下降沿触发时,状态更新和时钟沿错开,out_clk的变化不会和test2的采样沿冲突,因此符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 01:42:34