Mealy型有限状态机未在时钟沿触发状态变更的VHDL问题
Mealy型FSM输出随输入直接变化的问题分析与解决
核心原因
Mealy机的输出依赖当前状态+当前输入,但如果把输出写成组合逻辑(未在时钟沿触发的进程里赋值),就会出现输入变化时输出立刻更新、不等待时钟沿的情况。而Moore机的输出仅由状态(时序逻辑)决定,状态只在时钟沿更新,因此输出表现正常。
常见错误写法示例
直接用组合逻辑进程生成输出的错误写法:
-- 错误的Mealy输出写法(组合逻辑) process(i_state, i_input) begin case i_state is when S0 => if i_input = '1' then o_mealy <= '1'; else o_mealy <= '0'; end if; when S1 => o_mealy <= '0'; -- 其他状态分支 end case; end process;
这种写法下,i_input变化会直接触发进程,o_mealy无需等待时钟沿就会更新。
正确的同步写法
要让Mealy输出受时钟沿控制,需将输出赋值放到时序进程中,与状态更新同步:
-- 正确的Mealy输出写法(时序逻辑) process(clk, rst_n) begin if rst_n = '0' then o_mealy <= '0'; current_state <= S0; elsif rising_edge(clk) then -- 状态更新逻辑 current_state <= next_state; -- 同步生成Mealy输出 case current_state is when S0 => o_mealy <= i_input; when S1 => o_mealy <= '0'; -- 其他状态分支 end case; end if; end process;
也可以拆分状态进程与输出进程,但输出进程需基于寄存器后的状态和输入,且在时钟沿赋值:
-- 状态寄存器进程(时序) process(clk, rst_n) begin if rst_n = '0' then current_state <= S0; elsif rising_edge(clk) then current_state <= next_state; end if; end process; -- 输出进程(时序) process(clk, rst_n) begin if rst_n = '0' then o_mealy <= '0'; elsif rising_edge(clk) then case current_state is when S0 => if i_input = '1' then o_mealy <= '1'; else o_mealy <= '0'; end if; when S1 => o_mealy <= '0'; -- 其他状态分支 end case; end if; end process;
修改后输出只会在时钟上升沿更新,不会随输入直接变化。
额外注意点
- 组合逻辑输出易产生毛刺,同步到时钟沿后可消除大部分毛刺,符合时序电路设计规范。
- 异步Mealy机虽存在,但FPGA/ASIC设计中更推荐同步输出的Mealy机,保证时序稳定性。
内容的提问来源于stack exchange,提问作者First User
相关产品推荐
相关产品推荐

