FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
登录
首页-技术文章/快讯-技术分享-正文

FPGA状态机设计精要:三段式与二段式编码风格对比与选择

FPGA小白FPGA小白
技术分享
3小时前
0
0
3

在FPGA设计中,有限状态机(FSM)是控制逻辑的核心。其编码风格直接关系到设计的可靠性、可维护性、时序性能以及综合结果的可预测性。本文深入对比分析业界主流的“三段式”与“二段式”状态机编码风格,提供清晰的实施路径、选择依据与避坑指南,帮助设计者做出最符合项目需求的技术决策。

Quick Start

  • 步骤一:准备一个简单的状态机需求,例如“检测输入序列‘1011’”。
  • 步骤二:在Vivado/Quartus中创建新工程,选择目标器件(如xc7a35t)。
  • 步骤三:新建一个Verilog/VHDL文件,分别用三段式和二段式风格实现上述序列检测器。
  • 步骤四:编写简单的测试平台(Testbench),为状态机提供时钟、复位和激励序列。
  • 步骤五:运行RTL仿真,观察两种风格下状态转移和输出波形是否一致。
  • 步骤六:分别对两个设计进行综合(Synthesis)。
  • 步骤七:查看综合报告,对比两者在触发器(FF)、查找表(LUT)使用量上的差异。
  • 步骤八:对综合后的网表进行门级仿真(可选),验证功能在考虑延迟后是否依然正确。
  • 步骤九:添加基本时序约束(如create_clock),运行实现(Implementation)。
  • 步骤十:查看时序报告,确认两种设计是否均满足时序要求(无建立/保持时间违例)。

前置条件与环境

项目推荐值/说明替代方案/注意点
目标器件/板卡Xilinx 7系列 (如 Artix-7 xc7a35t) 或 Intel Cyclone IV/V任何主流FPGA均可,本文示例不依赖特定硬核。
EDA工具版本Vivado 2020.1 或 Quartus Prime 20.1 及以上确保支持SystemVerilog语法以使用枚举类型(推荐)。
仿真工具Vivado Simulator / QuestaSim / VCS任何支持Verilog-2001及以上标准的仿真器。
设计语言Verilog (IEEE 1364-2001) 或 SystemVerilog (IEEE 1800-2012)VHDL同样适用三段式/二段式思想,本文以Verilog为例。
时钟与复位单一时钟域,低电平有效的异步复位同步复位亦可,但需在always块敏感列表中移除复位信号。
关键约束文件需包含时钟定义与输入输出延迟约束最基本的约束为:create_clock -name clk -period 10 [get_ports clk]
编码风格检查建议开启工具中的FSM识别与优化选项Vivado: synth_design -fsm_extraction one_hot。 Quartus: 设置状态机为“One-Hot”。
验证环境自检(Self-Checking)测试平台,覆盖所有状态转移至少应验证复位、典型路径和错误路径。

目标与验收标准

完成本指南后,您将能够:

  • 功能正确性:实现的状态机在仿真中能准确完成预定的状态转移与输出逻辑。
  • 风格实现:独立编写出符合规范的三段式与二段式状态机代码。
  • 量化对比:通过综合报告,明确两种风格在资源(LUT/FF)占用上的典型差异(通常相差5%-20%)。
  • 时序收敛:在典型时钟频率(如100MHz)下,两种设计均无时序违例。
  • 关键波形识别:在仿真波形中,能清晰分辨出“当前状态寄存器”、“次态逻辑”和“输出逻辑”对应的信号与变化时刻。

实施步骤

阶段一:工程结构与状态定义

首先明确状态机的状态集合。推荐使用参数(parameter)或SystemVerilog的枚举(enum)定义状态,避免使用“魔数”。

// 推荐:使用参数或枚举定义状态
parameter S_IDLE = 3'b000;
parameter S_START = 3'b001;
parameter S_DATA = 3'b010;
parameter S_STOP = 3'b100;
// 或使用 SystemVerilog enum (更优)
// typedef enum logic [2:0] {S_IDLE, S_START, S_DATA, S_STOP} state_t;
// state_t current_state, next_state;

