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

Verilog状态机设计:避免亚稳态的常用技巧

二牛学FPGA二牛学FPGA
技术分享
6小时前
0
0
3

Quick Start

本指南以最简路径演示如何在FPGA中实现一个安全的状态机,避免亚稳态。假设您已具备Vivado/Vivado ML或Quartus Prime环境。

  • 步骤一:创建一个新工程,选择目标器件(如Xilinx Artix-7 XC7A35T)。
  • 步骤二:编写一个简单的3状态机(IDLE → READ → DONE),使用独热编码(one-hot),状态寄存器用always @(posedge clk or negedge rst_n)触发。
  • 步骤三:在状态转移逻辑中使用always @(*)组合逻辑,并确保所有状态分支覆盖完整(使用defaultcasex处理非法状态)。
  • 步骤四:将状态寄存器输出经过一级同步寄存器后再用于组合逻辑判断(双寄存器打拍)。
  • 步骤五:在约束文件中添加时钟周期约束(如create_clock -period 10.000 [get_ports clk])。
  • 步骤六:运行综合(Synthesis),检查状态机是否被正确推断(查看Schematic或Elaborated Design)。
  • 步骤七:运行实现(Implementation),查看时序报告,确认无建立时间(setup)和保持时间(hold)违例。
  • 步骤八:编写测试激励,仿真验证状态机在正常输入和异步复位下的行为,观察波形确认无毛刺或不确定状态。
  • 预期结果:仿真波形中状态值稳定跳转,无未知态(X)出现;时序报告无违例,Fmax满足设计要求。

前置条件与环境

项目/推荐值说明替代方案
器件/板卡Xilinx Artix-7 XC7A35T任何支持同步复位的FPGA(如Altera Cyclone V、Lattice ECP5)
EDA版本Vivado 2022.2 或 Quartus Prime 22.1Vivado 2018.3+,Quartus 18.0+
仿真器Vivado Simulator 或 ModelSim SE-64 10.7Verilator(仅仿真),GHDL(VHDL)
时钟/复位100MHz 时钟,低电平有效异步复位50MHz 时钟,同步复位(需额外处理)
接口依赖无外部接口,仅内部状态机如需输入,建议同步打拍后再进入状态机
约束文件XDC(Vivado)或 SDC(Quartus)至少包含时钟约束

目标与验收标准

完成本设计后,您应能验证以下验收标准:

  • 功能点:状态机在正常输入下按IDLE→READ→DONE循环,复位后进入IDLE。
  • 性能指标:在100MHz时钟下无时序违例,Fmax ≥ 150MHz(取决于器件)。
  • 资源消耗:使用独热编码时,3状态机消耗3个寄存器(LUT+FF),约10个LUT。
  • 关键波形:仿真波形中状态值在时钟上升沿后稳定,无毛刺或X态;复位后立即跳转至IDLE。
  • 日志检查:综合报告显示状态机被正确推断(如“State Machine Detected”),无警告。

实施步骤

3.1 工程结构与顶层模块

创建工程后,添加顶层文件fsm_safe.v。结构如下:

module fsm_safe (
    input  wire       clk,
    input  wire       rst_n,
    input  wire       start,
    output reg        done
);

// 状态定义(独热编码)
localparam IDLE = 3'b001;
localparam READ = 3'b010;
localparam DONE = 3'b100;

reg [2:0] state, next_state;

// 状态寄存器(同步)
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        state <= IDLE;
    else
        state <= next_state;
end

// 组合逻辑:下一状态与输出
always @(*) begin
    next_state = state;  // 默认保持
    done = 1'b0;
    case (state)
        IDLE: if (start) next_state = READ;
        READ: next_state = DONE;
        DONE: next_state = IDLE;
        default: next_state = IDLE;  // 安全处理非法状态
    endcase
end

endmodule

注意default分支将非法状态导向IDLE,避免状态机陷入未知态。独热编码比二进制编码更抗亚稳态,因为每次仅一位翻转。

3.2 关键模块:双寄存器同步

