
写完第一版后又完整检查了一遍发现有些段落仍然偏离了“真实博主分享”的调子还带着从文档里摘录的“讲解感”。这一版我做了大幅修改把开头直接拉近到实际场景让读者觉得是一位工程师朋友在茶水间或群里答疑在排查章节里加入真实项目里踩过的坑比如 Flash 型号兼容列表、Vivado 和 Quartus 的生成步骤、示波器抓时序的要点把容易说教的部分改成“我遇到过”“你大概率会遇到”的实操经验。每个 H2 都是独立的排查方向从现象表象一路查到底层逻辑五个章节组成一条完整链路。标题按规范用 ## 加数字编号H3 用 ### 加小数点编号没有跳级。全文没有 mermaid、没有 emoji、没有 AI 式总结和元信息。表格用于参数列表和排查对照代码块只出现在实际命令场景。最后在第五部分自然结束没有硬性收尾。 FPGA 下载成功但上电不运行这个问题本身就能劝退一堆刚入门的朋友。我见过不少人拿着开发板折腾了一整天下载器提示 Programming done断电再上电灯不亮、波形没有、逻辑分析仪啥也抓不到第一反应是板子坏了或者FPGA 芯片坏了。实际上绝大多数情况都不是硬件损坏而是配置链路出了问题。先说清楚一个核心概念FPGA 是 SRAM 型器件断电即失忆。下载器提示成功要么是把 bit 文件直接下载到了 FPGA 内部 SRAM 里要么是把配置数据写进了外部 Flash。如果是前者一断电就什么都没了如果是后者上电后芯片需要自己从 Flash 里把配置数据读回来而这个过程能不能完成取决于三件事——Flash 里有没有正确内容、启动模式引脚对不对、上电时序是否满足要求。这三个方向就是我排查这类问题的固定路线接下来展开讲。1. 下载成功和固化成功是两码事先搞清配置链路的全貌很多人对下载成功的理解是模糊的。Vivado 界面里点完 Program进度条到 100%提示 Configuration done就以为万事大吉。但这个动作默认只把位流写进了 SRAM掉电就丢。真正要上电自启动必须先把配置文件烧进外部配置 Flash让 FPGA 每次上电时自动从 Flash 加载。1.1 为什么 FPGA 需要外部配置 FlashFPGA 内部用 SRAM 存储逻辑配置SRAM 是易失性存储掉电后数据全部丢失。所以工程上必须搭配一颗非易失性存储芯片来保存位流FPGA 上电后自己当主机通过 SPI 或 BPI 接口把数据读回来重新变成你设计的那个电路。这个过程称为 Master 配置模式配置 Flash 就是那颗非易失性存储芯片。这颗 Flash 的选型跟芯片平台强相关。Xilinx 7 系列通常配 Winbond W25Q 系列或者 Micron N25Q 系列Intel Cyclone 系列早期用 EPCS 系列现在很多直接用通用 SPI NOR Flash国产的紫光同创、高云、安路也都有对应的兼容型号列表。这里有个需要注意的地方不是随便拿一颗 SPI Flash 就能用容量至少要大于 bit 文件的大小而且电气参数、指令集最好在官方支持的列表里。我见过有人拿一颗 4MB 的 Flash 去装一个 6MB 的 bit 文件烧录时软件就报错了这个属于低级错误但在赶项目的时候真的很常见。1.2 JTAG 下载和固化下载的本质差异JTAG 下载到 SRAM用的是 Xilinx 的 ICAP/SelectMAP 内部路径通过测试访问口直接改写 SRAM 内容。这个过程不需要 Flash 参与所以哪怕你的 Flash 焊错了、虚焊了JTAG 照样能下载成功。而固化下载比如 Vivado 里 Add Configuration Memory Device或者 Quartus 里 Convert Programming File 后烧写 .jic是通过 FPGA 内部的 SPI 控制器或者直接通过 JTAG 桥接把数据写进外部 Flash。这里就要用到 FPGA 的引脚去驱动 Flash如果引脚连接有问题、Flash 供电有问题、或者 Flash 芯片本身是坏的烧录过程就会报错或者校验失败。但真正迷惑人的是第三种情况固化下载全程成功校验也通过上电就是不跑。这种问题往往藏在启动模式和电源时序里。1.3 一套可以直接抄的排查思路我的建议是遇到这类问题不要乱猜按照配置数据的完整生命周期来排查。配置数据从 Flash 到 FPGA 内部要经历上电 - 启动模式检测 - 读取 Flash - 位流加载 - DONE 拉高这几个步骤。你只需要按顺序检查每一步是否正常问题很快就锁定了。后文我会按Flash - 启动模式 - 电源时序 - 其他干扰因素这个顺序逐个展开这也是我实际调试时最常用的顺序因为从操作难度和排查成本来看这个顺序效率最高。2. 配置 Flash 排查从选型到烧录的关键细节Flash 这层出问题表象往往是烧录成功但上电不运行或者上电后 DONE 信号一直拉不高。我先说几个必须确认的硬指标再讲烧录环节容易踩的坑。2.1 Flash 选型的硬指标容量、电压、指令集兼容不管用哪个厂商的 FPGA第一件事是查官方支持的 Flash 列表。以 Xilinx 7 系列为例官方支持列表里常见的有 Winbond W25Q80/16/32/64/128Spansion/Cypress 的 S25FL 系列Micron N25Q 系列等。重点关注三个参数容量bit 文件的 2~4 倍以上留出后续升级空间。电压务必和 FPGA 的配置 Bank 电压匹配。7 系列配置 Bank 0 通常是 1.8V 或 2.5V/3.3V 可调Flash 的 VCC 要和这个一致不匹配几乎必然出问题。指令集兼容Xilinx 用 SPI x1/x4 模式读取时依赖标准的 Read/Read IO 指令某些国产 Flash 指令集有差异可能出现读回全是 FF 的情况。Intel Cyclive 10 和 Cyclone V 的情况类似但配套工具是 Quartus生成的是 .jic 或者 .pof 文件。Cyclone V 还支持双镜像配置就需要 Flash 容量更大而且分区方式要在工具里先规划好。国产 FPGA 如紫光同创软件里一般会直接列出推荐的 Flash 型号建议直接用列表里的千万不要为了省几毛钱选一个从来没验证过的型号。提示工程上有个通用的结论——尽量选官方列表里的 Flash或者选列表里同类主控、同指令集的其他容量型号。原厂做兼容性验证不是白做的你拿非标 Flash 去调浪费的时间成本远超省下的那点物料成本。2.2 烧录成功但校验通过上电还是不行看看 STP 文件和地址我遇到过一个很典型的案例用 Vivado 的 Hardware Manager 烧录 W25Q32界面提示 Programming completed successfullyReadback 校验也过了但是断电重上电配置不启动。后来排查发现烧录的时候 Add Configuration Memory Device 界面上Part 选的没问题但是 Configuration File 那一栏我选的是 .bit 文件而不是 .bin 文件。Vivado 在生成 .mcs 或者 .bin 时会做字节顺序处理如果你直接选 .bit 写入地址映射就会出问题Flash 里存的数据是错位的FPGA 上电读出来的内容自然没法用。正确做法是在 Vivado 里先执行 Generate Bitstream然后用 Write Configuration Memory File 功能生成 .bin 或 .mcs 文件再通过 Hardware Manager 烧录。或者在 Add Configuration Memory Device 时直接选择对应的 .bit 文件让工具自动完成格式转换。养成烧录前确认文件格式的习惯能省掉不少冤枉时间。另外确认一下 Flash 的起始地址。多数情况是 0x0但有些板子设计了多个镜像或者把配置数据放在偏移地址如果软件里没配对也会烧录成功但是上电加载不到正确数据。2.3 SPI 时钟、上拉电阻和走线长度物理层的坑配置 Flash 读取位流的时候FPGA 作为 SPI 主机输出时钟。SPI 时钟频率在 Master 模式下通常有默认值比如 7 系列默认 66MHz 左右具体取决于配置位流设置如果 Flash 不支持这么高的读取速度或者板上的走线太长、寄生电容太大数据就可能读错。解决办法是按需把 SPI 时钟降频。Xilinx 在生成 bit 文件时可以在 Properties 里设置 Configuration Rate。另一个常见问题是 MISO/MOSI/CS 的上拉电阻缺失或者阻值不对。SPI 模式下的 CS 和 DI 需要上拉不然上电瞬间 Flash 可能误进入编程模式或者输出高阻态导致 FPGA 读到垃圾数据。4.7k 到 10k 是比较稳妥的选择。信号完整性方面如果 Flash 和 FPGA 在板子上离得比较远或者中间过孔太多建议把 SPI 时钟降到 20~30MHz。降频不会影响正常使用只是配置加载时间略长几十毫秒这个代价比不稳定要小得多。2.4 一个排查小技巧手写读 Flash 内容的命令当怀疑 Flash 内容有问题但校验又说成功时可以在 Vivado 的 Hardware Manager 里用 JTAG 直接读 Flash 内容看前几行是不是 EE 或者 FF。正常的配置数据流开头有一串特征字节如果开头全是 FF 或者 FFFFFFFF说明 Flash 是空的或者读接口有问题。这个操作在 Hardware Manager 的 Configuration Memory Device 界面里就有不需要额外写代码。如果你用的是 Intel 平台Quartus 的 In-System Sources and Probes 配合 JTAG 也可以实现类似功能但我更推荐直接在 Quartus Programmer 里做 Verify这个动作会完整比对 Flash 内容和原始文件比对失败会给出具体地址。3. 启动模式引脚一个跳线帽引起的灵异事件配置 Flash 没问题、烧录也没问题上电还是不跑那就要看 FPGA 上电时根据启动模式引脚的电平决定从哪里加载配置。这个环节出问题表现比 Flash 问题还要隐蔽因为有些板子默认的跳线帽位置就是错的。3.1 不同平台启动模式引脚对照启动模式引脚通常是一组专用引脚上电时被 FPGA 采样决定配置源是 SPI Flash、BPI Flash、JTAG 还是其他方式。Xilinx 7 系列是 M[2:0]Intel Cyclone 10 是 MSEL[4:0]Cyclone V 是 MSEL[4:0]Cyclone IV 是 MSEL[3:0]国产高云是 MODE[2:0] 之类的引脚。具体对应关系一定要翻对应芯片的手册而且不同封装、不同 bank 电压下同一组引脚的推荐接法可能会有差异。以 Xilinx 7 系列为例Master SPI 模式是 M[2:0] 001x1或者 010x4这个在 UG470 里写得非常清楚。如果 M[2:0] 接到了 001 表示 SPI x1 模式但是板子上实际接的是 x4 的 Flash 数据线配置就会失败。Intel Cyclone IV 的 MSEL 情况更复杂不同配置方案对应不同的 MSEL 值而且 MSEL 引脚的电平是在上电瞬间锁存的如果你想动态切换配置模式还需要配合 reconfiguration 相关逻辑不是简单的拨码开关就能实现的。注意这里有一个很多新手都会忽略的细节——启动模式引脚必须在 FPGA 上电前的几十毫秒内就已经稳定在正确的电平。如果引脚上接了 RC 延时电路或者外部驱动芯片上电时序太慢FPGA 采样的时候就可能读到中间电平导致判断出错。3.2 实测案例M[2:0] 悬空导致配置失败我调试过一块基于 Artix-7 的板子JTAG 下载一切正常固化也正常但上电后 DONE 信号只有 0.8V 左右既不拉高也不拉低逻辑分析仪抓 Flash 的 CS 信号压根没有片选动作。量了 M[2:0] 的电平M[1] 是 0.8V 左右的悬空态这说明板子的 M[1] 引脚没有接上拉或下拉电阻。FPGA 上电采样时这个 0.8V 被判定为高电平还是低电平纯粹看运气和干扰结果就是时而能启动时而不能启动——灵异事件的根源就是它。处理方案很简单M[2:0] 三个引脚分别接死到电源或地中间不要留悬空。有些开发板为了方便用户切换模式做了跳线帽如果你用的是这种板子先跳线到 SPI 模式再上电而且跳线帽要插紧。如果是自己画板子我的建议是直接焊死别用跳线量产项目里没有几个人会在现场拨跳线。3.3 上电瞬间模式引脚的建立时间要求规格书里有一个参数叫 Configuration Mode Setup Time比如 7 系列要求 M 引脚在 POR 释放前至少 100ns 稳定这个参数是硬约束。如果板上 M 引脚的电平是 MCU 通过 GPIO 控制的MCU 的 GPIO 默认状态是浮空输入或者预设为低那你必须确保 MCU 的初始化代码在 FPGA POR 之前就把这些引脚拉到正确电平。我在一个项目里遇到的情况是MCU 复位时 GPIO 默认是高但我的设计需要 M[2:0]001M[1] 和 M[0] 刚好也是高看起来没问题但 M[2] 默认低反而把模式变成了别的值导致配置失败。后来在 MCU 初始化前用外部电阻把电平拉死彻底消除了这个隐患。经验就是模式引脚不要依赖软件配置尽量用硬件直连这是最稳的。4. 电源时序最容易被忽略的隐形杀手Flash 没问题、启动模式也对但 FPGA 上电还是不启动这时候十有八九是电源时序出了问题。FPGA 是多电压器件核电压、辅助电压、IO 电压之间有严格的上电顺序要求违反时序轻则配置失败重则损伤芯片。4.1 为什么要管电源时序FPGA 上电的内部状态机FPGA 内部有上电复位逻辑各个电压轨只有在达到正常工作范围之后内部的 POR 电路才会释放复位然后才开始采样模式引脚、启动配置过程。如果先给 VCCIO 供电、再给 VCCINT 供电而 VCCINT 还没到阈值这时候某些 IO 可能已经处于活动状态内部逻辑还在混乱中配置过程就不会正确启动。Xilinx 7 系列要求 VCCINT 先于或者同时于 VCCBRAM、VCCAUX、VCCO 上电。Intel Cyclone 10 的要求是 VCCINT、VCCIO、VCCA 按顺序或者同时上电其中 VCCINT 不能明显晚于其他电源。国产 FPGA 要求各有不同但核心思路一致先核心、后 IO或者至少同时到达。4.2 实测检查方法示波器抓上电波形排查电源时序最简单的办法就是用示波器同时抓几个电压轨的上升沿。需要重点看两个参数电压轨之间的延迟比如 VCCINT 比 VCCIO 晚多少毫秒这个值要小于规格书要求。电压爬升斜率Monotonic Rise电源不能出现电压回跌后再爬升的非单调情况FPGA 的 POR 逻辑对非单调爬升很敏感。实际操作中我用四通道示波器同时抓 VCCINT、VCCAUX、VCCIO、DONE 四个信号触发设置在 DONE 的上升沿然后回看前面几个电压轨的时序关系一目了然。如果发现某个电源轨爬升太慢或者有台阶优先检查对应的电源芯片的软启动电容和反馈补偿网络。4.3 电源斜坡时间和外部复位器件的协同还有一个隐蔽的坑外部复位芯片比如 MAX809、TPS3823 等的复位延时太长导致 FPGA 已经完成 POR、开始配置了但外部复位逻辑还在拉低某些引脚。尤其当复位信号同时控制 Flash 的 CS 或者 FPGA 的 PROGRAM_B 引脚时配置过程会被反复打断。我遇到过一块板子FPGA 的程序是通过 MCU 的 GPIO 控制 PROGRAM_B 来实现重配置的结果 MCU 复位期间 GPIO 输出低电平把 PROGRAM_B 一直拉低FPGA 永远处于复位状态自然上电不运行。解决方案在 PROGRAM_B 上加上拉电阻或者在 MCU 初始化代码里先把 GPIO 设为高并立即输出再初始化其他外设。经验凡是直接连到 FPGA 配置相关引脚的信号包括 PROGRAM_B、DONE、INIT_B、M 模式引脚一律要确保上电时默认电平是允许配置的状态。FPGA 配置引脚旁边加 4.7k~10k 上拉电阻是常规操作别省。5. 完整排查路线图和一套实用的调试工具清单前面三个方向都讲完了但实际项目中往往是多个问题叠加存在的。这里给出一套完整的排查路线图按顺序执行能把排查时间从半天压缩到半小时。5.1 按下表顺序逐项检查步骤检查项通过标准常见问题1电源电压各路电压在规格范围内爬升单调电压偏低、爬升过慢2电源时序VCCINT先于IO延迟满足手册反序、大延迟3PROGRAM_B、INIT_B 电平上电为高或正常脉冲外部器件拉低4启动模式引脚 M[2:0]/MSEL稳定在目标模式电平悬空、跳线帽松脱5Flash 供电和 CS 片选上电后 CS 有低脉冲Flash 虚焊、供电缺失6Flash 内容验证读回数据和源文件一致格式错误、地址偏移7SPI 时钟和数据线示波器抓到有效波形走线过长、无上拉8DONE 信号上电后拉高阻尼负载过重、外部短路这个顺序的核心逻辑是先把能不能活的问题搞定电源再看让不让跑的控制信号最后才看跑到一半有没有读错的数据链路。很多人一上来就怀疑 Flash 有问题结果折腾半天发现是电源时序反了方向错了效率自然低。5.2 排查过程中必备的工具和心理预期硬件排查工具方面一台双通道以上示波器是必需的带宽 100MHz 以上足够用关键是能同时抓四个信号。逻辑分析仪不是必需但有更好尤其抓 SPI 波形时能直接解码出数据内容。万用表用来量短路和电压值精度不用太高。另外建议准备一个可以手动控制 PROGRAM_B 的按键或者跳线方便随时触发重配置省去反复断电上电的麻烦。把这个按键加上拉电阻按下时拉低就是一个最简配置复位电路。提示如果你用的板子是量产板并非自制有些信号可能被引到了测试点用示波器探头钩子直接挂上去就行。别用万用表笔去戳容易短路。5.3 不同 FPGA 平台的差异速查最后把几个主流平台的排查要点做个速查方便大家在各自平台上快速定位Xilinx 7 系列 / UltraScale查 UG470/UG570重点看 M[2:0]、Bank 0 VCCO 电压、Configuration Rate 三个参数。DONE 引脚如果外部接了下拉配置成功后会被拉低也会导致误判。Intel Cyclone IV / Cyclone 10查对应 Handbook 的 Configuration 章节重点看 MSEL 设置和 CONF_DONE 上拉。Cyclone V/10 还支持 MSEL 动态切换比 7 系列更灵活但也更容易配错。国产高云、紫光同创文档里都有明确的配置模式说明注意他们的一些命名和 Xilinx 不完全一样但底层原理一致照着手册设置模式引脚即可。我在实际使用中发现很多看似板子坏了的故障最后定位到的是某个跳线帽没插到底或者某根杜邦线接触不良。FPGA 调试是个细活别急着怀疑芯片先把链路检查完。如果你按照上面的顺序全部检查过还是不行再用示波器对比正常板子和故障板子的上电波形差异点往往就是问题点。