FPGA下载成功但上电不运行?配置Flash与启动模式排查指南

发布时间:2026/9/5 6:02:05
FPGA下载成功但上电不运行?配置Flash与启动模式排查指南 这问题太经典了。我几乎每隔两周就能在技术交流群里看到有人发“JTAG下载明明成功DONE也拉高了但一断电重新上电板子就睡死过去什么反应都没有”。很多人的第一反应是“FPGA芯片是不是坏了”或者“Flash型号不支持”。实际上这颗芯片大概率毫发无损问题基本都出在“把程序固化进配置Flash”和“让FPGA在上电时从配置Flash启动”这两件事上。这篇内容我就围绕“FPGA下载成功但上电不运行”这个场景把配置Flash、启动模式、电源时序这三个排查方向一次讲透。顺便把我这些年调试过的Xilinx、Intel、高云、安路这些主流平台里共通的查错思路梳理一遍。不管你是刚点亮第一块开发板的初学者还是被现场设备折腾得焦头烂额的工程师这篇内容应该都能帮你省下半天时间。1. 先说清楚JTAG下载成功和上电自动运行本来就是两条路很多初学者容易把“烧录”理解成一个动作好像只要下载器提示“100% Complete”程序就已经写进芯片里以后每次上电都该自动跑。实际上完全不是这么回事这两条路从物理链路到数据格式都不一样。1.1 “下载成功”的含义可能和你理解的不太一样FPGA的JTAG下载本质上是通过下载器把bit文件或者叫比特流直接搬运到FPGA内部的SRAM配置区。SRAM的特性就是掉电即失所以用JTAG加载的bit流只对“当前这一次上电”有效。只要一断电配置区里的数据就没了下次上电FPGA内部还是空白的没有任何逻辑功能。所以当我说“JTAG下载成功只能证明JTAG链路和芯片本身基本正常”这句话的潜台词是它既不能证明你的配置Flash有问题也不能证明你的启动模式引脚设对了更不能证明你的电源时序是健康的。你只是验证了最基础的一条链路而已。提示下载器提示成功之后下载器继续保持连接时FPGA能跑一旦拔掉下载器再断电上电FPGA立刻“失忆”。这种现场我见过几百次绝大多数是用户没有烧写配置Flash而不是硬件故障。1.2 bit文件、mcshex文件、pof文件之间是什么关系现在得把这几个文件格式彻底捋清楚因为它们对应着完全不同的用途。bit文件Xilinx系FPGA的配置数据流包含配置指令、配置数据和CRC校验码用于JTAG在线调试。mcs文件Xilinx叫.mcsAltera/Intel系常叫.hex或.pof这是真正要写入配置FlashSPI Flash的文件格式。它是在bit文件的基础上额外添加了配置Flash的地址信息和校验信息让配置Flash在FPGA配置时能被正确识别和按地址读取。bin文件纯粹的二进制约简版本如果配置Flash挂接在处理器总线上往往由处理器直接读取bin文件并写入Flash。我把这个关系类比成bit文件是一份“源代码”可以直接交给FPGA“临时阅读并运行”mcs/hex/pof文件则是把这份代码“编译打包成固件”烧录到“外部硬盘”配置Flash里FPGA每次上电自动从这个硬盘启动加载。你下载bit文件就像对着会议室投影仪临时插U盘展示PPT你烧写配置Flash才是把PPT固化到硬盘里以后开机自动播放。1.3 常见误区下载了bit就当作了“已固化”很多从单片机转过来做FPGA的朋友最容易掉进这个坑。单片机里程序掉电不丢是因为它内部就有Flash但FPGA内部没有可存储程序的大容量非易失单元绝大多数主流FPGA。它内部只有SRAM配置单元和OTP加密区部分高端型号日常工作必须依赖外部配置Flash作为“启动盘”。所以用FPGA调试时如果只是临时调逻辑下载bit完全够用但只要涉及交付、现场运行、独立上电跑就必须在最后做一步“生成配置Flash文件并烧写”的操作。我见过不止一次开发板调通了很久最后要打包给客户时才发现压根没烧过Flash一上电就“不运行”。这种问题纯粹是流程上的疏漏。2. 配置Flash选型与烧录流程这里藏着最多的“翻车现场”既然FPGA上电要靠配置Flash这个“启动盘”那启动盘本身就得先确保没问题。先从选型开始讲这块看起来简单实际坑不少。2.1 配置Flash不是随便拿一颗SPI Flash就能用的先说结论绝大多数主流FPGA的SPI配置模式对Flash的基本要求是“标准SPI接口 3.3V或者1.8V电平看bank电压”但对指令集和厂商ID有隐含兼容性要求。以Xilinx 7系列为例Xilinx官方推荐的SPI Flash以Winbond华邦、Spansion现属Cypress、Micron、ISSI等厂商为主。很多开发板用的是华邦W25Q64JV、W25Q128JV这类SPI NOR Flash。这块在Vivado里需要手工添加Flash型号很多朋友在“Add Configuration Memory Device”这一步找不到自己的Flash型号就随便选一个“Generic SPI x4”或者选一个相似型号结果烧写时经常报ID mismatchID不匹配之类的错误。注意如果在Vivado的配置Flash列表里找不到你的W25Q128JV建议优先检查Vivado版本。老版本Vivado对新出的Flash型号支持不全升级到新版本后器件库会更新如果还是没有再尝试用Generic SPI配置但下载前务必确认SPI Flash的位宽x1/x2/x4和主控端匹配。IntelAltera系有自己专用的EPCS系列后来的MAX 10和Cyclone 10等也支持通用SPI Flash配置时最好查阅目标器件的配置手册确认Flash指令集的兼容性。国产FPGA方面高云小蜜蜂家族常用SPI NOR Flash引导安路、紫光同创的推荐Flash列表也各有差异。总之一句话选型前先去官方的手册或配置指南里找“Supported SPI Flash List”比盲目买一颗大容量Flash踏实得多。2.2 用Vivado/Quartus生成固化文件并写入Flash的具体操作这块我以Vivado为例讲一遍操作路径Intel Quartus和高云等工具的思路上是类似的只是按钮位置不一样。第一步在Vivado里正常做完综合实现生成最终的bit文件。 第二步打开“Add Configuration Memory Device”选择你的Flash型号。这里有个技术细节如果你选的是W25Q128JV那么Vivado会自动把bit文件转换成对应地址的配置数据流。 第三步右键点击器件选择“Program Configuration Memory Device”烧写时建议勾选“Verify”选项让软件写完后回读校验一遍防止Flash写入过程中出现位反转或漏写这一点成本极低但好处极大。 第四步也是最多人忽略的一步烧写完Flash之后把下载器拔掉确认FPGA的启动模式引脚拨到SPI_x4或者SPI_x1模式具体看板子设计然后断电重新上电验证是否从Flash正常启动。很多板子默认上电后DONE会被拉低或者FPGA进入JTAG模式等待下载就是因为模式引脚没拨对。拨到正确的SPI启动模式后DONE信号在上电几百毫秒内应该会拉高看到这个信号基本就可以确认配置链路通了。补充一句Intel Quartus里生成固化文件用的是“Convert Programming Files”把.sof文件转换成.jic文件然后通过JTAG烧写到EPCS/EPCQ配置器件里。思路和Vivado完全一样只是文件后缀和菜单名字不同。2.3 烧写Flash阶段的几个典型翻车点Flash供电和Bank电压不匹配SPI Flash的VCC如果是3.3V但FPGA配置Bank的VCCO只有1.8V那SPI通信电平不匹配上电配置大概率失败。很多高速PCIe板卡为了功耗把配置Bank压在1.8V这时候就要选1.8V版本的SPI Flash比如W25Q128JWPIM带“P”后缀通常是1.8V版本。SPI引脚被复用或没引出FPGA的SPI配置引脚比如Xilinx 7系的D[0]/D[1]/D[2]/D[3]、CCLK、FCS_B在配置完成后可以作为普通IO使用但原理图设计上如果这些引脚没有预留到Flash或者被其他外设占用配置链路就从物理上断开了。Flash焊接问题QFP封装还好WSON-8这种小封装手工焊接时虚焊率高特别是pin1如果没对准上电后CS_B拉低时Flash根本没回应。实在排查不出来先用放大镜检查一下焊盘和引脚。烧写序列里混了多个Flash如果JTAG链路上既有FPGA又有CPLD还有其他器件烧写Flash时选错目标器件或者地址范围配置错也会出现“烧写成功但上电没数据”的现象。3. 启动模式引脚与DONE信号最直接的“现场侦察点”Flash烧好之后还不算完。FPGA上电后首先要判断自己应该从哪种介质启动这个判断依据就是启动模式引脚的电平状态。这块出问题烧了再好的Flash也无济于事。3.1 启动模式引脚FPGA的“BIOS启动项”类比电脑来说启动模式引脚就相当于BIOS里的“启动顺序设置”——你是从硬盘启动、从U盘启动还是从网络启动都由这个设置决定。FPGA的启动模式引脚就是一排硬件管脚通过上下拉电阻配置成不同电平组合告诉芯片“你开机后去读哪里”。各主流平台的叫法不太一样Xilinx 7系列叫M[2:0]常见的组合是Master SPI001、Master BPI010、Master SelectMAP011、JTAG101等。Intel/Altera Cyclone系列叫MSEL[2:0]/MSEL[4:0]配置模式包括AS主动串行、PS被动串行、JTAG等。高云GW1N系列叫CFG_MODE引脚安路、紫光同创也各有对应管脚。如果模式引脚的电平组合不对比如你想要Master SPI启动但M[2:0]被拨到了JTAG模式那FPGA上电后就会一直等着JTAG链路上的下载操作而不会主动去读SPI Flash表现出来就是“板上程序完全没有运行”。实操中模式引脚的处理有几个容易忽略的点。第一如果整套板子只通过JTAG下载并用SPI Flash启动M[2:0]请务必用电阻硬拉到对应电平不要让它悬空。悬空的引脚在噪声环境下可能出现电平漂移有时候上午能启动下午不能启动折腾死你。第二如果是开发板一般会用拨码开关或者跳线帽调试时每换一次模式记得完全断电再上电有些模式切换需要冷启动才生效。3.2 看DONE信号判断“配置进行到哪一步了”DONE信号是FPGA配置完成后的状态输出高电平表示配置成功、内部逻辑开始运行低电平表示配置还没成功。这是一个极其重要的侦察节点。上电后你用示波器表笔点住DONE引脚观察它的行为如果DONE一开始有一个短暂的低电平然后被拉高而且不再掉下来说明FPGA成功从配置Flash加载了程序。如果DONE始终低电平说明配置链路根本没走通。如果DONE在低电平和高电平之间来回抖动或者反复出现周期性的“低-高-低-高”波形那往往说明FPGA在不断地尝试配置又失败常见原因是SPI Flash数据异常、时钟不稳定或者模式引脚抖动。对于Xilinx 7系列还有一颗INIT_B信号值得关注。INIT_B在配置开始前会拉低一段时间然后释放如果INIT_B一直拉低不放说明FPGA检测到了配置数据错误或者CRC校验失败。这个时候回读Flash内容或者重新烧写Flash往往比修改逻辑更管用。实操心得调试任何一个FPGA系统先把DONE引脚飞线到一个LED指示灯串联1k电阻接VCC调试时一眼就知道配置是否成功。多花两毛钱成本能省下大量接示波器的工夫。4. 电源时序容易被忽略却能致死的“隐形变量”前面说的都是数据链路最后这个方向是物理层面的。FPGA上电不运行有时候和数据、Flash、模式引脚都没关系纯粹是电源没有按规矩来。4.1 FPGA对上电时序的要求到底有多严格严格来说不同厂家、不同型号的FPGA对上电时序的要求有差异。多数Xilinx 7系列要求VCCINT内核电源1.0V先于VCCAUX辅助电源1.8V和VCCOIO电源上电Intel Cyclone系列有类似要求内核电源通常优先于IO电源国产FPGA基本继承了类似的趋势但具体顺序以数据手册为准。为什么要有这个顺序核心原因有几个。一是配置期间IO引脚处于未知状态如果VCCO先上电而内核还没起来IO引脚上的外部电路可能通过IO保护二极管倒灌电流引起Latch-up闩锁效应风险。二是部分FPGA的配置逻辑和PLL等模拟电路依赖VCCAUX如果VCCAUX先于VCCINT上电内部上电复位POR电路可能无法正确释放导致芯片一直卡在复位状态。实际调试中最容易出问题的是上电顺序设计正确但实现不完整。比如原理图上用DC-DC先产生3.3V再通过LDO产生1.0V内核心看起来顺序是对了但如果3.3V上电到LDO使能之间没有延时两个电源轨可能几乎同时爬升甚至内核电源比3.3V更晚稳定一样可能触发POR异常。4.2 用示波器实测电源时序一个必须养成的调试习惯很多人看电路设计文件里写了“VCCINT → VCCAUX → VCCO”就以为万事大吉从来不实测。电源时序这东西原理图设计合理不等于实际波形合理。我建议在首次上电调试时至少用示波器同时测量三路电源轨的爬升曲线检查两点第一各路电源的上电顺序是否符合数据手册要求。第二各路电源从10%到90%的爬升时间是否在手册规定范围内。某些FPGA对电源斜率有明确要求比如要求VCCINT上升时间在0.2ms到50ms之间如果上升太快或者太慢都可能造成POR逻辑误判。补充提醒上电斜率的问题在采用大容量陶瓷电容的设计里比较突出。如果内核电源轨上并联了过多容值的去耦电容上电瞬间这些电容相当于短路DC-DC可能进入限流保护导致电压爬升得很慢甚至永远爬不到目标值。这时候不是FPGA坏了是电源设计余量不足。实测中还有一个经典坑用万用表量电压看到1.0V、1.8V、3.3V都正常就以为电源没问题。但万用表只显示稳态值看不到时序。必须在示波器上用多通道同时捕获上电瞬间才能确认先后顺序。建议把触发电平设在内核电压的50%处时基调到10ms/div左右这样能捕捉到完整的爬升过程。4.3 电源监控芯片和POR机制时序问题的“兜底手段”很多量产板会加一颗电源监控芯片比如TI的TPS3808、ADI的ADM6315等用来检测各路电源是否都到达阈值然后输出一个Power Good信号这个信号接到FPGA的配置复位或者系统复位电路上。这样做的好处是把“多路电源时序”简化成“一路复位信号”只有所有电源都稳定复位才释放FPGA才开始启动。如果你在调试的板子没有电源监控芯片又碰上电源时序不满足的情况可以临时加一块小电路板或者用信号发生器做一个延时控制先验证一下问题方向。我在实验室里就经常用“一个LDO加一个RC延时电路”临时做上电顺序控制来区分是电源问题还是配置问题。5. 一整套实际排查流程从下载成功到上电稳定运行的行动指南前面把三个核心方向拆开了现在把它们串成一条完整的排查流水线。按照这个顺序走一遍大多数“上电不运行”的问题都能定位。5.1 排查第一步确认下载bit后功能本身就正常这是最容易忽略的一步但必须先做。用JTAG下载一个控制LED翻转的简单工程确认下载后LED正常闪烁。这一步的目的有两个一是确认FPGA芯片和JTAG链路没问题二是确认板子上的时钟、复位等基础条件能支撑逻辑运行。如果连JTAG下载后LED都不闪那说明问题不在配置Flash和启动模式而在更底层的时钟、电源或者复位电路得先解决这个再往下查。5.2 排查第二步检查拨码开关/跳线帽的启动模式用万用表量模式引脚的电压确认与数据手册里SPI启动模式一致。这里有一个细节有些开发板的启动模式拨码开关丝印方向和实际状态是反的别只信丝印要实测电平。另外如果板子上模式引脚有上下拉电阻阻值不要选太大一般4.7k到10k比较常见太大容易被干扰太小会增加静态功耗。5.3 排查第三步看看DONE引脚有没有被拉高用示波器或者逻辑分析仪测DONE。如果配置成功DONE应该保持高电平如果一直低说明配置流程没走完。这时候回头检查SPI Flash的CS_B、CLK、DI、DO信号有没有正常的读写波形。正常时CS_B在上电后应该有一个明显的低脉冲CLK上应该有几MHz到几十MHz的时钟输出。如果CS_B纹丝不动说明FPGA压根没有去访问Flash问题更可能出在启动模式或复位上如果CS_B有动作但CLK上没有连续的时钟可能是Flash的器件ID不匹配或者SPI模式配置不对。5.4 排查第四步检查电源时序和配置相关引脚电平万用表测量所有电源轨的静态电压然后用示波器抓取上电瞬间的时序波形确认各路电源爬升顺序符合数据手册要求。同时检查FPGA的PROGRAM_B引脚Xilinx或nCONFIG引脚Intel是否正常释放——如果这个复位引脚被外部电路拉低或者被其他器件占用也能导致FPGA永远不能启动配置。5.5 排查速查表排查项正常状态异常可能原因处理建议JTAG下载bitDONE拉高功能正常JTAG链路、时钟、电源先解决基础下载问题启动模式引脚电平组合匹配SPI模式拨码错误、悬空、上下拉失效实测引脚电压按手册设置DONE信号上电后拉高且稳定Flash没烧写、Flash内容损坏、模式不对重新烧写并校验FlashSPI Flash访问波形CS_B有低脉冲、CLK有连续翻转引脚短路、虚焊、电平不匹配示波器检测波形检查焊接电源轨时序按手册顺序爬升且斜率合理LDO延时不够、电容过大、限流实测波形调整上电控制复位/配置引脚正常释放到高电平被下拉、外部电路占用检查复位电路和引脚复用6. 几个实战案例复盘每个坑都有人反复踩光讲理论不够我挑三个实际调试里遇到过的案例把“从现象到根因”的完整推理过程还原出来。这三个案例的覆盖面覆盖了软件操作、硬件设计和电源设计三个维度。6.1 案例一Flash烧写成功上电后DONE周期性抖动现象JTAG下载bit后逻辑正常烧写完mcs后断电上电FPGA没反应用示波器看DONE引脚发现它每隔几百毫秒就有一个低脉冲像在不停尝试启动。排查思路DONE周期性抖动说明FPGA在反复尝试配置。先测Flash的CS_B发现CS_B跟着DONE的节奏周期性拉低说明FPGA确实去找Flash了但读取失败导致重试。测Flash的MISODO信号发现上电后在读取阶段完全没有任何回读数据总线一直是高阻状态。根因SPI Flash的VCC引脚虚焊导致Flash实际上没上电FPGA每次拉低CS_B都得不到响应。处理用热风枪补焊Flash重新烧写后上电即恢复正常。这个案例提醒我焊接问题导致的“上电不运行”在排查顺序上应该排在Flash和FPGA之前先查。尤其是WSON-8这类底 pad 焊盘容易在视觉上看着“焊上了”实际底部并没有和PCB焊盘形成良好接触。6.2 案例二模式引脚拨对了但PCB内部走线把电平拉死了现象某块自研板所有设计都确认过Flash也烧写了DONE就是拉不高。用万用表量模式引脚发现其中一个引脚电压只有0.3V但拨码开关明明拨到了高电平。排查思路怀疑拨码开关到FPGA模式引脚之间的走线被某个下拉电阻拉低了于是检查原理图。发现该模式引脚在FPGA内部已经被内部下拉电阻Internal Pull-down影响而外部拨码开关又通过很长的走线连接线上寄生电容和内部下拉形成了一个分压实际到达FPGA引脚的电平不满足VIH要求。根因模式引脚既要适配拨码开关又被FPGA内部弱下拉影响走线过长导致电平不足。处理在拨码开关侧并联一个10k上拉电阻把电平重新拉到可靠的高电平区间。这个案例的通用性很强FPGA不少IO都有内部上拉/下拉模式引脚在配置阶段的状态受内外电阻共同作用。设计时别只依赖内部弱上下拉外部加一个明确的上拉/下拉电阻最稳妥。6.3 案例三电源静态电压正常但上电时序不满足导致配置失败现象一块量产板大约有5%的产品出现“上电不运行”但JTAG下载bit后功能完全正常。用万用表测各路电源电压都在规格内。排查思路因为是量产概率性不良先怀疑时序。用示波器测三路电源爬升顺序发现部分板卡上电时3.3V先于1.0V爬升与数据手册要求的1.0V先于3.3V相反。根因原理图设计里用的是同一个DC-DC先出3.3V再经LDO出1.0V但由于LDO上电启动延时不一致部分板卡上LDO输出反而比DC-DC输出更早建立。本质是器件批次差异导致的上电斜率不一致。处理在LDO的使能引脚上增加一个RC延时网络强制1.0V晚于3.3V稳定同时针对有问题的批次更换了LDO型号。这个案例告诉我们原理图设计顺序和实际波形顺序可能是两码事尤其是有多个电源转换级联时一定要实测。7. 设计阶段就埋好“自查开关”一些让调试顺滑的小习惯聊完排错最后讲三个能让你后续少吃苦的经验。这些经验来自多次“被坑—复盘—改进”的循环值得在下一个FPGA项目里直接用上。7.1 在原理图上预留DONE、INIT_B、模式引脚的测试点很多工程师画原理图时会把所有FPGA配置引脚直接连到Flash和拨码开关不留测试点。结果一上电发现问题示波器探头没地方放只能去刮焊盘或者飞线非常痛苦。我现在的习惯是所有和配置相关的关键信号都引出测试点或者0欧电阻方便调试时断开和测量。DONE引脚直接加一个LED指示灯每块板子上电后一眼就能看出配置是否成功。这个小改动成本极低却能把“上电不运行”的排查时间从小时级压缩到分钟级。7.2 每次发布版本保留“发布包”目录文件命名和校验记录不能省一个项目迭代几十个版本之后最怕的就是“明明烧了这个版本为什么上电跑起来不对”。其实往往是因为开发和生产用的不是同一份配置文件。我现在每个工程里都有一个固定的“release”目录里面放着对应版本的bit/mcs/hex文件文件名带上日期和功能比如“xxx_v1.2_20250115_mcs”。同时每次烧写完Flash后做一次回读校验并把校验值记到版本说明里。如果现场出问题一对比校验值就能快速判断是不是配置数据损坏。7.3 升级Vivado/Quartus时留意配置Flash器件库变化我之前遇到过一颗新买的Flash型号在Vivado老版本里找不到选了个Generic类型也能烧写但上电后DONE就是拉不高。后来升级了Vivado版本在器件库里找到了这颗Flash的确切型号重新生成mcs并烧写后一切正常。原因是新Flash的某些扩展指令或状态寄存器行为和早期通用配置不一致导致FPGA配置请求无法被正确响应。所以别嫌麻烦该升级工具链就升级或者至少装一个最新版本的器件库。整体来说“FPGA下载成功但上电不运行”这个问题本质上就是一条“从固化文件到启动模式再到电源时序”的完整链路。链路里的每一环都可能成为故障点但好消息是每一环都大概率可以通过示波器和万用表快速查清楚。只要养成“先确认JTAG能下载、再确认Flash烧写正确、然后确认启动模式电平、最后实测上电时序”的习惯这类问题基本与你无缘。