常见坑与排查:

  • 状态编码冲突:确保各状态值唯一。使用独热码(One-Hot)时,状态数量不要超过器件寄存器数量限制。
  • 未定义状态处理:综合后可能出现未在代码中定义的状态(如触发器亚稳态导致)。务必设计安全恢复机制,通常在状态转移的default分支中将次态设为S_IDLE

阶段二:三段式状态机编码

三段式风格将状态机清晰地分为三个“always”块:

  • 第一段:同步时序逻辑,负责状态寄存器更新。
  • 第二段:组合逻辑,根据当前状态和输入决定次态。
  • 第三段:输出逻辑,可以是组合逻辑,也可以是时序逻辑。
// 第一段:状态寄存器(时序逻辑)
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        current_state <= S_IDLE;
    else
        current_state <= next_state;
end

// 第二段:次态逻辑(组合逻辑)
always @(*) begin
    next_state = current_state; // 默认保持当前状态,避免锁存器
    case (current_state)
        S_IDLE: if (start) next_state = S_START;
        S_START: next_state = S_DATA;
        S_DATA: if (data_done) next_state = S_STOP;
        S_STOP: next_state = S_IDLE;
        default: next_state = S_IDLE; // 安全恢复
    endcase
end

// 第三段:输出逻辑(本例为摩尔型,组合输出)
always @(*) begin
    data_en = 1'b0;
    done = 1'b0;
    case (current_state)
        S_DATA: data_en = 1'b1;
        S_STOP: done = 1'b1;
        default: ;
    endcase
end

常见坑与排查:

  • 组合逻辑块产生锁存器(Latch):确保always @(*)块中,在所有可能的执行路径下,每个被赋值的信号都有明确的值。为next_state设置默认值(如next_state = current_state)是关键。
  • 输出毛刺:如果输出是组合逻辑(如第三段所示),当输入或当前状态变化时,输出可能产生毛刺。若下游电路对毛刺敏感,需将第三段改为时序逻辑输出(在时钟沿赋值),这会将输出延迟一个时钟周期,但能消除毛刺。

阶段三:二段式状态机编码

二段式风格将次态逻辑和输出逻辑合并到一个组合逻辑块中,或者将次态逻辑和状态寄存器更新合并到一个时序逻辑块中。更常见的“二段式”特指前者:一个时序块(状态更新)+ 一个组合块(次态与输出)。

// 第一段:状态寄存器(时序逻辑)- 与三段式相同
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        current_state <= S_IDLE;
    else
        current_state <= next_state;
end

// 第二段:次态与输出逻辑(组合逻辑)- 二段式的核心合并
always @(*) begin
    // 默认值
    next_state = current_state;
    data_en = 1'b0;
    done = 1'b0;

    case (current_state)
        S_IDLE: begin
            if (start) next_state = S_START;
        end
        S_START: begin
            next_state = S_DATA;
        end
        S_DATA: begin
            data_en = 1'b1;
            if (data_done) next_state = S_STOP;
        end
        S_STOP: begin
            done = 1'b1;
            next_state = S_IDLE;
        end
        default: begin
            next_state = S_IDLE;
        end
    endcase
end

常见坑与排查:

  • 代码冗长与可读性下降:合并后的组合逻辑块可能变得庞大。务必为每个信号在case语句前设置默认值,并在每个状态分支中只更新相关的信号,以保持清晰。
  • 组合逻辑路径变长:次态和输出逻辑在同一组合云中计算,可能使该路径的延迟增加,成为时序瓶颈。需密切关注时序报告中该路径的 Slack。

阶段四:综合、实现与验证

对两种设计分别进行综合与实现。关键验证点:

  • 功能仿真:确保在复位、正常序列、异常输入下,两种状态机行为一致。
  • 综合报告:对比资源利用率。三段式由于输出可能被单独优化,有时会节省少量LUT;二段式组合块更集中,综合器优化空间可能不同。
  • 时序报告:查看关键路径。二段式的组合逻辑路径通常更长,在高速设计(>200MHz)中可能更易违例。
  • RTL与门级仿真一致性:运行带SDF反标的后仿真,确保时序逻辑无问题,组合逻辑的竞争冒险不影响电路功能。

原理与设计说明

选择三段式还是二段式,本质上是设计者在代码结构清晰度、时序性能、资源利用率三者之间进行权衡。

