状态机分三段式(现态寄存器+次态组合+输出组合)和一段式(全写在一个 always),推荐三段式:时序清晰、易综合、时序收敛好;输出用寄存器输出避免毛刺,状态编码用 one-hot 或 binary 看资源和速度。
本文概述
状态机是 FPGA 设计核心,面试常考:一段/二段/三段式区别、独热码 vs 二进制、输出毛刺、复位。回答要能写出三段式骨架并说出为什么推荐三段式。
核心要点
三段式:1)现态寄存器时序逻辑 2)次态组合逻辑 3)输出寄存器时序逻辑,推荐
一段式:所有逻辑写一个 always,组合时序混在一起,难维护、时序差
状态编码:binary(省资源)、gray(低功耗)、one-hot(快、触发器多)
输出用寄存器输出(Moore 型)避免组合逻辑毛刺,Mealy 型输出跟输入和状态都有关
复位用异步复位同步释放,状态机复位到 IDLE

面试官考察点
面试官看你是否真写过状态机、是否理解三段式结构,而不是背概念。重点听:三个 always、状态编码、输出寄存器。
回答思路
先讲三段式结构,再给骨架代码,最后讲按键消抖和长短按判断。
参考回答
三段式结构。
| 段 | 逻辑 | 描述 |
|---|---|---|
| 第一段 | 时序 | 现态寄存器:current_state <= next_state |
| 第二段 | 组合 | 次态逻辑:根据 current_state 和输入算 next_state |
| 第三段 | 时序 | 输出寄存器:根据 current_state 输出,避免毛刺 |
骨架代码。
reg [2:0] current_state, next_state;
// 第一段:现态寄存器
always @(posedge clk or negedge rst_n)
if(!rst_n) current_state <= IDLE;
else current_state <= next_state;
// 第二段:次态组合
always @(*) begin
case(current_state)
IDLE: if(key_press) next_state = WAIT_HOLD;
WAIT_HOLD: if(key_release) next_state = IDLE;
else if(hold_cnt>=THRESH) next_state = LONG;
default: next_state = IDLE;
endcase
end
为什么推荐三段式。
时序清晰:三段分开,每段功能单一,易读易维护;
时序收敛好:第二段组合逻辑短,第三段寄存器输出,FPGA 综合器容易优化;
无毛刺:输出用寄存器,不是组合逻辑直接输出,避免毛刺。
状态编码选择。
| 编码 | 资源 | 速度 | 适用 |
|---|---|---|---|
| Binary | 少(n 个状态需 log2n 触发器) | 较慢 | 状态多、资源紧 |
| One-hot | 多(n 个触发器) | 快(无译码) | 状态少、速度高(Xilinx 推荐) |
| Gray | 少 | 中 | 低功耗、跨时钟域 |
按键长短按判断。IDLE 检测到按下→WAIT_HOLD,同时启动计数器;到阈值(如 1s)进 LONG;释放则判 SHORT。按键要先消抖(20ms 稳定)。

扫码关注





























