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

Mealy状态机代码输出异常,状态图无法显示求排查与指导

Mealy状态机问题分析与代码修正

问题现象

  • 仿真后出现don't-care输出
  • 状态图查看器无法正常解析状态逻辑

原代码问题根源

1. 状态编码未完全覆盖

状态寄存器定义为[1:0],共包含4种可能编码(00/01/10/11),但仅显式定义了s0/s1/s2三个状态,遗漏了11编码对应的状态。综合器会将未定义状态视为无关项,直接导致don't-care输出,同时状态图工具因状态逻辑不完整无法正确解析。

2. 组合逻辑块存在漏洞

  • 两个组合逻辑always块均未设置默认分支,当状态进入未定义的11编码时,次态和输出会变为不确定值。
  • 测试平台中rst_n仅初始拉低一次,随机输入的切换时机未对齐时钟边沿,增加了亚稳态风险和输出不确定性。

3. 状态机鲁棒性不足

未对异常状态(未定义编码)做跳转处理,状态机可能进入死锁,进一步加剧输出异常。

修正后的状态机代码

module mealy(input x_in, rst_n, clk, output reg y_out);

parameter s0 = 2'b00, s1 = 2'b01, s2 = 2'b10, s_undef = 2'b11;
reg [1:0] p_state, n_state;

// 状态寄存器时序逻辑
always@(posedge clk, negedge rst_n) begin
    if(!rst_n) 
        p_state <= s0;
    else 
        p_state <= n_state;
end

// 次态组合逻辑:覆盖所有状态编码
always@(*) begin
    case(p_state)
        s0:     n_state = x_in ? s2 : s1;
        s1:     n_state = x_in ? s2 : s1;
        s2:     n_state = x_in ? s2 : s1;
        s_undef:n_state = s0; // 异常状态跳转回初始态
        default:n_state = s0; // 双重保险,覆盖所有未匹配情况
    endcase
end

// 输出组合逻辑:设置默认值避免不确定输出
always@(*) begin
    y_out = 1'b0; // 默认输出0,再通过case覆盖特定情况
    case(p_state)
        s0:     y_out = 1'b0;
        s1:     y_out = x_in ? 1'b1 : 1'b0;
        s2:     y_out = !x_in ? 1'b1 : 1'b0;
        s_undef:y_out = 1'b0; // 异常状态输出0
    endcase
end

endmodule

修正后的测试平台代码

module mealy_tb;

reg x_in, rst_n, clk;
wire y_out;

mealy dut(x_in, rst_n, clk, y_out);

// 时钟生成
initial begin
    clk = 1'b0;
    forever #10 clk = ~clk;
end

// 激励生成:规范复位时序,对齐时钟边沿
initial begin
    rst_n = 1'b0;
    x_in = 1'b0;
    #20; // 复位保持2个时钟周期,确保状态稳定
    rst_n = 1'b1;
    
    // 随机输入对齐时钟上升沿,避免亚稳态
    repeat(1000) begin
        @(posedge clk);
        x_in = {$random};
    end
    $finish; // 主动结束仿真
end

// 波形监控(可选,方便调试)
initial begin
    $monitor("Time:%0t, clk:%b, rst_n:%b, x_in:%b, p_state:%b, y_out:%b", 
             $time, clk, rst_n, x_in, dut.p_state, y_out);
end

endmodule

状态机编写核心规范

  • 状态编码全覆盖:确保所有可能的寄存器编码都有对应状态定义或默认处理逻辑,杜绝无关项。
  • 组合逻辑用always@(*):自动包含所有敏感信号,避免手动遗漏导致的时序问题。
  • 设置默认值:组合逻辑块开头先设置输出/次态的默认值,再通过case覆盖特定情况,保证所有分支都有定义。
  • 异常状态处理:将未用到的编码状态跳转回初始态,防止状态机死锁。
  • 测试平台严谨性:复位信号保持足够时长,输入切换对齐时钟边沿,添加仿真结束语句和监控逻辑,便于调试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:43:10