资讯动态

FPGA程序固化到Flash完整指南:Vivado烧录流程与启动模式详解

发布时间:2026/9/22 2:57:17 来源:尧图企业网站定制
玩Xilinx FPGA的朋友应该都有过这种崩溃时刻代码写完综合实现全过生成比特流下载到板子上现象全部正常。结果一断电再上电板子回到出厂状态一开始跑的又是官方demo你刚才调出来的功能全没了。FPGA芯片本身是SRAM工艺配置数据只能临时存放在芯片内部的配置单元里断电即清空。想要让程序永久留在板卡上就必须把它烧进开发板上的Flash芯片上电后由FPGA自己从Flash里加载程序。这篇文章我以Vivado 2020.2作为工具链把从.bit到Flash的完整烧录流程、配置文件生成方法、启动模式设置和常见错误处理一次讲清楚。适合刚入门FPGA、被“掉电丢失”折磨过的新手也适合从ISE切到Vivado的老兄弟快速上手。1. 为什么程序非得烧进FlashFPGA的“失忆”和“记忆”1.1 SRAM工艺决定了FPGA的临时记忆FPGA内部用来实现逻辑的资源是LUT、FF、BRAM这些东西配置数据决定了每个LUT实现什么逻辑、每个可编程开关怎么连接。绝大多数Xilinx 7系列FPGAArtix-7、Kintex-7、Virtex-7都是SRAM-based架构意思是这些配置数据放在SRAM单元里断电就丢。这件事本身不难理解但不少人会忽略一个关键点芯片上电的一瞬间它也是一片空白没有任何逻辑功能它需要某种方式把自己“唤醒”。所以在FPGA芯片内部其实有一套硬件固化好的上电加载逻辑它会根据MODE引脚上的电平组合自动决定从JTAG口、SPI Flash、BPI Flash还是其他接口去读取配置数据。这个加载过程完全不需要用户干预也不需要任何外部控制器参与只要Flash里存了正确的配置数据电源一上芯片自己就能把自己配置好。1.2 Flash芯片在启动链路里的角色FPGA不是计算机它没有操作系统也不需要复杂的bootloader。在纯FPGA项目里只要Flash里存的是一个完整的bitstream文件上电后FPGA内部的配置逻辑就会主动通过SPI或QSPI接口去读Flash把数据搬进自己的配置SRAM然后释放IO、进入用户工作状态。整个过程一般只需要几百毫秒到几秒视Flash容量和接口速率而定。这里说的Flash芯片工程上基本都是SPI NOR Flash和QSPI NOR Flash常见型号有Winbond的W25Q128、ISSI的IS25LP128、Cypress的S25FL128S、Micron的N25Q128等等。为什么是NOR而不是NAND因为NOR Flash支持按字节随机读取上电之后FPGA可以直接把它当成一块只读存储器顺序读取不需要地址转换、不需要坏块管理、也不需要ECC纠错天然适合启动加载NAND是按页读写的需要专门的控制器去做扇区映射和坏块管理一般用作大容量数据存储很少用来做FPGA启动介质。搞明白了这一点你就知道选Flash型号时至少得保证接口和指令兼容而不是随便拿个NAND就往上怼。1.3 .bit、.bin、.mcs三种文件的区别说了半天Flash得先把文件格式讲清楚不然很多人会卡在“生成哪个文件”这一步。平时调试用的是.bit它通过JTAG直接下载到FPGA内部的配置SRAM只影响当前这一次上电运行掉电就没了。.bit文件本身带了一堆头部信息和比特流数据并不适合直接扔进Flash所以烧Flash前要转换成.bin或者.mcs。.bin是纯二进制文件数据从地址0开始连续存放烧录时直接写到Flash起始地址简单直接。我实测下来常规固化项目用bin最省心什么额外参数都不用管。.mcs其实是Intel HEX格式的一种变体文本格式带地址记录和校验信息适合需要指定复杂偏移地址、或者要把多个配置文件合烧到不同地址的场景。比如一个Bootloader加一个App用mcs就很方便。如果你只是想把一个程序固化到开发板生成bin就够了。2. 烧录前的准备配置文件生成与硬件检查2.1 在Vivado 2020.2里生成.bin文件生成bin文件有两种方式GUI和Tcl命令。对初学者我建议先在GUI里走一遍把里面每个选项看明白后面熟悉了再用命令行批量处理。打开Vivado 2020.2加载已经综合实现完毕的工程确认Generate Bitstream已经跑完生成了top.bit。然后顶部菜单点Tools - Generate Memory Configuration File弹出配置窗口后有几个关键选项要特别注意。第一个是Memory Type选SPI Flash。如果你的板子用的Flash是QSPI四线依然选这个真正决定几线的是下面那一个选项。第二个是Interface选SPIx1还是SPIx4。这取决于开发板上Flash和FPGA之间实际连了几根数据线。只连了MOSI/MISO两根线的板子必须选SPIx1四根数据线都连了的选SPIx4上电加载速度会快一些。选错接口轻则启动变慢重则直接读不出来。第三个是Size填入Flash芯片的容量单位是Mb不是MB。W25Q128JV对应的就是128MbN25Q128也是128Mb。填错不会马上报错但生成的bin文件长度会按这个值来定可能产生不必要的空白填充。第四个是Generate格式勾选bin。然后在Data Files区域点加号把top.bit添加进去Offset填0x00000000同时勾选Fill remaining locations with 0xFF意思是Flash没用到的地方全部填充0xFF。最后点OK稍等片刻就生成top.bin了。用Tcl命令更快直接在Tcl Console里执行write_cfgmem -force -format bin -interface spi -loadbit up 0x0 C:/fpga_project/top.bit -size 128 C:/fpga_project/top.bin其中-format bin指定输出格式-interface spi指定使用SPI接口-loadbit后面up表示正序写入、0x0是起始地址然后跟要转换的bit文件-size 128表示Flash容量128Mb最后是输出路径。这个命令生成的bin和GUI方式完全等价。想用spix4时把-interface参数改成spix4即可。2.2 硬件连接和驱动检查烧录Flash前先把硬件准备好。一条靠谱的JTAG下载线很重要原装Digilent JTAG或者Xilinx Platform Cable USB II当然最稳很多国产开发板自带的下载器也能用但当TCK频率偏高、或者线缆比较长的时候稳定性明显差一些。这一点后面讲问题排查时还会细说。用USB线把下载器和电脑连好开发板供电接上。这里提醒一句烧录Flash时数据量比较大建议用开发板上标注的电源适配器供电不要只靠USB取电。我自己遇到过板子外设较多、USB供电不稳定烧到一半和目标断开连接的情况换成外部电源就好了。供电之后打开Vivado 2020.2的Hardware Manager。如果电脑没有自动识别到下载器查一下驱动。Vivado安装时一般会顺带装Cable Drivers目录在安装路径的data/xicom/cable_drivers/nt64下面里面有digilent和xilinx_windrv等子目录可以手动运行里面的安装脚本。Windows下偶尔会遇到驱动没装上、设备管理器里下载器显示黄色感叹号的情况重新手动安装一次驱动即可。在Hardware Manager里点Open Target - Auto Connect如果一切正常左侧会列出可用的硬件设备。插一块Artix-7开发板就能看到xc7a35t_0或者xc7a100t_0之类的设备名。2.3 一个容易忽略的动作先清空FPGA再烧Flash烧Flash前我习惯右键FPGA设备选择Clear Configuration把FPGA内部的SRAM配置清掉。这一步的目的是释放FPGA对IO的控制权。如果FPGA里跑着的程序正好占用了和Flash复用的几个引脚烧Flash时要么通信失败要么整个过程不稳定。Clear之后FPGA引脚进入高阻态JTAG和Flash之间的通信链路就干净了。这个细节在官方文档里没怎么强调但我实际项目中遇到过不少因为没清空而烧写失败的案例操作很简单也就多花几秒钟建议每次烧Flash前都做一次。注意Clear Configuration只是清空FPGA内部SRAM不会动Flash里的任何数据可以放心操作。但如果你用Readback或者Erase那就真的会影响Flash里的内容了动手前先确认没有重要数据在里面。3. 完整烧录流程把bin写进Flash芯片3.1 登记Flash芯片Add Configuration Memory Device硬件连接好、bin文件准备好之后开始烧录。在Hardware Manager设备列表中右键你的FPGA设备选择Add Configuration Memory Device。这一步的作用是告诉Vivado板子上挂了一颗Flash请把它纳入管理。点击后会弹出搜索窗口让你选择Flash具体型号。这里必须选对与你板卡实际芯片一致的型号或者至少是同一个系列、指令集完全兼容的型号。比如Nexys A7开发板的Flash是S25FL128S直接搜S25FL128就能找到很多国产板用的是Winbond W25Q128就搜W25Q128选W25Q128JV或者W25Q128xxx对应的那个条目。选好型号确认之后Hardware Manager的设备树里会多出一个Flash节点显示为你的FPGA设备下挂着一颗Flash。这一步只做登记不会立刻擦写所以不用担心误操作。3.2 配置烧录参数bin文件、偏移地址和操作选项接下来右键Flash节点选择Program Configuration Memory Device会弹出烧录配置窗口。需要设置三块东西Configuration File、Offset、操作选项。Configuration File选之前生成的top.bin。Offset一般填0x0因为普通FPGA固化程序就应该放在Flash起始地址FPGA上电后从0x0开始读。如果你想把程序放到其他分区这里的偏移地址要和生成bin文件时的地址一致否则上电后读取不到正确数据。操作选项有Erase、Program、Verify三个建议全部勾上。Erase负责先擦除Flash全部内容Program负责写入新文件Verify负责烧完后读回来比对确认没有写错。三个选项勾上后中间不需要人工干预Vivado会按顺序自动执行。等三个步骤全部显示成功烧录就算完成。点OK之后进入烧录流程Vivado在底部状态栏显示当前进度。这个阶段需要点耐心。擦除一颗128Mb的Flash根据芯片不同可能要10秒到30秒写入bin文件的速度由TCK时钟频率决定通常也要几十秒最后的Verify同样要读取一遍所有扇区时间也不会短。整个流程跑完几分钟很正常如果中途不动了也不要急着打断先看日志栏有没有新报错。这里讲一个实际遇到的案例。有个同事烧W25Q128在Verify阶段报了一个地址不一致错误他第一反应是Flash坏了。我过去一看他其实把Artix-7 35T的bit文件烧到了100T的板子上两个器件型号不同配置数据长度和内容都不一样Verify自然对不上。换回正确型号的bit文件重新生成bin一次通过。所以烧录前确认一下比特流和FPGA型号匹配能省很多排查时间。3.3 多配置文件场景mcs文件的合烧如果项目里有两份程序要一起烧比如Bootloader加App或者想预留一个工厂测试版本单bin就不够用了。这时候用mcs文件才有意义。在Generate Memory Configuration File时可以往Data Files里添加多个bit文件给每个文件指定不同的Offset偏移地址生成的mcs会按地址组织所有数据。烧录时Flash低地址放Bootloader高地址放AppFPGA上电先跑Bootloader再由Bootloader跳转到App。很多产品的版本管理就是这么做的多文件合烧属于进阶玩法但理解了地址的概念后就很容易上手。4. 上电启动跳线开关和验证4.1 把启动模式从JTAG切到SPI Flash烧录成功之后如果保持JTAG启动模式断电再上电FPGA依然会等着JTAG给它喂数据Flash里的内容不会被自动加载看起来就像“烧了但没反应”。所以必须检查开发板的启动模式设置。这部分不同板卡差异很大。Artix-7系列FPGA通过M[2:0]引脚来设置启动模式JTAG模式、Master SPI模式、Master BPI模式等对应不同的电平组合。很多开发板把这些引脚连到了板边的拨码开关或者跳线帽上丝印上会写MODE、M0、M1、M2或者类似字样。比如Nexys系列在板卡一角有跳线出厂默认是JTAG模式烧完Flash之后需要把它拨到QSPI模式再重新上电。国产开发板常见的是几个拨码开关说明书里会明确给出“SPI Flash启动”对应的开关状态。这里我不打算给一个固定的拨码表因为不同板子定义完全不一样。正确做法是翻一下板卡原理图或者官方手册找到MODE引脚对应Flash启动模式的组合照着拨就行。上电后如果程序里的效果正常出现比如LED流水灯跑起来、串口有输出说明已经是从Flash启动了。再把JTAG线拔掉只留电源重新上电一次确认程序还在跑这才是真正意义上的“永久烧录”。提示切完启动模式后请务必彻底断电再上电。只按复位键很多时候不会重新读取启动模式引脚看起来就跟没切一样。4.2 细说启动模式里的几个坑设置启动模式时最容易踩的坑有三个。第一个是拨了跳线之后没断电只按了复位键。Master SPI启动模式是在芯片真正上电那一刻才去采样MODE引脚的如果你只是复位部分芯片不会重新采样所以看起来没反应。切完启动模式后最好彻底断电等几秒再上电。第二个坑是有些开发板的启动模式引脚有其他复用功能拨码开关又没标注清楚用户凭经验拨了一组组合结果根本不是Flash模式。我以前见过一块板子被拨到了BPI模式上电后系统要等很久才开始加载而且功能偶尔异常。最后拿示波器抓了MODE引脚的电平对照原理图才发现是模式设置错了。这种问题不抓硬件很难定位所以遇到上电行为诡异的情况先查MODE引脚。第三个坑是FPGA上电后如果从一个空Flash或者内容有错的Flash读取配置整个芯片会一直停留在配置失败状态此时打开Hardware Manager可以看到配置状态寄存器里报错。看到这种状态别慌把启动模式拨回JTAG重新连接上再烧一次Flash就行。5. 常见问题与排查技巧实录5.1 Flash Download Failed - Target DLL has been cancelled这个报错可能是烧录过程中最让人崩溃的。常见于烧录进行到一半突然弹出或者在点击烧录的瞬间直接出来整个过程直接中断。Target DLL is cancelled翻译过来就是和下载器通信的底层动态库被取消了硬件链路和软件之间的握手失败了。我遇到这类问题的排查顺序是固定的先看USB线是不是虚接换一根短线试试然后确认是否同时开了多个Vivado或者ISE残留进程占用了下载器打开任务管理器把Vivado、hw_server相关进程全部结束再重新打开软件再检查驱动是否正常设备管理器里如果下载器上有黄色感叹号重新手动指定驱动路径安装一遍。这一套操作下来绝大多数问题都能解决。还不行的话试着把TCK频率调低这个在Open Target时或者硬件属性里可以设置默认可能是6MHz左右手动改到3MHz甚至1.5MHz稳定性会好很多。5.2 Failed to communicate with the flash chip这个错误的意思是JTAG链路是通的FPGA也被识别到了但Flash没有给出正确应答。常见原因是Flash型号选错或者Flash相关引脚被当前FPGA里的逻辑占用、处于不确定电平。解决方法是先对FPGA做Clear Configuration再重新尝试。同时核对板卡原理图确认选的Flash型号与实际芯片一致特别要留意后缀比如W25Q128JV和W25Q128FV操作指令基本一样但如果板子上用的是W25Q64BV那差异就比较大了。另外有些自制板卡如果Flash供电没有使能或者片选被错误上拉/下拉也会出现这个报错。可以用示波器抓一下Flash的CS引脚看看在FPGA尝试读取时有没有产生片选脉冲。没有脉冲说明FPGA压根没在尝试访问这颗Flash问题更可能在配置链路和启动模式上。5.3 Cannot load flash device description偶尔会搜不到板上的Flash型号尤其是国产或冷门型号界面会直接提示无法加载设备描述文件。这种情况我建议从硬件兼容性想办法选一个容量相同、电压一致、指令集兼容的替代型号。例如找不到某个小厂128Mb型号时可以选S25FL128S或者W25Q128试试这两个型号在7系列FPGA的Master SPI启动兼容性上表现很好。注意如果SPIx4/QSPI模式启动出现兼容性问题可以先退回SPIx1模式这种问题大多是Quad Enable位处理差异引起的。5.4 烧录成功但上电不启动烧录成功但断电后程序不跑这问题排在咨询榜前三。排查清单按顺序给出来启动模式跳线是否已切到Flash模式并且断电重新上电过。bit文件是否正确匹配FPGA型号。Offset是否写在0x0。Flash是否焊接良好工业级老化板上偶发虚焊。电源是否稳定尝试换外部电源。用JTAG连上板子在Hardware Manager里查看配置状态寄存器。如果显示配置成功但程序没跑问题在程序本身如果显示配置失败多半是Flash读取链路有问题。5.5 烧录太慢、老是失败试试降低TCK频率TCK频率是很多新手完全没意识到的变量。之前我在一个线缆比较长的测试环境里默认频率烧写一烧就断后来把频率降到2MHz一整晚跑了十几轮都没事。操作方式在Hardware Manager窗口中打开Target属性或者Connection设置找到TCK Frequency或Frequency Setting选项手动输入3单位MHz。如果是脚本连接的方式也可以在连接命令里指定频率参数。如果每次降低频率就顺了一提升就失败基本可以断定是线缆质量、线长或者目标板信号完整性问题。正式项目里为了保证可靠我一般直接主动设到3MHz不折腾。5.6 常见错误速查表报错/现象可能原因优先排查方向Flash download failed - Target DLL has been cancelled信号链路中断换USB线、关多余Vivado进程、重装驱动Failed to communicate with the flash chipFlash型号不匹配或引脚被占用Clear配置、核对芯片型号Cannot load flash device description不支持该Flash型号选同系列兼容型号烧录成功但上电不启动启动模式不对检查MODE跳线并断电重启Verify阶段地址不一致bit文件与FPGA型号不匹配换正确型号的bit再生成bin经常烧到一半断掉TCK频率过高降到3MHz或更低我个人的体会是FPGA固化这个操作本身并不复杂半天就能学会真正考验人的是对启动链路和硬件特性的理解。我踩过的这些坑大多不是Vivado软件本身的问题而是对板卡Flash型号、启动模式、TCK稳定性这些“外围细节”不够重视。如果你第一次烧录就遇到报错别急着怀疑工具按上面的排查步骤一项项对一遍基本都能找到真正的病根。最后再分享一个小技巧烧录前尽量把Flash原内容用Readback读出来备份一份万一后面想把板子恢复出厂状态直接烧回去就行这个习惯我一直保留到现在。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价