1. 前言:FPGA 里没有玄学,更多是细节没对上
做 FPGA 项目的人,大多都见过这种场面:仿真没问题,上板就开始抽风;低频能跑,高频一上去就乱;板子碰一下、线一晃,现象又变了。看起来像'玄学',其实通常都有明确原因,只是被藏在复位、时钟、约束和接线这些不起眼的地方。
下面这 10 类问题,基本覆盖了日常排障里最常见的坑。顺着它们查,往往比盯着波形瞎猜有效得多。
2. BUG 1:复位接法不对
现象:上电不稳定、状态机乱跑、偶发死机,重启后又时好时坏。
常见原因:
- 复位高低有效和代码写反了,
rst和rst_n没对齐; - 按键直接当复位用,没做同步释放;
- 工程里复位信号太多,模块之间各管各的,最后互相打架。
怎么查:先核对电平极性,再看复位是不是同步释放。按键类输入别直接进复位逻辑,至少要先消抖、再同步。工程里复位网络尽量收敛成一套,全局复位往下派生,别让每个模块都带一套自己的'土办法'。
3. BUG 2:跨时钟域没处理好
现象:信号偶尔跳一下,状态机莫名跑飞,数据偶发错一次,低频看不出来,频率越高越明显。
常见原因:
- 异步信号直接打一拍就用,亚稳态没兜住;
- 多 bit 数据直接跨时钟域传输,没有握手或异步 FIFO;
- 异步 FIFO 的读写指针没按格雷码处理。
怎么查:单 bit 信号用两级寄存器同步,多 bit 信号别硬跨,老老实实上握手或异步 FIFO。Vivado 的 CDC 警告别一股脑忽略,很多时候它报得比人还准。异步 FIFO 也别只看'能跑',先确认读写指针、满空信号是不是都按规范走的。
4. BUG 3:组合逻辑毛刺
现象:仿真看着很稳,上板后高频运行开始乱码、误触发,低速时又像没事。
常见原因:
- 关键输出直接用组合逻辑驱动,没有寄存;
- 状态机写法太随意,输出跟着状态直接变;
- 组合逻辑链太长,不同路径延迟不一致,毛刺就出来了。
怎么查:外部输出和关键控制信号,尽量都走时序寄存器再出去。状态机别图省事写成一坨,输出单独寄存会稳很多。组合逻辑能拆就拆,别让一长串 assign 把问题藏起来。抓波形时重点看边沿附近有没有短脉冲,这类问题通常就是这么露出来的。
5. BUG 4:时序约束没写或者写错
现象:低频正常,一加速就炸;逻辑明明不复杂,工具却一直报时序违规。
常见原因:
- 工程根本没写时序约束,工具只能自己猜;
- 只约束了时钟,复位和 CDC 没处理,报了一堆无效告警;
- 时钟周期写错,明明是 100MHz,约束成了 100ns。
怎么查:先把时钟约束补上,别让工具瞎猜。复位和明显的跨时钟域路径要设成伪路径,别拿无效报错淹没真正问题。周期别靠感觉,直接按 1000 / 频率(MHz) = 周期(ns) 算一遍,很多'玄学炸裂'其实就是这里写错了。
6. BUG 5:管脚分配错了
现象:代码看起来全对,仿真也过了,上板后 LED 不亮、串口没数据、按键没反应,严重时芯片还发热。
常见原因:
- 管脚号和原理图对不上;
- IO 电平标准配错,3.3V 和 1.8V 混在一起;
- 时钟、复位没放到合适的专用引脚;
- 输入输出方向搞反了。
怎么查:逐脚对原理图和芯片手册,别只盯代码。时钟脚要走专用时钟资源,别随手分配。电平标准也别想当然,外部器件和 FPGA 不是同一套电压时,很多现象看上去像逻辑错,实际是电气层没接上。最省事的验证方式还是老办法:先写一个最简单的闪灯程序,把基础链路跑通。

