尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

FPGA程序固化实战:从Vivado生成bitstream到W25Q128烧录与启动排查

FPGA程序固化实战:从Vivado生成bitstream到W25Q128烧录与启动排查 第一次在调试间里遇到“烧录成功但上电不运行”的问题时我的整块板子沉默得像块砖。LED不亮、串口没反应、示波器探针在Flash的CS引脚上也看不到任何时钟跳变——那一刻我才意识到FPGA程序固化这件事远没有在Vivado里点一下“Program Device”那么简单。所谓固化就是把FPGA的配置数据写进一颗掉电不丢失的外部Flash常见如Winbond W25Q128这颗SPI NOR Flash让板卡每次上电都自动从Flash加载程序不再依赖JTAG调试器。这篇内容主要面向正在用Vivado做FPGA开发、想把bitstream真正固化到板子上跑起来的工程师我会把从工程配置、文件生成、烧录操作到各种报错的完整排查链路一次性讲透。1. 为什么FPGA一断电就“失忆”固化的本质与W25Q128的适配逻辑1.1 SRAM架构的“断电即清零”注定要外挂FlashFPGA内部的配置存储单元本质上是SRAM。SRAM的快、可反复重写、无限次配置让FPGA能够灵活地不断更换逻辑功能但它有一个天然缺陷——易失性。一旦断电SRAM里存的LUT查找表内容、触发器初始值、IO配置、时钟管理配置全部清零。这就是为什么你在Vivado里综合、实现、生成bitstream再通过JTAG下载到板子上跑起来一切正常但只要一断电重启板子就变回“白纸一张”。这个特性和MCU有本质区别。MCU把程序放在片内Flash里上电后CPU自己从Flash取指令执行不需要外部帮忙FPGA自己则没有可存储配置数据的非易失单元它的“程序”必须放在外部存储器中由FPGA在上电时主动把配置数据读进来。这个“上电自己读”的过程就是启动配置而把bitstream写进外部Flash的动作就是我们在工程中常说的“程序固化”。理解了这一层你就能明白为什么任何基于SRAM架构的FPGA系统板子上都必须有一颗非易失存储芯片。无论是早期的Xilinx Spartan/Artix还是更复杂的Kintex/Virtex甚至部分UltraScale平台只要没有内置FLASH的版本都逃不开这个设计需求。1.2 SPI NOR Flash凭什么成了标配W25Q128核心参数FPGA的配置bitstream文件有多大以Artix-7中等规模器件为例一个完整的配置bitstream通常在几MB到十几MB量级更大型的Kintex/Virtex会更大。这个体积决定了你没法用几KB的EEPROM需要的是容量充足、接口简单、可靠性高的存储介质。W25Q128就是典型的选择。这颗Winbond的SPI NOR Flash容量128Mbit即16MB工作电压2.7V~3.6V最常见的是3.3V供电版本。它支持标准SPI、Dual SPI、Quad SPI读速度根据子型号不同最高可以到104MHz或133MHz写入和擦除都按标准NOR Flash规范操作。下面是它的关键参数参数典型值容量128Mbit16MB接口SPI / Dual SPI / Quad SPI供电电压2.7V ~ 3.6V页大小256字节扇区大小4KB块大小64KB最大读时钟104MHz / 133MHz取决于子型号对比NAND FlashNOR Flash的优势在于支持随机读取、接口简单、没有坏块管理和ECC校验负担特别适合作为FPGA配置存储器。NAND虽然单位容量价格更低但在配置场景下要处理坏块、页管理、一次性写入等多了一堆麻烦事除非配置数据特别大否则一般用不上。这也是为什么绝大多数FPGA开发板上你看到的都是W25Q128、W25Q64、W25Q256这类SPI NOR Flash。1.3 配置模式串讲Master SPI、Slave与JTAG各管什么事在Xilinx 7系列平台上FPGA的启动配置模式由MODE引脚M[2:0]决定常见的有这么几类Master SPI模式FPGA作为SPI主机上电后主动从外部SPI Flash读取配置数据。这是固化最常用的模式。Slave模式SelectMAP/Serial由外部处理器、CPLD或其他控制器把配置数据“喂”给FPGA适合系统主控统一管理配置的场景。JTAG模式仅用于调试阶段通过下载器加载bitstream不能作为上电自动启动的来源。很多初学者在调试阶段一直用JTAG下载对“Master SPI”完全没有概念等到需要量产或让板卡独立启动时才开始补课。其实这个概念并不难只要记住一条主线调试用JTAG固化用Master SPI。后面烧录Flash、设置MODE引脚都是围绕这条主线展开的。2. 烧录前必须对齐的隐藏配置MODE引脚、工程参数与Flash型号2.1 硬件侧MODE引脚的拨码与走线检查很多人烧完Flash上电发现板子还是什么都没跑第一反应是Flash没烧进去但实际上问题往往出在MODE引脚上。FPGA上电瞬间会根据M[2:0]这三个引脚的电平状态决定启动模式如果板卡上的跳线帽还停在JTAG模式那FPGA根本不会去读Flash自然不会启动。以7系列平台为例常见的MODE引脚组合如下配置模式M[2:0]说明Master SPIx10014线SPI最常见Master SPIx4010需要硬件支持Quad连接JTAG100下载调试用需要特别提醒的是MODE引脚的电平设置一定要在断电状态下调整。带电拨动跳线或拨码开关除了可能引起配置逻辑误动作严重的还会损伤引脚。另外如果板卡原理图上有上下拉电阻并到MODE引脚要以板卡实际设计为准不要只看丝印示意图。各家的开发板虽然普遍遵循Xilinx参考设计但个别板子的拨码方向可能相反保险做法是翻一下板卡手册或原理图确认拨到对应位置的电平值。2.2 工程侧Vivado里Bitstream Settings的SPI模式与配置频率Hardware层面的MODE引脚要设对Vivado工程里的配置参数同样要对齐。打开Vivado在菜单栏进入Tools → Settings → Bitstream这里面有几个选项会影响固化Configuration mode选择SPIx1还是SPIx4。很多人会在这里犯错——工程里选了SPIx4但板卡上FPGA和Flash之间只连了SCK、CS、DI、DO四根线IO2和IO3根本没有连接那上电时FPGA想以Quad模式读Flash读回来的数据自然不对配置直接失败。反过来如果硬件明明支持Quad你却用SPIx1模式虽然能启动但加载速度慢不少。正确做法是先去翻原理图确认硬件连接再回Vivado里选对应模式。Configuration rate这是FPGA上电读Flash时所产生的CCLK速率。默认值通常是33MHz但并不是所有板子都能在这个速率下稳定启动。如果PCB走线长、Flash型号偏老或者信号质量一般建议保守一点设成15MHz甚至10MHz。实测中很多上电启动失败的问题就是在这一步用默认33MHz导致的把频率降下来立刻正常。Enable Bitstream Compression这个选项建议关掉。压缩后的bitstream可以减小占用空间但部分SPI Flash在启动时对压缩bitstream的兼容性有坑尤其当你后续还要做多启动MultiBoot时压缩会引入额外的复杂度。固化和调试阶段保持非压缩模式最稳妥。2.3 器件侧在Vivado里选对Winbond W25Q128后缀差异就是坑当你进入Hardware Manager准备添加Flash器件时在搜索框输入“W25Q128”列表里可能出现好几个相似条目。不同后缀的W25Q128J、W25Q128F等虽然大部分情况下JEDEC ID相同但个别新款型号或特殊封装版本在Vivado数据库里的描述可能有差异。选错型号的后果轻则无法识别Flash ID重则会用错误的擦除指令操作芯片。以W25Q128为例它的JEDEC ID通常是0xEF40180xEF是Winbond厂商ID0x40是SPI NOR类型0x18表示容量128Mbit。如果你在列表里误选了W25Q64或W25Q256Vivado读回来的ID会是0xEF4017或0xEF4019立刻报ID mismatch。所以添加Flash时要养成看板卡丝印的习惯——W25Q128后面有时候还有一长串字母数字那个主要是封装、温度等级、包装方式不影响容量和ID但在Vivado里只要选对“W25Q128”这个主型号基本就把九成问题规避掉了。3. 从.bit到.binFlash烧录文件的生成方法与格式细节3.1 为什么不能直接把.bit烧进Flash这个坑我见过不少人踩。在Vivado的Program Configuration Memory Device界面里其实直接选择.bit文件也能烧录但如果你用第三方工具或者想自己生成烧录文件就必须搞清楚.bit和.bin的区别。.bit文件是Vivado生成的比特流文件它的结构包含了头部同步字、设备IDCODE、寄存器配置信息等。这些信息是给JTAG下载链路用的用于告诉下载器“我这个bitstream是给哪个器件准备的”。但FPGA上电从Flash读取配置数据时期望的是纯配置数据流也就是剥离掉这些头部信息之后的原始比特流。如果把整个.bit文件原样烧进FlashFPGA从地址0读到的是同步字、IDCODE这些东西和正常配置数据的头完全对不上配置必然失败。所以烧Flash要用的文件格式通常是.bin也就是纯二进制配置流。Vivado可以在生成bitstream时顺带生成.bin也可以用write_cfgmem命令从.bit转换。3.2 GUI方式Bitstream Settings里一步勾选最简单的办法是在生成bitstream之前就设置好。打开Tools → Settings → Bitstream找到“bin_file”选项并勾选这样Vivado在完成综合实现生成.bit时会在同一个输出目录下自动生成同名的.bin文件。这个方式最省心不需要额外操作生成的.bin就是纯配置数据流。如果你已经生成过bitstream但当时没勾选bin_file也不需要重新跑一遍实现可以直接用下面的Tcl命令在Vivado的Tcl Console里转换。3.3 Tcl方式write_cfgmem用法与参数拆解在Vivado Tcl Console里切换到bit文件所在目录执行下面这条命令就能生成.binwrite_cfgmem -force -format bin -interface SPIx1 -size 128 -loadbit up 0x0 ./top.bit ./top.bin逐个参数拆解-format bin指定输出格式为bin。-interface SPIx1指定生成这个bin时按SPI x1接口组织数据。这个参数和前面工程设置里的Configuration mode要一致如果你硬件和工程都用了SPIx4这里就写SPIx4。-size 128指定目标Flash容量单位是Mbit。W25Q128是128Mbit所以填128。填错容量生成的bin可能在地址空间对齐上有问题。-loadbit up 0x0 ./top.bit表示将top.bit加载到Flash起始地址0x0。如果将来要做MultiBoot可能要把不同版本加载到不同地址常规单镜像固化地址就是0x0。./top.bin输出文件名。执行完这条命令你可以用十六进制查看工具打开bin观察文件开头是不是跟Vivado的bit流特征一致。正常情况下bin开头不会再有“FFFFFFFF”之类的同步头而是一段有序的配置数据。4. Vivado Hardware Manager烧录W25Q128的完整实操流程4.1 连接硬件与加载临时bit流烧录前的准备不只是把USB下载器插上。我的习惯是打开Hardware Manager后先Open Target确认能识别到FPGA设备然后右键设备选择Program Device先加载一个临时的bitstream。这一步不是多余的。很多板卡上Flash的供电或者IO bank的VCCO是受FPGA逻辑控制的FPGA没有运行起来时Flash可能根本没有电源或者相关IO处于高阻态直接去和Flash通信会失败。先跑一个bit让FPGA正常工作把SPI相关的IO口驱动起来Flash侧才能稳定工作。同时先加载bit也能让你确认当前bitstream本身是好的排除后续烧录完成但上电不启动时问题到底出在bit文件还是Flash烧录环节。4.2 Add Configuration Memory Device选中W25Q128在Hardware Manager的Device列表里右键FPGA设备选择Add Configuration Memory Device。弹出的搜索框里输入W25Q128从结果里挑选与板卡丝印匹配的型号。选定后Vivado会尝试读取Flash的JEDEC ID并和所选型号校验。如果一切正常Hardware Manager界面里会出现一个Configuration Memory Device节点这就代表Vivado已经通过SPI接口和Flash建立通信。如果这一步就报错多半是硬件问题参见第五章的排查链路。4.3 写入、校验与进度观察选中Configuration Memory Device节点右键选择Program Configuration Memory Device。在弹出的对话框里选择你要烧录的bin文件也可以直接选bitVivado会自动转换成Flash格式确认地址范围从0x0开始点击OK开始烧录。烧录过程包含擦除、写入、校验几个阶段Vivado的Progress窗口会显示进度。这里要提前做好心理准备W25Q128有16MB擦除和写入都不是瞬间完成的。SPIx1模式下全片擦除加写入可能要好几分钟如果烧录途中进度条长时间不动不要急着拔线先观察几分钟。如果最终出现Verify失败再按第五章的常见问题处理。烧录完成后Vivado通常会自动做一次Verify。你也可以在Configuration Memory Device节点上手动右键选择Verify Configuration Memory Device再次确认写入的数据和源文件一致。校验通过后断电、设置MODE引脚到Master SPI模式重新上电即可验证启动。5. 最值钱的避坑环节烧录失败场景与我的完整排查链路5.1 “target dll has been cancelled”报错JTAG通信中断的连锁反应在Windows环境下使用Vivado烧录Flash时如果你看到类似“ERROR: [Labtools 27-2269] Flash download failed - Target DLL has been cancelled”的报错核心原因是JTAG通信在写入过程中被中断了。这类中断通常会伴随烧录进度条卡住、下载器指示灯异常或者Vivado提示连接丢失。我实际排查过几次归纳下来主要原因有四类USB链路不稳定下载器用的USB线质量差、接口接触不良、或者接了USB Hub导致供电不足。这是最常见的原因建议尽量插在机箱后置USB口不要用前置面板和Hub。Windows USB节能策略系统在烧录过程中让USB端口休眠导致下载器掉线。可以去电源选项里关闭“USB选择性暂停设置”或者把电脑的睡眠时间改成“从不”。hw_server进程异常Vivado后台的hw_server长时间运行或之前异常退出导致残留进程占用JTAG资源。遇到这种情况关掉Vivado在任务管理器里结束所有hw_server进程重新打开Vivado再试。JTAG链上存在干扰设备如果JTAG链上串联了多个FPGA/CPLD某个器件的IR/DR链异常会影响整条链路通信。可以尝试断开其他无关设备只保留目标FPGA。处理这套问题我的顺序永远是换USB口和线缆、关USB节能、重启Vivado与hw_server、降JTAG频率。其中降JTAG频率往往最有效。在Hardware Manager里右键设备找到Hardware Server Settings把Target Frequency从默认的15MHz降到3MHz很多莫名其妙的通信中断问题会立刻消失。5.2 “failed to communicate with the flash chip”焊点、电平与保护引脚这个警告在Add Configuration Memory Device或烧录时都可能出现字面意思是“无法和Flash芯片通信”。它在提示你FPGA通过SPI接口访问Flash时没有得到任何有效应答。第一条排查线是SPI信号连接。用万用表检查CS、SCK、DI、DO四根线是否通路有没有虚焊、短路特别是在手工焊接的板子上SOIC-8封装的引脚间距不大很容易出现相邻引脚桥连。如果Flash是贴片焊接的建议用放大镜或显微镜观察焊点。第二条排查线是供电电平。W25Q128的VCC供电范围是2.7V~3.6V如果你的Flash供电是1.8V那就用错了器件反过来如果FPGA的BANK电压是1.8V而Flash是3.3VSPI引脚电平不匹配通信一样不稳定。可以用示波器量一下Flash的VCC引脚确认上电后电压正常。第三条排查线很多人会忽略就是WP#和HOLD#这两个引脚。在标准SPI x1模式下这两个引脚如果悬空或者被拉到一个不合适的电平Flash可能进入写保护或保持状态导致写入无效。尤其是WP#如果被拉低芯片的SRP保护就会生效Vivado写入时可能不报错但数据根本写不进去。正常设计里这两个引脚应该通过上拉电阻接到VCC如果板子上没有可以飞线拉高再试。5.3 IDCODE不符与器件选错一个字符的代价报错“ID code mismatch”或者类似提示说明Vivado从Flash读到的器件ID和你在Add Configuration Memory Device里选择的型号对不上。原因通常有两个要么板卡上的Flash根本不是W25Q128要么你选错了列表里的另一个相似型号。W25Q128的JEDEC ID是0xEF4018如果你选择的是W25Q64ID 0xEF4017或W25Q256ID 0xEF4019Vivado读回来的ID自然不一样。解决方案很简单回Add Configuration Memory Device界面重新搜索W25Q128选择对应的正确型号。但也遇到过一个特殊情况某款板卡使用的Flash是W25Q128JVVivado低版本比如2018.3之前的数据库里没有收录这个子型号读ID时识别不了。这种情况可以试试在列表里找其他Winbond同容量型号或者升级Vivado版本。如果是在产线上紧急处理可以临时用其他128Mbit的Winbond型号替代但要注意Vivado可能以不同指令时序访问需要做完整烧录验证后再批量操作。5.4 烧录成功但上电启动不了MODE引脚与配置时序的玄机最让人抓狂的一种情况Vivado显示烧录成功、Verify也通过但断电重新上电后FPGA就是没有任何反应。遇到这个问题我强烈建议按下面这个顺序排查不要一上来就怀疑Flash烧坏了。先查MODE引脚。这是最高频的原因。前面反复强调过跳线帽或拨码开关必须处于Master SPI模式如果在JTAG模式FPGA根本不会访问Flash。用万用表量一下M[2:0]引脚的上电电平确认和表2里的一致。再查DONE和INIT_B引脚。上电后DONE引脚应该是高电平表示配置成功如果DONE一直为低说明FPGA尝试配置但失败了。INIT_B引脚在上电初始化时会有一个短暂的低电平脉冲之后应为高电平如果一直为低往往是Flash读取出错或者数据校验失败。用示波器观察这两个引脚的波形能很直观地判断配置卡在哪一步。然后确认工程配置模式和硬件是否一致。工程里选了SPIx4但硬件只走了SPIx1FPGA上电后按照Quad模式去读Flash数据根本不对。这个问题的隐蔽之处在于你在Vivado里看着一切正常但它不会主动检查硬件。最后是Configuration rate。如果上了33MHz才失败降到15MHz或10MHz试试。有些PCB上SPI走线没有做阻抗匹配高速时钟下信号振铃严重FPGA读回来的数据有误就会导致配置失败。降频能解决大部分这类问题。5.5 烧录速度、Windows驱动与量产前的稳定性习惯除了上面那些大坑还有几个小问题经常让人抓狂。比如Windows下Vivado识别不到板卡打开设备管理器看到“未知设备”这是Cable Driver没装好。Vivado安装目录下自带驱动通常在Vivado安装路径/data/xicom/cable_drivers/nt64里手动更新驱动时指向这个目录即可。烧录速度的问题如果你的硬件支持Quad模式强烈建议使用SPIx4。同样烧录16MBSPIx4比SPIx1快3~4倍能显著减少产线等待时间。前提是工程里的Configuration mode也同步选成SPIx4生成的bin对应SPIx4MODE引脚拨到对应模式三个环节必须完全对齐。量产阶段我建议把“烧录前读回原Flash内容并保存备份”做成固定动作。很多板卡出厂时已经带了一份厂家固件如果直接覆盖烧录一旦新固件出问题想恢复原厂状态就没有原始文件了。在Hardware Manager里对Configuration Memory Device执行Readback把读回的数据存成bin归档留底。这个习惯在项目维护中能救命。6. 烧录完成只是开始固化后的验证方法与量产习惯6.1 断电重启测试的规范步骤烧录完成、Verify通过之后不能直接宣布固化成功。最可靠的验证方式永远是断电重启模拟真实的上电场景。操作步骤很简单断开板卡电源等待5秒以上让电容放电确认MODE引脚处于Master SPI模式重新上电。观察DONE引脚状态、LED指示、串口输出、或者外设行为是否符合预期。如果功能比较多建议做一次完整的系统自测不要只看某个LED亮了就收工。这里有个人人都会忽略的细节上电后第一次加载Flash配置时FPGA的DDONE信号和功能IO之间有几百毫秒的延迟。如果测试程序中有对外设的初始化时序要求要确保这些时序在配置完成后才发生避免因为“上电后立即检测外设”导致的假失败。6.2 Readback备份与Verify交叉确认如果你在做量产或者需要长期维护的项目我强烈建议把Readback和Verify做成必选动作。Vivado可以对Configuration Memory Device执行Readback把Flash里的内容读回来。这个操作有两个作用一是作为固件备份存档二是通过多次读回比较确认Flash中的数据稳定没有漂移。实际操作中我会在烧录完成后执行一次Readback把读回的bin文件保存好再执行一次Verify让Vivado自动对比校验。如果两次读回的哈希值一致基本可以确认Flash中的数据是完整、稳定的。这里补充一个教训不要用同一个在线烧录流程里Verify通过的结果来替代Readback备份。Verify只是表明Flash内容和源文件一致但如果你烧进去的源文件本身就是错误的旧版本那唯一能救你的就是之前的Readback备份。养成“烧录前先备份原厂固件”的习惯能让你在开发阶段少承担很多不可逆的风险。6.3 失败场景的降级排查思路与MultiBoot的进阶预留按照上面流程走完后如果固化后的板卡仍然有问题我的降级排查思路是先怀疑硬件链路MODE、Flash供电、SPI走线再怀疑工程配置SPI模式、配置频率最后才怀疑异常数据本身。不要一上来就反复烧录Flash那样既浪费时间也可能在反复擦写中损坏Flash。W25Q128虽然是工业级器件但擦写次数和高温焊接后的可靠性并不是无限的。如果你用的是7系列或部分UltraScale平台固化稳定之后还可以考虑做MultiBoot多启动也就是在Flash里同时放一份Golden Image和一份Update Image。上电时FPGA先加载Golden再通过IPROG命令跳转到用户指定地址的Update镜像。这样即便用户镜像损坏Golden镜像还能兜底设备不会变砖。MultiBoot的底子就是你固化的第一份镜像和地址规划基础固化流程不扎实后面这些进阶功能全是空中楼阁。做过的固化项目越多我越觉得真正决定固化稳定性的往往不是Vivado弹窗里那些按钮而是你对板子的熟悉程度。MODE引脚长什么样、Flash的WP#接在哪里、配置时钟该给多少、PCB上SPI走线走了多远——这些信息才是你把坑填平的关键。第一次做固化前先把板卡原理图拿在手里翻一遍会比在网上搜任何教程都管用。
返回列表