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

交通控制器仿真仅执行1个时钟周期问题排查求助

问题定位与修复方案

核心问题:组合逻辑环路引发仿真异常

你的代码存在组合逻辑环路,这是导致仿真时信号跳变、提前停止的根本原因:

  • count变量在组合逻辑块(always @(current_state))中被赋值,但该变量同时作为这个逻辑块的判断条件(if(count < 5)),而敏感列表仅包含current_state。这种设计会让仿真器陷入无限循环的组合逻辑计算,直接触发仿真异常。
  • 另外,count属于时序逻辑变量,本应在时钟沿更新,却被错误地放在组合逻辑中修改,违背了时序电路的设计规范。

修复步骤

1. 重构count的更新逻辑

将count的更新移至时序逻辑块,和current_state同步在时钟沿更新:

// 时序逻辑:更新状态与计数器
always @ (posedge clk_i or negedge rst_i) begin
    if (!rst_i) begin
        current_state <= s0;
        count <= 0;
    end else begin
        current_state <= next_state;
        // 若状态未切换,计数器自增;切换则清零
        if (next_state == current_state) begin
            count <= count + 1;
        end else begin
            count <= 0;
        end
    end
end

2. 修改组合逻辑的状态转移判断

组合逻辑块仅负责根据current_state和count计算next_state,不再修改count,同时修正敏感列表(添加count):

// 组合逻辑:计算下一个状态
always @ (current_state, count) begin
    case(current_state) 
        s0  :   next_state = (count < 5) ? s0 : s1;
        s1  :   next_state = (count < 1) ? s1 : s2;
        s2  :   next_state = (count < 1) ? s2 : s3;
        s3  :   next_state = (count < 5) ? s3 : s4;
        s4  :   next_state = (count < 1) ? s4 : s5;
        s5  :   next_state = (count < 1) ? s5 : s0;
        default : next_state = s0; 
    endcase
end

3. 规范赋值风格

组合逻辑中统一使用阻塞赋值(=),时序逻辑使用非阻塞赋值(<=),符合Verilog设计的最佳实践。

完整修复后的traffic_top模块代码

module traffic_top (
    input                   clk_i,
    input                   rst_i,

    output  logic   [2:0]   light_A_o,
    output  logic   [2:0]   light_B_o

);

    // 独热码定义状态
    parameter   s0 = 6'b000001,
                s1 = 6'b000010,
                s2 = 6'b000100,
                s3 = 6'b001000,
                s4 = 6'b010000,
                s5 = 6'b100000;

    reg [5:0] current_state, next_state;
    reg [2:0] count;

    // 时序逻辑:更新状态与计数器
    always @ (posedge clk_i or negedge rst_i) begin
        if (!rst_i) begin
            current_state <= s0;
            count <= 0;
        end else begin
            current_state <= next_state;
            if (next_state == current_state) begin
                count <= count + 1;
            end else begin
                count <= 0;
            end
        end
    end

    // 组合逻辑:计算下一个状态
    always @ (current_state, count) begin
        case(current_state) 
            s0  :   next_state = (count < 5) ? s0 : s1;
            s1  :   next_state = (count < 1) ? s1 : s2;
            s2  :   next_state = (count < 1) ? s2 : s3;
            s3  :   next_state = (count < 5) ? s3 : s4;
            s4  :   next_state = (count < 1) ? s4 : s5;
            s5  :   next_state = (count < 1) ? s5 : s0;
            default : next_state = s0; 
        endcase
    end

    // 输出信号灯逻辑
    always @ (*) begin
        case(current_state)
            s0  :       begin   light_A_o = 3'b001; light_B_o = 3'b100; end
            s1  :       begin   light_A_o = 3'b010; light_B_o = 3'b100; end
            s2  :       begin   light_A_o = 3'b100; light_B_o = 3'b100; end
            s3  :       begin   light_A_o = 3'b100; light_B_o = 3'b001; end
            s4  :       begin   light_A_o = 3'b100; light_B_o = 3'b010; end
            s5  :       begin   light_A_o = 3'b100; light_B_o = 3'b100; end
            default :   begin   light_A_o = 3'b100; light_B_o = 3'b100; end
        endcase
    end

    
endmodule

仿真验证说明

修复后仿真将正常运行:

  • 复位后从s0状态启动,count在每个时钟周期自增,达到设定值后切换状态并清零计数器。
  • 信号灯将按照红、黄、绿的预期时序切换,不会再出现信号跳变或提前停止的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:45:31