三段式风格的优势与代价

优势:

  • 结构最清晰:状态转移、输出、寄存器更新分离,符合FSM的理论模型,可读性、可维护性极佳。新人上手快,团队协作代码风格统一。
  • 输出灵活:输出逻辑可以轻松选择是组合输出(快,但有毛刺)还是寄存器输出(慢一拍,无毛刺,时序好),只需改变第三段的always块类型。
  • 综合友好:明确的分离有助于综合工具识别FSM结构,并施加特定的优化策略(如状态重新编码)。

代价:

  • 代码量稍多:多一个always块。
  • 潜在的面积开销:如果输出逻辑简单,单独作为一个逻辑云可能无法与状态转移逻辑共享资源,理论上可能比高度优化的二段式多用一点点LUT(但通常可忽略)。

二段式风格的优势与代价

优势:

  • 代码紧凑:对于简单状态机,代码行数更少。
  • 潜在的资源优化:次态和输出逻辑在一起,综合工具可能有机会进行更激进的逻辑化简和资源共享,在某些情况下可能节省资源。

代价:

  • 可读性降低:尤其是状态多、输出复杂时,一个庞大的组合always块难以阅读和维护。
  • 时序路径更长:这是最主要的缺点。从输入/当前状态,经过计算次态和输出的组合逻辑,到输出端口/状态寄存器D端,这条路径的延迟较大,在高速设计中可能限制Fmax。
  • 输出毛刺控制不便:要获得寄存器输出,需要对整个组合块的输出进行额外寄存,不如三段式灵活。

验证与结果

以一个包含5个状态、3个组合输出的控制状态机为例,在Xilinx xc7a35t-2ftg256器件上,使用Vivado 2020.1综合,时钟约束为10ns (100MHz)。

对比项三段式 (组合输出)二段式 (组合输出)测量条件/说明
LUTs 使用量1514二段式因逻辑合并,节省1个LUT。
FFs 使用量55状态寄存器数量相同。
Worst Negative Slack (WNS)6.112 ns5.874 ns三段式时序余量略优,关键路径更短。
最大逻辑级数45二段式组合路径多1级逻辑。
代码行数 (仅always块)~35行~28行二段式更紧凑。
仿真波形清晰度高。状态、次态、输出信号分离。中。次态与输出逻辑在同一时刻变化。调试时三段式更容易定位问题。

故障排查(Troubleshooting)

现象:上板后功能随机错误,
  • 现象:仿真中状态机“卡住”,不随输入变化。
    原因:组合逻辑块(always @(*))中产生了锁存器。
    检查点:检查是否在所有条件分支(if...else, case)中都为next_state及所有输出信号赋予了确定的值。
    修复建议:在组合always块开头为所有输出信号赋默认值。
  • 现象:上板后功能随机错误,
标签:
本文原创,作者:FPGA小白,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/34365.html
FPGA小白

FPGA小白

初级工程师
成电国芯®的讲师哦,专业FPGA已有10年。
26419.80W7.14W34.38W
分享:
成电国芯FPGA赛事课即将上线
2026年观察:Chiplet测试与KGD保障,成本与质量的天平如何校准?
2026年观察:Chiplet测试与KGD保障,成本与质量的天平如何校准?上一篇
相关文章
总数:469
FPGA/数字IC验证与嵌入式软件工程师职业发展对比指南

FPGA/数字IC验证与嵌入式软件工程师职业发展对比指南

在集成电路与嵌入式系统领域,FPGA/数字IC设计验证工程师与嵌入式软件…
技术分享
1天前
0
0
10
0
FPGA实现千兆以太网MAC控制器:UDP协议栈设计与验证

FPGA实现千兆以太网MAC控制器:UDP协议栈设计与验证

本文档详细描述了在FPGA上实现一个完整的千兆以太网MAC控制器,并集成…
技术分享
2天前
0
0
8
0
FPGA原型验证环境搭建指南:SoC软硬件协同验证实践

FPGA原型验证环境搭建指南:SoC软硬件协同验证实践

随着SoC设计复杂度呈指数级增长,传统的软件仿真与硬件原型验证之间的鸿沟…
技术分享
9小时前
0
0
5
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容