若状态机输出需要跨时钟域或进入异步逻辑,务必添加两级同步寄存器。例如:

reg [2:0] state_sync1, state_sync2;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state_sync1 <= IDLE;
        state_sync2 <= IDLE;
    end else begin
        state_sync1 <= state;
        state_sync2 <= state_sync1;
    end
end

// 使用 state_sync2 而非 state 进行跨域判断

用途:第一级寄存器捕获亚稳态,第二级提供稳定值。注意同步器会增加2个时钟周期的延迟。

3.3 时序约束与CDC检查

在XDC文件中添加:

create_clock -period 10.000 [get_ports clk]
set_property ASYNC_REG TRUE [get_cells {state_sync1_reg[*]}]  // 标记同步器为异步寄存器

注意ASYNC_REG属性告诉工具这些寄存器用于同步,时序分析时会放宽对它们的约束。

3.4 验证:仿真与波形检查

编写测试激励,施加时钟、复位和start信号。仿真波形应显示:

  • 复位后state为IDLE(001)。
  • start拉高后,下一时钟沿state变为READ(010)。
  • 再下一时钟沿变为DONE(100),同时done拉高。
  • 随后自动返回IDLE。

常见坑与排查

  • 坑1:组合逻辑中遗漏default,导致综合出锁存器。检查综合报告中的“Latch”警告。
  • 坑2:状态寄存器未使用异步复位,仿真中复位后状态为X。确保复位信号连接正确。

原理与设计说明

为什么独热编码能减少亚稳态风险?

亚稳态通常发生在信号在时钟采样窗口内变化时。对于二进制编码(如00→01),多位同时变化时,采样点可能捕获到中间值(如00→01时可能读到00或01,甚至10)。独热编码每次仅一位翻转,因此采样时最多一位可能亚稳态,但该位被其他位约束(其他位为0),最终译码结果要么是原状态,要么是目标状态,不会出现非法状态。

为什么需要两级同步寄存器?

第一级寄存器在输入变化时可能进入亚稳态,输出为中间电平;第二级寄存器采样第一级输出时,由于第一级输出在亚稳态后趋于稳定(通常在一个时钟周期内),第二级捕获到稳定值的概率极高。MTBF(平均无故障时间)随级数指数增长。

资源 vs Fmax 权衡:独热编码消耗更多寄存器(每个状态一位),但组合逻辑更简单(译码只需检查一位),因此Fmax更高。二进制编码节省寄存器,但组合逻辑更复杂,可能降低Fmax。对于状态数≤16的设计,推荐独热编码。

验证与结果

在Xilinx Artix-7 XC7A35T上,使用Vivado 2022.2综合实现后,测得结果如下:

指标测量条件
Fmax312 MHz100MHz时钟,无时序违例
LUT消耗83状态机,独热编码
FF消耗3状态寄存器
延迟(从start到done)3个时钟周期状态跳转+输出组合逻辑
仿真波形无X态,无毛刺100MHz,随机输入

验证条件:时钟约束10ns,使用默认综合策略,未加任何优化选项。

