1. 前言:FPGA 没有玄学,只有你没查到的点
很多人做 FPGA 项目,上板后总会遇到各种'离谱'现象,越查越懵,总以为是芯片坏了、是玄学,其实都是有迹可循的:
- 有时正常、有时不正常,没有固定规律;
- 仿真全对、波形完美,一上板就报错、跑飞;
- 拍一下板子就好,动一下接线、碰一下芯片就挂;
- 低频运行一切正常,频率一拉高就乱码、死机。
核心观点:绝大多数此类问题并非 FPGA 芯片本身的问题,而是代码、约束、硬件接线等细节未处理好。以下 10 个 BUG 覆盖了大部分'玄学故障',掌握排查思路可快速定位。
2. BUG 1:复位接法错误(占比最高,新手首踩坑)
现象:上电不稳定、程序随机出错、状态机乱跑,有时上电正常,重启后就出问题,甚至偶尔死机后重启又恢复。
原因:
- 复位电平搞反:代码里写的高有效复位(rst),硬件接成低有效(rst_n),或反之;
- 复位没有做同步:直接把按键信号硬拉当复位,没有加同步释放电路,异步复位信号不稳定;
- 多个复位网络干扰:工程里有多个复位信号(比如模块复位、全局复位),没有统一管理,互相干扰。
排查思路:
- 第一步:核对复位电平,确保硬件接线(rst_n/rst)与代码里的复位逻辑完全一致;
- 第二步:异步复位必须加同步释放,避免亚稳态;
- 第三步:不要把按键信号不处理直接当复位,按键需加消抖 + 同步,再作为复位信号;
- 第四步:统一复位网络,尽量用一个全局复位,模块复位由全局复位派生,避免多复位干扰。
3. BUG 2:亚稳态 / 跨时钟域没处理(CDC 相关,玄学重灾区)
现象:信号偶尔跳变、状态机莫名跑飞、数据偶尔错一次(不是必现),低频正常,高频报错概率大幅增加。
原因:本质是异步信号处理不当:
- 异步信号(不同时钟域)直接打一拍就用,没有做两级同步,产生亚稳态;
- 多 bit 数据直接跨时钟域传输,没有用握手机制或异步 FIFO,导致数据错乱;
- 异步 FIFO 读写指针没有用格雷码编码,跨时钟域时出现多 bit 同时变化。
排查思路:
- 单 bit 跨时钟域信号:必须用两级寄存器同步,规避亚稳态;
- 多 bit 跨时钟域信号:禁止直接打拍,必须用握手机制或异步 FIFO;
- 查看开发工具(Vivado)的 CDC 警告,不要全部屏蔽,90% 的警告都是亚稳态隐患;
- 异步 FIFO 排查:确认读写指针是否用格雷码,满空信号是否由 IP 核内部同步生成,避免手动同步导致隐患。
4. BUG 3:组合逻辑产生毛刺(高速场景必踩,仿真查不到)
现象:低速运行一切正常,高速运行就报错;仿真波形完美,上板后信号跳变异常、输出乱码。
原因:组合逻辑本身的延迟不一致,导致信号出现毛刺,高速场景下毛刺被放大:
- 关键输出信号直接由组合逻辑给出(比如 assign 直接驱动输出),没有经过时序寄存器锁存;
- 状态机用一段式编写,输出直接由状态判断给出,没有单独的输出寄存器,产生毛刺;
- 多层 assign 嵌套、组合逻辑链路过长,不同路径的延迟不一致,出现竞争冒险。
排查思路:
- 核心原则:所有外部输出信号、关键控制信号,一律经过时序寄存器(reg)锁存后再输出;
- 状态机整改:摒弃一段式,改用三段式状态机(次态、现态、输出分开),输出单独寄存;
- 简化组合逻辑:减少多层 assign 嵌套,复杂控制逻辑拆分模块,避免过长的组合逻辑链路;
- 工具排查:用 Vivado 的波形抓取功能,查看关键信号是否有毛刺,针对性优化。
5. BUG 4:没有写时序约束(时序隐患,低频侥幸、高频必炸)
现象:频率不高(比如 25MHz 以下)时能正常运行,频率一拉高(50MHz 以上)就跑飞;逻辑很简单,却频繁出现时序违规报错。

