ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ISE iMPACT生成mcs固化Flash:FPGA上电自启动全流程与避坑指南

ISE iMPACT生成mcs固化Flash:FPGA上电自启动全流程与避坑指南 1. 从bit到mcs为什么FPGA掉电就“失忆”很多刚接触Xilinx FPGA开发的朋友都有过这样的困惑明明用ISE烧录了bit文件开发板跑得好好的一断电再上电程序就没了FPGA又变回一张白纸。这不是你的板子坏了而是FPGA的配置存储机制决定的。FPGA内部用来存放配置数据的单元是易失性的SRAM结构掉电之后数据全部丢失。bit文件本质上就是一份“配置说明书”它告诉FPGA内部的查找表、布线开关、IOB该怎么连接。JTAG下载bit的过程就是把这本说明书临时塞进SRAM里所以断电即失效。要想让FPGA上电自动加载程序就必须把配置数据存到非易失性存储器里最常见的就是板载的SPI Flash。而ISE工具链里把bit转成能烧进Flash的格式用的就是iMPACT生成的mcs文件。mcs是Intel HEX格式的一种变体专门用于存储配置数据它带有地址信息iMPACT按地址把数据一段段写进Flash。整个链路是bit文件 → 通过iMPACT转换成mcs → 通过JTAG把mcs烧进Flash → FPGA上电后从Flash读取配置。这套流程在ISE 14.7上依然是最经典的做法虽然Vivado已经普及但大量老项目、教学板卡、工业设备还在用ISE尤其是Spartan-6、Virtex-5这些器件。我手上就有好几块Spartan-6的板子客户要求必须用ISE维护所以这套流程我反复走过很多遍踩过的坑也不少。下面把完整流程和关键细节拆开讲清楚。2. 生成mcs之前bit文件必须先过这几关2.1 bit文件的来源与常见误区mcs是从bit文件转出来的所以bit文件本身的质量直接决定固化后能不能正常启动。很多人以为只要ISE综合实现通过了生成的bit就没问题其实不然。bit文件生成过程中有几个关键设置如果没注意固化后会出现“JTAG下载能跑Flash启动不跑”的诡异现象。第一个是配置时钟频率。在ISE的Generate Programming File属性里有个-g ConfigRate选项默认是6对应大约3MHz的配置时钟。如果Flash的读取速度跟不上或者板子走线较长这个值偏大就会导致配置失败。我遇到过一块板子JTAG下载一切正常固化后死活不启动后来把ConfigRate从6改成3问题消失。原因是JTAG下载时时钟由下载器控制而Flash启动时时钟由FPGA内部振荡器产生两者路径不同裕量也不一样。第二个是未使用引脚的处理。在ISE的Generate Programming File属性里-g UnusedPin选项控制未使用IO的状态默认是Pull-down。如果板子上某些未使用引脚外部有上拉固化启动时可能出现冲突。这个选项要根据实际硬件来定不能无脑用默认值。第三个是bit文件的压缩。ISE支持生成压缩bit能减小mcs体积但压缩后的配置数据需要FPGA内部解压会增加启动时间。对于启动时间敏感的应用建议不压缩。2.2 确认bit文件与器件型号匹配这一步听起来废话但实际中真有人搞错。ISE工程里选的器件型号必须和板子上的FPGA完全一致包括速度等级和封装。比如xc6slx9-2tqg144和xc6slx9-3tqg144速度等级不同bit文件不通用。烧进去之后iMPACT可能不报错但FPGA启动后行为异常。确认方法很简单在ISE里打开工程看Project Summary里的Device信息和板子丝印上的型号对一遍。另外bit文件头部也包含器件IDiMPACT在加载bit时会校验如果型号不匹配会直接报错所以这一步一般不会出大问题但速度等级这种细节容易被忽略。2.3 bit文件命名与路径的坑ISE默认生成的bit文件名和工程顶层模块名一致路径在工程目录下。这里有个小坑如果工程路径包含中文或空格iMPACT加载bit时可能报错。我建议把bit文件复制到一个纯英文、无空格的短路径下比如D:\fpga\flash后续操作都在这个目录里做省得路径问题干扰。另外如果你用的是ISE的iMPACT GUI它默认会去工程目录找bit但有时候工程重新编译后bit文件被覆盖iMPACT还引用旧路径导致烧进去的是旧版本。养成习惯每次生成mcs前手动确认bit文件的修改时间确保是最新编译出来的。3. iMPACT生成mcsGUI操作与批处理两条路3.1 GUI方式一步步点但要知道每步在干什么打开iMPACT第一件事是新建工程。菜单File → New Project弹出向导。这里有个选择是配置单个器件还是多个对于固化Flash我们选Configure single FPGA然后选择SPI Flash或BPI Flash。大多数板子用的是SPI Flash比如M25P16、W25Q64这类。接下来iMPACT会让你添加bit文件。选中之前准备好的bit然后它会自动识别器件型号。这时候注意看iMPACT识别的器件和你的FPGA是否一致不一致要手动改。关键步骤来了右键点击Flash器件选择Add SPI/BPI Flash然后选Flash型号。如果列表里没有你的Flash型号可以选一个容量相同或更大的兼容型号或者手动输入Flash的ID。我遇到过一块板子用的是国产FlashiMPACT列表里没有最后选了M25P16因为两者指令集兼容烧进去也能用。然后就是生成mcs右键Flash器件选Generate File格式选MCS输出文件名自己定。iMPACT会弹出一个窗口让你设置mcs的起始地址和结束地址。对于SPI Flash起始地址一般是0结束地址根据bit文件大小自动填充。这里有个细节mcs的地址范围要覆盖整个bit文件且不能超过Flash容量。如果bit文件压缩后是2MbitFlash是16Mbit那结束地址填0x1FFFF就够了不用填满。生成完mcsiMPACT会提示成功。这时候你可以用文本编辑器打开mcs看一眼开头是:020000040000FA这样的记录这是Intel HEX的扩展线性地址记录正常。3.2 批处理方式适合反复烧录和自动化GUI点一次两次还行如果经常要改代码重新固化每次都点一遍太累。iMPACT支持批处理模式用命令行脚本一次搞定。我一般会写一个.cmd文件内容大致如下setMode -bscan setCable -p auto addDevice -p 1 -file D:\fpga\flash\top.bit addDevice -p 2 -file D:\fpga\flash\flash.mcs program -p 2 -e -v quit这个脚本的逻辑是先设置边界扫描模式自动识别下载线然后添加FPGA器件和Flash器件最后对Flash执行擦除、编程、校验。-e是擦除-v是校验这两个参数建议都加上擦除保证没有残留数据校验保证烧进去的数据和mcs一致。运行方式在命令行里执行impact -batch flash.cmd。注意iMPACT的路径要加到系统环境变量里或者用绝对路径调用。ISE 14.7安装后iMPACT在Xilinx\14.7\ISE_DS\ISE\bin\nt64目录下。批处理方式还有一个好处可以集成到Makefile或CI流程里。比如你每次编译完bit自动调用iMPACT生成mcs并烧录省去人工操作。不过要注意批处理模式下如果下载线没插好或Flash型号识别错误脚本会直接报错退出不会像GUI那样弹窗提示所以第一次用建议先用GUI确认硬件连接正常。3.3 mcs生成后的验证mcs生成后别急着烧先做两件事。第一检查mcs文件大小。一个未压缩的bit文件mcs大小大约是bit的2.5倍左右因为HEX格式每个字节用两个ASCII字符表示再加上地址和校验。如果mcs大小异常小可能是生成过程中断了。第二用iMPACT的Verify功能把mcs和bit对比一下确认转换无误。我个人的习惯是生成mcs后立刻用impact -batch跑一次校验确认mcs能被iMPACT正确解析。这一步花不了几秒钟但能避免烧录到一半发现文件损坏的尴尬。4. 把mcs烧进FlashJTAG链路与Flash识别的实战细节4.1 硬件连接JTAG链路上的器件顺序烧录Flash时JTAG链路上通常有两个器件FPGA和Flash。但Flash本身没有JTAG接口它是通过FPGA的边界扫描单元间接访问的。所以iMPACT里看到的器件顺序是第一个是FPGA第二个是Flash逻辑上挂在FPGA后面。实际连接时下载线接板子的JTAG口板子上的FPGA和Flash之间的SPI连线必须正常。如果SPI连线有问题iMPACT能识别到Flash但读写会失败。我遇到过一块板子Flash的CS信号被外部电路拉死iMPACT识别Flash正常但一编程就报failed to communicate with the flash chip。后来查原理图发现CS上有个电阻下拉导致FPGA无法拉低CS。所以硬件排查时SPI的四根线CS、CLK、MOSI、MISO都要确认。4.2 iMPACT识别Flash失败的常见原因iMPACT识别Flash时会通过FPGA发送Read ID指令读取Flash的制造商ID和设备ID。如果读不到就会报cannot load flash device description或failed to communicate with the flash chip。常见原因有这几个Flash型号选错iMPACT里选的Flash型号和实际板子上的不一致导致ID不匹配。解决办法是查Flash datasheet找到Manufacturer ID和Device ID在iMPACT里手动添加。SPI时钟太快iMPACT默认的SPI时钟可能偏高某些Flash支持不了。可以在iMPACT的Flash属性里把时钟降下来比如从10MHz降到1MHz。FPGA未配置烧录Flash前FPGA必须先配置一个能正常工作的bit因为iMPACT是通过FPGA的边界扫描逻辑去访问Flash的。如果FPGA里没有配置或者配置了一个IO状态不对的bitFlash访问就会失败。所以流程上先下载一个正常的bit到FPGA再烧Flash。电源不稳Flash编程时电流较大如果板子供电不足会出现随机失败。用示波器看Flash的VCC编程瞬间不能有明显跌落。4.3 烧录过程中的参数设置在iMPACT里对Flash执行编程时有几个选项要留意Erase建议勾选。Flash编程前必须擦除否则旧数据可能残留。擦除是按扇区进行的SPI Flash的扇区大小一般是64KB或4KB擦除整个芯片需要几秒钟。Program把mcs数据写入Flash。Verify烧录后校验确保数据一致。这个选项强烈建议勾选虽然多花一点时间但能保证可靠性。Blank Check擦除后检查是否全空一般不用勾因为Erase已经保证了。烧录时间取决于Flash容量和mcs大小。16Mbit的Flash烧一个2Mbit的mcs大约需要10到20秒。如果超过一分钟还没完成可能是SPI时钟太慢或Flash有问题。4.4 烧录完成后的启动验证烧录完成后iMPACT会提示Program Succeeded。这时候别急着拔下载线先做启动验证断开下载线给板子断电再上电。观察FPGA的配置指示灯如果有DONE信号灯正常情况下DONE灯会在上电后几百毫秒内亮起。如果DONE灯不亮说明FPGA没有从Flash成功加载配置。如果DONE灯不亮排查顺序是先确认Flash里的数据是否正确重新用iMPACT读回Flash内容和mcs对比再确认FPGA的配置模式引脚M[2:0]是否设置为SPI模式。Spartan-6的M[2:0]引脚决定启动模式001是SPI模式如果设成000就是JTAG模式上电不会从Flash加载。这个引脚通常在板子上有跳线或电阻配置查原理图确认。5. 那些年我踩过的Flash固化坑5.1 “JTAG能跑Flash不跑”的典型排查链路这个现象太常见了我至少遇到过五六次。排查思路可以按以下顺序走第一步确认bit文件本身没问题。用JTAG下载同一个bit功能正常说明bit逻辑没问题。第二步确认mcs生成正确。用iMPACT的Verify功能对比mcs和bit确认转换无误。第三步确认Flash烧录成功。用iMPACT的Readback功能把Flash内容读回来和mcs对比。如果读回来的数据和mcs不一致说明烧录过程有问题可能是Flash型号选错或SPI时钟太快。第四步确认FPGA配置模式。查M[2:0]引脚确认是SPI模式。有些板子用拨码开关选择启动模式拨错了就启动不了。第五步确认ConfigRate。如果前面都正常但启动仍然失败把ConfigRate从6降到3或2重新生成bit和mcs再烧一次。这个参数对启动成功率影响很大尤其是老Flash或长走线的情况。第六步检查Flash的WP写保护引脚。有些板子把WP引脚接地或接VCC导致Flash被写保护烧录时看似成功实际数据没写进去。用万用表量一下WP引脚电平。5.2 Flash容量与mcs地址范围的匹配问题mcs文件里包含地址信息iMPACT烧录时会按地址写入Flash。如果mcs的地址范围超过了Flash的实际容量烧录会失败或数据被截断。比如Flash是8Mbit1MBmcs覆盖了2MB的地址范围那超出部分写不进去。反过来如果mcs的地址范围小于Flash容量没问题剩余空间空着就行。但要注意有些FPGA启动时会从Flash的0地址开始读如果mcs的起始地址不是0FPGA可能读不到正确的配置数据。所以生成mcs时起始地址一定要设为0。我遇到过一种情况客户用了一个第三方工具生成mcs起始地址设成了0x1000结果FPGA启动时从0地址读读到的全是0xFF配置失败。后来用iMPACT重新生成起始地址设为0问题解决。5.3 多配置镜像与Golden Image的注意事项有些应用需要多个配置镜像比如Golden Image加Update Image用于远程升级。这种情况下mcs的地址分配要提前规划。Golden Image放在0地址Update Image放在某个偏移地址FPGA启动时先加载Golden Image再由逻辑决定是否切换到Update Image。ISE的iMPACT支持生成多个mcs但地址分配需要手动设置。我建议在生成mcs之前先画一张Flash地址映射表明确每个镜像的起始地址和大小避免地址重叠。另外多镜像模式下ConfigRate和启动时序要留足裕量因为FPGA可能需要尝试多次加载才能成功。5.4 批处理脚本中的常见报错与处理用impact -batch时常见的报错有ERROR:Flash download failed - Target DLL has been cancelled这个通常是下载线驱动问题或USB连接不稳定。换一个USB口或者重新安装下载线驱动。WARNING:Failed to communicate with the Flash chipSPI通信失败检查Flash型号、SPI时钟、硬件连线。Cannot load flash programming algorithmiMPACT找不到对应Flash的编程算法需要手动指定或更新iMPACT的Flash列表。处理这些报错时我一般先用GUI模式跑一遍看具体是哪一步出错然后再回到批处理模式调整脚本。GUI的报错信息更详细有助于定位问题。6. 固化完成之后上电自启动的验证与长期可靠性6.1 上电自启动的完整验证流程烧录完Flash拔掉下载线断电再上电。观察几个信号DONE信号FPGA配置完成后DONE引脚会拉高。如果板子上有DONE指示灯灯亮表示配置成功。INIT信号配置开始前INIT会拉低配置完成后拉高。如果INIT一直低说明配置过程出错。功能验证配置成功后跑一个简单的测试逻辑比如LED闪烁或串口输出确认FPGA逻辑正常工作。如果DONE不亮先别急着重新烧用示波器看Flash的CS、CLK、MOSI信号确认FPGA上电后有没有发起SPI读取。如果没有信号说明FPGA没有进入SPI启动模式查M[2:0]引脚。如果有信号但DONE不亮说明Flash里的数据有问题重新烧录。6.2 长期可靠性Flash数据保持与刷新Flash存储的数据不是永久的一般数据保持时间是10到20年但高温会加速数据丢失。工业级应用里如果设备长期运行在高温环境建议定期刷新Flash内容。另外Flash的擦写次数有限SPI Flash一般10万次左右频繁烧录会缩短寿命。我个人的做法是在产品出厂前烧录一次之后除非固件升级否则不轻易擦写Flash。固件升级时用iMPACT的擦除加编程流程不要只编程不擦除否则旧数据残留可能导致校验失败。6.3 从ISE到Vivado固化流程的异同虽然这篇讲的是ISE但很多人也在用Vivado。Vivado里生成mcs的流程类似但工具换成了write_cfgmem命令烧录用program_hw_cfgmem。Vivado的mcs生成更自动化地址分配和Flash型号识别也更智能。不过底层原理一样bit转mcsJTAG烧Flash上电自启动。如果你同时维护ISE和Vivado项目建议把mcs生成和烧录的脚本统一管理比如用Makefile封装避免两套流程混淆。我在实际项目中ISE和Vivado的烧录脚本放在同一个目录下用不同的目标名区分比如make flash_ise和make flash_vivado这样切换项目时不容易搞错。最后再分享一个小技巧烧录Flash前先用iMPACT的Read ID功能确认Flash能被正确识别。这一步只要几秒钟但能提前发现硬件连接问题避免烧到一半失败。我现在的习惯是每次烧录前都先Read ID确认Flash在线再执行擦除和编程。这个习惯帮我省了不少返工时间。
返回列表