---
title: FPGA有限状态机（FSM）设计实践指南：三段式与二段式编码风格对比与实现
url: "https://www.fpgalearn.com/31357.html"
kind: article
id: 31357
excerpt: 有限状态机（Finite State Machine, FSM）是数字逻辑设计的核心模式，用于描述具有有限个状态并按特定条件进行状态转移的系统。在FPGA设计中…
published_at: 2026-04-11
author: 二牛学FPGA
tags: fpga, FSM, 有限状态机
word_count: 2797
source: "https://www.fpgalearn.com"
---

# FPGA有限状态机（FSM）设计实践指南：三段式与二段式编码风格对比与实现

> 标签：fpga、FSM、有限状态机
> 有限状态机（Finite State Machine, FSM）是数字逻辑设计的核心模式，用于描述具有有限个状态并按特定条件进行状态转移的系统。在FPGA设计中…

> 有限状态机（Finite State Machine, FSM）是数字逻辑设计的核心模式，用于描述具有有限个状态并按特定条件进行状态转移的系统。在FPGA设计中…

有限状态机（Finite State Machine, FSM）是数字逻辑设计的核心模式，用于描述具有有限个状态并按特定条件进行状态转移的系统。在FPGA设计中，FSM的编码风格直接影响其可读性、可维护性、时序性能以及综合结果的可预测性。本文旨在提供一份从快速上手到深度优化的完整设计指南，通过对比业界主流的三段式与二段式编码风格，帮助开发者做出更优的工程选择。
## 快速上手
本指南将引导您完成两种不同风格FSM的设计、实现与验证流程。您将首先创建一个基础工程框架，然后分别实现三段式和二段式FSM，最后通过仿真与综合对比其差异。
## 前置条件与环境
- **硬件平台**：任意支持HDL综合的FPGA开发板。
- **软件工具**：Vivado、Quartus Prime或同等FPGA开发套件。
- **基础知识**：熟悉Verilog或VHDL硬件描述语言，了解同步时序电路设计基础。
## 目标与验收标准
完成本指南后，您将能够：
- 理解三段式与二段式FSM的代码结构与设计哲学。
- 独立实现两种编码风格的FSM模块。
- 通过综合报告与仿真波形，评估不同风格在时序、资源及可靠性方面的差异。
## 实施步骤
### 阶段一：工程结构与模块定义
- **创建顶层模块**：新建一个Verilog模块（如`fsm_top`），明确时钟（clk）、复位（rst_n）、输入信号和输出信号的端口定义。
- **定义状态常量**：使用`parameter`或`localparam`定义状态机的所有状态（如`IDLE`, `WORK`, `DONE`）。建议使用独热码（One-Hot）或格雷码（Gray Code）进行编码，以优化时序或降低功耗。
### 阶段二：三段式FSM编码实现
三段式风格将设计清晰地分为三个独立的always块，职责分离明确：
1. **状态寄存器更新（时序逻辑）**：在时钟边沿，将次态（next_state）赋值给当前状态（current_state）。这是唯一包含寄存器（触发器）的always块。
1. **次态逻辑（组合逻辑）**：根据当前状态和输入条件，使用`case`或`if-else`语句计算下一个状态的值。
1. **输出逻辑（组合逻辑或时序逻辑）**：根据当前状态（Moore型）或当前状态与输入（Mealy型）产生输出。为优化时序和消除毛刺，强烈建议将此部分输出寄存器化，即也用时序逻辑实现。
### 阶段三：二段式FSM编码实现
二段式风格将逻辑合并为两部分：
1. **状态寄存器更新（时序逻辑）**：与三段式第一段完全相同。
1. **次态与输出逻辑（组合逻辑）**：在一个组合always块中，同时根据当前状态和输入计算次态和输出。这导致输出逻辑与状态转移逻辑紧密耦合。
## 验证与结果
分别对两种设计进行以下验证：
- **功能仿真**：编写测试平台（Testbench），验证状态转移和输出是否符合预期。
- **综合与实现**：运行综合工具，对比两份报告的差异，重点关注：
- **时序裕量（Slack）**：三段式因输出寄存器化，通常关键路径更短，时序更优。
- **资源消耗**：三段式可能因额外寄存器而多用一些触发器，但组合逻辑可能更简化。
- **警告信息**：二段式设计更容易因代码不完整而意外推断出锁存器（Latch）。
## 故障排查
- **综合时序不达标**：检查关键路径报告。对于二段式，关键路径可能包含复杂的输出逻辑；对于三段式，确保输出已寄存器化。可尝试流水线或重新划分组合逻辑。
- **状态机卡死或跳转异常**：仿真检查状态转移条件是否覆盖所有情况。在每个`case`语句中务必添加`default`分支，并赋予一个安全状态（如`IDLE`）。
- **出现锁存器（Latch）警告**：此问题在二段式中更常见。确保描述组合逻辑的always块中，在所有可能的执行路径下，每个被赋值的变量都有明确的值。使用`always @(*)`并初始化所有变量。
- **输出存在毛刺**：这是组合逻辑输出的固有风险。最有效的解决方案是将输出通过寄存器打一拍（即采用三段式中的寄存器化输出），用单个时钟周期延迟换取信号的绝对稳定。
## 原理与设计说明
### 为什么推荐三段式风格？
三段式风格的核心优势在于其清晰的**职责分离**，这并非仅为代码美观，而是带来了深层的工程效益：
- **时序优化友好**：寄存器到寄存器的路径是FPGA时序引擎优化得最好的路径。三段式将输出寄存器化后，关键路径被严格限制在“次态逻辑”这一段组合逻辑内，工具更容易优化以满足时序约束。
- **避免毛刺，提升可靠性**：寄存器输出从根本上消除了组合逻辑竞争冒险产生的毛刺，使系统输出稳定可靠，这对驱动外部设备或作为其他模块的使能信号至关重要。
- **综合结果可预测**：代码结构与硬件映射关系清晰。状态寄存器、次态逻辑、输出寄存器分别对应明确的硬件资源，减少了综合工具进行意外推断的风险。
- **可维护性与可调试性极强**：任何状态的输出仅与当前状态寄存器相关，修改输出逻辑或状态转移逻辑时影响范围小，且仿真波形中输出信号干净整齐，便于调试。
### 二段式风格的应用场景与权衡
二段式风格将次态与输出逻辑合并，其优势在于代码紧凑，对于简单的、输出直接依赖于当前输入（Mealy型）的状态机，书写可能更直观。但其主要权衡在于：
- **性能与复杂度权衡**：输出逻辑被并入关键路径，可能降低系统最高工作频率。当输出逻辑复杂时，这一问题会加剧。
- **可靠性与简洁性权衡**：组合输出易产生毛刺。代码合并后，更容易因编写疏忽（如条件分支不全）而产生锁存器，引入难以排查的异步逻辑风险。
## 结论性建议
在FPGA设计中，**除非是对输出延迟极其敏感（要求输入变化在同一时钟周期内立刻反映在输出上）且输出逻辑极其简单的特定场景，否则应优先使用三段式风格，并务必将输出寄存器化**。这是一种以极小的、固定为一个时钟周期的延迟代价，换取电路可靠性、时序性能和设计可维护性的最佳工程实践。对于初学者和大多数项目，三段式是更安全、更高效的选择。
## 扩展与下一步
- **参数化状态机设计**：使用SystemVerilog的`typedef`定义枚举类型的状态变量，提升代码类型安全性和可读性。
- **加入断言（Assertion）**：在代码中嵌入形式验证断言，用于仿真时自动检查状态机的合法跳转、互斥输出等属性。
- **实现安全状态机**：设计上电复位后自动进入安全状态，并在运行中通过“看门狗”逻辑检测异常状态，强制跳回安全状态。
- **跨时钟域（CDC）状态机同步**：研究当状态机信号需要穿越不同时钟域时，如何安全地使用两级同步器进行同步，避免亚稳态传播。