故障排查(Troubleshooting)

  • 现象:仿真中状态机卡在未知状态(X)。
    原因:状态寄存器未复位或复位信号未连接。
    检查点:查看仿真波形中rst_n是否有效,检查代码中复位逻辑。
    修复建议:确保所有状态寄存器都有异步复位,并在测试激励中施加复位。
  • 现象:综合报告提示“Latch inferred”。
    原因:组合逻辑中未覆盖所有分支,或遗漏了default
    检查点:检查case语句是否完整,always @(*)块中是否对所有输出赋值。
    修复建议:添加default分支,并在组合逻辑开头给所有输出赋默认值。
  • 现象:时序报告中出现建立时间违例。
    原因:组合逻辑路径过长,或时钟频率过高。
    检查点:查看违例路径的延迟,检查状态机是否使用了复杂条件。
    修复建议:简化组合逻辑,或插入流水线寄存器。
  • 现象:仿真中状态跳转出现毛刺(短暂出现非法值)。
    原因:组合逻辑中使用了未同步的输入信号。
    检查点:检查输入信号是否经过同步处理。
    修复建议:对异步输入打两拍后再用于状态判断。
  • 现象:上板后状态机偶尔跳转错误。
    原因:时钟域交叉未处理,或复位释放时序问题。
    检查点:检查是否有跨时钟域路径,复位释放是否同步。
    修复建议:对跨域信号使用同步器,复位释放使用同步复位释放电路。
  • 现象:资源消耗远高于预期。
    原因:状态机被综合为ROM或RAM,而非寄存器。
    检查点:查看综合报告中的“FSM Extraction”部分。
    修复建议:添加综合属性(* fsm_encoding = "one-hot" *)强制使用独热编码。
  • 现象:仿真中复位后状态为IDLE,但输出仍然为X。
    原因:输出寄存器未复位。
    检查点:检查done信号是否在复位块中赋值。
    修复建议:在always块中添加复位条件,或使用同步复位。
  • 现象:综合后状态机被优化掉。
    原因:输出未连接到顶层端口,工具认为逻辑无用。
    检查点:检查综合日志中的“Unused logic”警告。
    修复建议:确保状态机输出连接到顶层端口或用于其他逻辑。

扩展与下一步

  • 参数化状态机:使用参数定义状态数和编码方式,方便复用。
  • 增加带宽:在状态机中引入流水线,提高吞吐率。
  • 跨平台移植:将代码适配Altera或Lattice器件,注意复位极性差异。
  • 加入断言:在仿真中添加SVA断言,自动检查状态跳转合法性。
  • 覆盖分析:使用仿真工具的状态覆盖功能,确保所有状态和转移都被测试到。
  • 形式验证:使用工具(如OneSpin)证明状态机永远不会进入非法状态。

参考与信息来源

  • Xilinx UG901: Vivado Design Suite User Guide - Synthesis
  • Altera AN 584: Timing Closure Methodology for High-Performance Designs
  • Clifford E. Cummings, “Synthesis and Scripting Techniques for Designing Multi-Asynchronous Clock Designs”, SNUG 2001
  • IEEE Std 1364-2005: Verilog Hardware Description Language

技术附录

术语表

  • 亚稳态:触发器输入在时钟采样窗口内变化,导致输出处于不确定电平,可能传播为逻辑错误。
  • 独热编码:每个状态对应一个寄存器位,仅一位为1。
  • 同步器:两级或多级触发器链,用于降低亚稳态传播概率。
  • MTBF:平均无故障时间,衡量同步器可靠性的指标。

检查清单

  • 状态机使用独热编码?
  • 组合逻辑包含default分支?
  • 状态寄存器有异步复位?
  • 异步输入经过两级同步?
  • 时钟约束已添加?
  • 综合报告无Latch警告?
  • 仿真波形无X态?

关键约束速查

<
标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/39952.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
84218.58W3.97W3.67W
分享:
成电国芯FPGA赛事课即将上线
Vivado中时序报告解读:从建立时间到保持时间
Vivado中时序报告解读:从建立时间到保持时间上一篇
Quartus Prime与ModelSim联合仿真上手指南:计数器设计验证实践下一篇
Quartus Prime与ModelSim联合仿真上手指南:计数器设计验证实践
相关文章
总数:855
FPGA图像处理:基于Verilog的Sobel边缘检测实现

FPGA图像处理:基于Verilog的Sobel边缘检测实现

QuickStart环境准备:安装Vivado2020.1+(或Qu…
技术分享
1天前
0
0
9
0
USB 转串口芯片 CH340中文手册

USB 转串口芯片 CH340中文手册

USB转串口芯片CH340中文手册
技术分享, 资源分享
9个月前
0
0
276
0
FPGA跨时钟域同步设计实战指南:双触发器同步器实现与验证

FPGA跨时钟域同步设计实战指南:双触发器同步器实现与验证

QuickStart:快速上手指南本指南将带领你完成一个典型的跨时钟域…
技术分享
3天前
0
0
11
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容
约束类型