VHDL实现的Mealy型FSM饮料售货机卡在Finalizing状态问题
Mealy型饮料售货机FSM卡在Finalizing状态故障排查与解决
故障核心现象
实现的饮料售货机Mealy FSM包含三个状态:
- Accumulating:累计投入金额(上限10货币单位)
- Dispensing:单周期输出商品
- Finalizing:执行找零逻辑,预期优先输出5lei,再输出1lei,余额归0后返回Accumulating
实际运行时,FSM卡在Finalizing状态,leu1_rest持续触发,无法回到Accumulating状态。
常见故障原因分析
- 找零优先级逻辑缺失/错误
未正确实现“先出5lei再出1lei”的优先级,导致余额无法快速归0,或始终进入减1的分支,形成死循环。 - 余额更新与状态跳转不同步
若balance通过组合逻辑更新,而非时钟同步的寄存器操作,会导致余额值出现毛刺或持续变化,状态跳转条件无法正确触发。 - Finalizing状态跳转条件遗漏
未在余额归0时明确触发状态跳转,或跳转条件判断基于未更新的余额值,导致FSM始终停留在Finalizing。 - 找零请求信号异常
若cerere_rest持续拉高而非脉冲触发,可能导致Finalizing状态被反复触发,干扰正常的找零流程。
针对性解决办法
1. 修正Finalizing状态的找零逻辑
确保在时钟同步的进程内,先判断余额是否满足5lei找零条件,再处理1lei找零,最后在余额为0时跳转状态:
process(clk, reset) begin if reset = '1' then current_state <= Accumulating; balance <= 0; leu1_rest <= '0'; lei5_rest <= '0'; -- 初始化其他输出信号 elsif rising_edge(clk) then -- 默认输出置0,避免 latch 生成 leu1_rest <= '0'; lei5_rest <= '0'; case current_state is when Accumulating => -- 原有累计金额逻辑(处理leu1/lei5/lei10输入,上限10) -- 处理商品选择跳转至Dispensing,或找零请求跳转至Finalizing when Dispensing => -- 单周期商品输出逻辑 -- 输出完成后,根据余额是否大于0跳转至Finalizing或直接返回Accumulating current_state <= Finalizing; when Finalizing => if balance > 0 then -- 优先找零5lei if balance >= 5 then lei5_rest <= '1'; balance <= balance - 5; else -- 余额不足5时找零1lei leu1_rest <= '1'; balance <= balance - 1; end if; -- 余额未清,保持Finalizing状态 else -- 余额归0,返回Accumulating current_state <= Accumulating; end if; end case; end if; end process;
2. 确保余额为同步寄存器
禁止用组合逻辑更新balance,必须将其放在时钟触发的进程内作为寄存器变量/信号,避免异步更新导致的逻辑不稳定。
3. 校验找零请求信号的激励逻辑
在测试平台中,确保cerere_rest是脉冲信号(仅在一个时钟周期内拉高),而非持续高电平,防止Finalizing状态被重复触发。
4. 检查状态跳转的条件判断
确保在Finalizing状态中,跳转至Accumulating的条件是balance = 0,且该判断基于更新后的余额值(同步逻辑下,余额更新和状态判断在同一个时钟沿完成,无需额外延迟)。
内容的提问来源于stack exchange,提问作者Antonius Florea
相关产品推荐
相关产品推荐

