
搞FPGA的兄弟肯定遇到过这个场景新买的Flash芯片板子画好了JTAG链也扫出来了到了iMPACT里添加SPI Flash准备固化固件一点Program啪一下弹出个“ID check failed”整个流程卡死在起点。更气的是有时候下载器、板子、Flash都是好的查了半天硬件没问题问题就出在ISE的器件库根本不认识这颗新Flash。我最早碰上这个报错是在一个量产项目上一批板子换了更便宜的国产物料主控还是那款老芯片结果iMPACT坚决不认同一个板子换回原装Flash就一切正常。从那次之后我把这个问题的来龙去脉彻底摸了一遍。这篇文章就把所有能绕过ID检测的方案、原理、坑一次讲清楚。1. 认识ID check failed报错背后的三个真相1.1 iMPACT到底在检查什么先说原理。FPGA要从SPI Flash启动上电后需要从Flash里读配置数据所以烧录时Flash里写的必须是FPGA能认的格式。iMPACT做烧录的时候会通过JTAG链让FPGA充当一个“中间人”FPGA再去操作SPI Flash。整个链路里iMPACT需要确认“挂在SPI总线上的这颗器件确实是你要烧的那颗”于是就会发起一个读ID操作。SPI Flash都遵守JEDEC标准内部有9F指令用来读取3字节的Manufacture ID和Device ID。比如Winbond的W25Q128ID是EF 40 18Macronix的MX25L12835F是C2 20 18。iMPACT在扫描到Flash之后会把读回来的ID和数据库里记录的ID比对对不上就报“ID check failed”或者“The IDCODE read from the device does not match the expected IDCODE”。这个机制本来是为了防止你选错型号烧了不匹配的数据但在实际开发中它经常误伤“数据库里没有的新型号”或者“国产替代型号”。这种检查本质上是对比“预期值”和“实际值”所以绕过思路无非两种让iMPACT不检查或者让数据库认识这颗芯片。1.2 为什么你的Flash会“ID不匹配”实际项目中我归纳了一下报错原因主要就三类排查时要先对号入座。第一类是型号太新ISE数据库里根本没有。ISE 14.7是2013年的版本之后几乎没怎么更新那时候市面上的SPI Flash主流还是W25Q64、W25Q128这些后来出的W25Q256、W25Q512、各类国产GD25Q系列、XM25QH系列iMPACT一概不认识。这类情况最常见。第二类是板子硬件连接有问题导致FPGA读回来的ID是错的。比如SPI Flash的片选没接对、DO脚虚焊、MISO/MOSI短路或者FPGA的配置引脚没有设置成SPI模式。这种情况下读回来的ID可能是全F或者全0同样会报ID check failed。注意区分“ID不匹配”和“读不到ID”这两种现象前者数据库里有这颗型号但值对不上后者数据库里根本没有任何值能匹配。第三类是FPGA配置模式不对。部分FPGA需要外部引脚设置成主SPI模式才能正常访问Flash如果引脚拨码错误FPGA内部Flash控制器根本没激活JTAG链路里虽然能识别FPGA但访问Flash时读回来的全是噪声。1.3 常见误区这不是板子坏了遇到ID check failed很多新手第一反应是Flash坏了或者板子焊接有问题。我在现场踩过的坑可以负责任地告诉你绝大多数情况下板子和芯片都是好的就是软件不认识。我遇到过最典型的例子同一批板子在装了ISE 13.4的旧电脑上能正常烧写在ISE 14.7的新电脑上报ID错误这就是版本数据库差异。所以第一步不是动烙铁而是先确认“硬件链路是否健康”。最快的方法就是用示波器抓一下FPGA和Flash之间的电平逻辑或者直接换一颗数据库里有的同容量Flash试烧一次。如果数据库里有的能烧、没有的报错基本就能锁定是ID数据库的问题硬件没有问题。2. 最省事的方案让iMPACT忽略ID检测直接烧写2.1 GUI模式下强制继续的操作路径最简单粗暴的方法就是在iMPACT的图形界面里当ID不匹配的弹窗出现时选择强制继续。但这里有个细节不同版本的iMPACT弹窗的选项名称不一样。在ISE 14.7里点开“Program”后如果ID不对会弹出一个警告框提示读到的ID和预期不符问你是否继续。这种弹窗出现的时候关键是不要点Cancel要找“Yes”、“Continue”、“Ignore”这类选项。如果弹窗里没有明显的强制选项还有一个办法回到添加Flash器件的步骤手动选择Flash型号时不要选具体型号直接选“Generic SPI Flash”这一项。Generic方式就是通用SPI Flash它不比对具体ID只要容量和扇区参数对得上就能往下走。选Generic时会让你填容量和品牌这个要注意填对否则后续烧录时地址范围会错乱。以W25Q128为例容量16MB页大小256字节扇区4KB。Generic选项里把这些参数填正确iMPACT就能按照通用协议擦除、写入、校验。2.2 批量脚本模式下也有跳过参数如果你习惯用批处理脚本跑iMPACT而不是每次都点GUI那更简单。iMPACT支持命令行批处理模式可以把烧录过程整理成一个.cmd脚本每次跑一遍省去大量重复点击。在写脚本时烧录命令里可以带一个跳过ID检查的参数这样就算Flash型号不在数据库里脚本也能正常往下执行。我这里以ISE 14.7为例给出一个常用的SPI Flash烧写脚本模板setMode -ss addDevice -p 1 -spi W25Q128 identify program -e -p -v -skipid quit这个脚本做了四件事设置SPI Flash模式、添加Flash器件、识别器件、擦除并写入和校验。最后一行program命令里的-skipid就是跳过ID检查的关键。如果你的iMPACT版本不认-skipid这个参数可以试试-ignoreid或者-force不同小版本号命令上有细微差异。还有一点脚本里指定了W25Q128这个型号但实际目标芯片可能是别的品牌。这里有个小心机你可以故意指定一个容量和结构相近的已知型号配合-skipid参数iMPACT就不会真正校验ID只是借用这个型号对应的扇区结构来完成擦写。比如你的板子实际是GD25Q128脚本里写成W25Q128只要容量和扇区布局一致烧完之后完全正常。2.3 用Generic方式选型的好处与注意Generic SPI Flash这个选项是iMPACT隐藏的一个“万能钥匙”。选Generic的好处很明显不用管什么品牌不用查什么IDCODE只要容量匹配就能烧。但代价是你失去了iMPACT对Flash指令集的自动适配能力。正常烧录时iMPACT会调用特定型号的指令序列来擦除、编程。如果选GenericiMPACT会按标准的JEDEC公共指令集来操作。当前市面上绝大多数SPI Flash都兼容这套公共指令但有小部分特殊型号比如需要4字节地址模式才能访问大容量的Flash32MB以上或者需要独有的解锁指令的芯片Generic方式可能就会失败。所以我的建议是开发阶段临时用Generic跳过ID检查没问题但量产之前还是应该按照第三章的方法把具体型号的ID加到数据库里让烧录过程走完整校验避免批量生产时因为个别芯片的怪癖导致废品。3. 治本之策给iMPACT添加新Flash的ID Code3.1 找到iMPACT的器件数据库文件跳过ID检查是权宜之计最正规的方案是给iMPACT“喂”新Flash的ID信息让它真正认识这颗芯片。ISE安装目录下有一个Flash器件数据库文件iMPACT启动时会加载这个文件烧写时拿实际读到的ID到里面去比对。以ISE 14.7在Windows下的默认安装路径为例核心文件在C:\Xilinx\14.7\ISE_DS\ISE\data\impact\目录下。这里面有一个叫flash_programmers的文件还有几个跟Flash型号相关的配置文件。你可以用文本编辑器打开这个文件搜索一下有没有你的Flash型号。以W25Q128为例正常安装的ISE 14.7里其实是有这个型号的所以打开文件后搜索“W25Q128”能找到一条记录。但你搜“W25Q256”或者“GD25Q128”很可能就搜不到。找到已有条目后照着它的格式复制一份改成你的型号名和IDCODE保存重启iMPACT新型号就进数据库了。3.2 手写一条新的Flash定义记录打开flash_programmers文件后你会看到类似这样的条目结构具体字段名不同版本略有差异# Winbond W25Q128 SPI Flash W25Q128 { IDCODE 0xEF4018; PageSize 256; SectorSize 4096; NumSectors 4096; ... }这个结构里的关键字段是IDCODE、PageSize、SectorSize和NumSectors。IDCODE就是前面说的JEDEC IDPageSize通常是256字节SectorSize是擦除扇区大小NumSectors是扇区总数。这些参数在Flash芯片的官方数据手册里都能查到。添加新条目时我的建议是带两行注释一行写品牌型号一行写数据手册版本方便以后追溯。我这里以添加一颗常见的GD25Q128为例演示一下怎么改# GigaDevice GD25Q128 SPI Flash GD25Q128 { IDCODE 0xC84018; PageSize 256; SectorSize 4096; NumSectors 4096; }改完之后保存文件关闭iMPACT再重新打开就能在Flash型号下拉列表里找到GD25Q128了。这里有一个非常关键的提示修改数据库文件之前一定要先备份原文件。ISE这个工具本身就比较娇贵配置文件改坏可能导致iMPACT直接打不开到时候还得重装那是真的伤。3.3 修改配置的后续动作数据库文件改完之后不是立即生效的。很多人改完发现新加的型号还是找不到就开始怀疑是不是路径不对。其实原因通常有两个第一个原因是iMPACT缓存了旧配置必须彻底关闭所有ISE相关进程再重新打开。建议打开任务管理器把impact.exe、xilinx_jtag.exe之类的进程全部结束再重新启动。第二个原因是文件权限问题。ISE 14.7如果安装在C:\Program Files目录下Windows的UAC用户账户控制会阻止普通权限的编辑器写文件。你可能以为保存成功了实际上被系统挡了回来。解决办法是用管理员身份运行文本编辑器再在保存时确认文件已确实更新。第三个原因是大小写和格式问题。IDCODE前面的0x前缀不能丢分号结尾不能漏注释行用#开头。有时候只是格式错了一位整个解析就失败了。4. 绕开iMPACT的降维打击换工具4.1 用Vivado Hardware Manager做SPI Flash烧录如果你手里的FPGA是7系列的那其实还有一条更干净的路改用Vivado的Hardware Manager做烧录。Vivado的器件库更新频率高得多对新Flash的支持比ISE好不少而且Vivado里也保留了一套完整的Flash烧写功能支持SPI和BPI两种配置方式。操作路径是打开Vivado - 打开Hardware Manager - 连接开发板 - 右键点击FPGA器件 - 选择“Add Configuration Memory Device”。这里弹出来的器件列表比ISE全很多基本能覆盖市面上主流的Flash型号。如果列表里没有Vivado同样支持Generic方式直接填容量参数就行。但要提醒的是Vivado和ISE不是完全替代关系。老的V5、V6、Spartan-6这些器件Vivado根本不支持只有ISE能管。另外Vivado的Hardware Manager在烧写SPI Flash时必须要有一个有效的硬件平台文件操作前需要先打开一个工程或者至少有一个ltx文件这个跟iMPACT直接甩开工程操作的方式不太一样刚上手时会觉得流程很啰嗦。4.2 用第三方烧录器直接操作Flash还有一种彻底脱离FPGA工具链的思路不通过FPGA直接用独立的SPI Flash烧录器烧芯片。市面上几十块钱到几百块钱不等的USB SPI Flash编程器配合烧录软件直接夹在Flash芯片上就能读写完全不经过FPGA也就不存在ID check failed的问题。这种方案特别适合调试阶段。比如你想快速验证固件内容对不对或者手头没有JTAG下载器直接用烧录器就能把固件写进Flash还能整片读出来做比对。需要注意的是在线夹着烧录时板子必须断电否则Flash的其他引脚被板子上电路拉住了烧录器驱动不了很容易烧写失败。另外量产场景下如果板子数量很大我建议直接采购支持离线烧录的编程器让产线先把固件烧到Flash里再贴片到板子上。这样既绕开了JTAG链路的限制又提高了产线效率一台离线编程器可以同时烧多颗芯片。这个思路不是逃避问题而是从生产流程上彻底消灭了“每块板子都要过一遍iMPACT”这个环节。4.3 断开JTAG用SPI独立烧录器连接如果你决定用第三方烧录器接线是核心。SPI Flash引脚不多但接线错了轻则烧不进重则可能搞坏芯片。标准SPI Flash的引脚定义是1脚CS片选、2脚DO数据输出、3脚WP写保护、4脚GND、5脚DI数据输入、6脚CLK时钟、7脚HOLD保持、8脚VCC。跟烧录器连接时把CS、CLK、DI、DO、GND、VCC这六根线接上就行WP和HOLD两个引脚在烧录时原则上要拉高否则芯片可能进入保护状态写不进去。很多烧录器配套的夹具自带拉高但如果是手工飞线一定要把WP和HOLD接到VCC上这俩脚悬空很容易造成烧录异常。电源电压要特别注意。老一点的Flash是3.3V供电新一些的有些是1.8V烧录器要匹配对应电压档位不然轻则通信失败重则因为电平不匹配把芯片IO口打坏。我见过有同事把3.3V的Flash插到1.8V档位上芯片没坏但怎么都读不到ID排查了半小时才发现是电压档选错了。5. 实操手记一个Win11下ISE 14.7的完整修复案例5.1 从安装到报错的流程复盘前阵子帮一个朋友复现问题他的情况很有代表性新换的Win11电脑刚装好ISE 14.7连接下载器时一切正常能识别到FPGA但添加Flash后双击Program立刻弹出ID check failed。他的板子是老设计用的是Spartan-6 FPGA加一颗W25Q64按道理这颗型号ISE是认识的怎么会报错我到了现场一看问题出在三个环节叠加。第一Win11下安装ISE 14.7本身就要做一些兼容性设置他没有设置导致软件部分功能异常第二ISE安装时没有用管理员权限驱动装得不完整下载器和电脑通信时数据容易出错第三他选的不是W25Q64而是Generic SPI Flash但Generic参数里容量选错了读回来的ID当然对不上。这个案例说明ID check failed这个报错不一定就是“数据库里没有这个型号”这一个原因。系统兼容性、驱动异常、参数配错都可能让读ID这个过程出错。遇到报错时先按第五章的思路把环境层面的变量全部排除掉再考虑数据库和芯片本身的问题。5.2 一步一步完成“忽略ID”烧写并校验下面用一个完整的例子演示从添加Flash到完成烧写的全过程。环境是Win11 ISE 14.7下载器是Xilinx Platform Cable USB II目标板是Spartan-6 W25Q64。第一步连接下载器和板子打开iMPACT双击“Boundary Scan”然后右键点击空白处选择“Initialize Chain”。正常情况下软件会识别出链上的FPGA显示为“unknow device”或具体型号。第二步右键点击FPGA器件选择“Add SPI/BPI Flash”。在弹出窗口中选择Flash品牌和型号。如果你的型号不在列表里就选“Generic SPI Flash”。第三步如果刚才选的是Generic会弹出参数配置界面容量填8MBW25Q64是64Mbit换算后是8MByte页大小256扇区4KB。填好后点击OK。第四步双击Flash器件的图标打开操作面板。勾选“Erase Before Programming”擦除后编程、“Verify”校验、“Blank Check”空检。选择要烧录的固件文件注意选对文件格式SPI Flash烧录用的是.mcs文件不是.bit文件。第五步点击Program开始烧录。如果弹出ID不匹配的警告直接选择忽略/继续。烧录完成后看状态栏有没有“Program succeeded”再确认Verify这一栏没有报错。第六步断电重上电观察FPGA是否从Flash正确加载配置。如果加载成功板子行为正常说明整个链路没问题。5.3 固化后上电不启动别急着怀疑Flash烧录提示成功了但板子断电再上电FPGA没有正常启动这是很多新手都遇到过的问题。别急着把Flash拆下来重新烧先按下面的顺序排查。首先是检查FPGA的配置模式引脚。Spartan-6的M0、M1、M2三个引脚决定了配置模式要设置为主SPI模式也就是M[2:0]001不同厂商设置不一样。如果这组引脚悬空或者拨错了位置FPGA上电后根本不会去读Flash看起来就像“没烧录成功”。其次是检查Flash的片选和时钟。上电瞬间用示波器抓一下Flash CS引脚正常应该有一个从高到低的脉冲。如果没有这个脉冲说明FPGA压根没有发起读Flash操作问题出在配置引脚或JTAG口的状态上。最后是检查固件格式。有时候你烧的确实是.mcs文件但这个.mcs文件生成时起了问题。ISE里生成mcs文件的流程是先综合出.bit文件再通过Generate PROM File功能转换成.mcs。如果转换时Flash型号、位宽这些参数设置不对生成的mcs格式就可能不对FPGA读不懂自然启动不了。6. 避坑清单与高级技巧6.1 烧写时最常犯的三个错误第一误勾选“Erase Before Programming”。这个选项的作用是烧写前先擦除整片Flash防止旧数据残留导致烧写后校验不一致。但在某些场景下比如只想更新配置的一部分这时候擦除反而会破坏其他数据。开发阶段一般建议勾上量产阶段如果要单独更新某一块就要谨慎处理。第二选择错误的文件格式。.bit文件是FPGA直接配置用的不能直接烧进Flash。烧Flash必须用.mcs或.bin格式。很多新手直接点开Program选了一个.bit文件iMPACT不会报错但烧进去的固件启动不了因为.bit文件头部有大量JTAG配置指令Flash控制器读不懂。第三Verify失败后忽略警告继续发货。做了这一步我就当你前面白看了。Verify失败说明Flash里的数据和源文件不一致可能是擦除不彻底、电压不稳或者Flash寿命问题。出现这个情况应该先换一颗Flash再烧一次而不是抱着侥幸心理把问题板子流到生产环节。6.2 让现场更容易的小技巧保存impact批处理脚本前面提过iMPACT支持批处理模式。我强烈建议一个项目调试稳定之后把烧录动作整理成一个.cmd脚本整个团队共用。这样不管是换电脑还是换人操作都能保证烧录参数完全一致彻底规避手工点击时选错参数的问题。保存脚本的方式很简单在iMPACT的GUI里做一次完整操作然后打开“View - Log”窗口把里面的命令全部复制出来保存成.cmd文件就行。以后要用的时候打开命令行窗口输入impact -batch xxx.cmd就能自动跑完整个烧录流程。脚本还有个好处可以加一些自动化判断。比如在脚本里加一个读回校验的步骤烧完自动读一遍并比对把整个流程做成无人值守。产线技术员不需要理解FPGA是什么双击一个脚本就能完成烧录出错率比手点GUI低得多。6.3 关于调试下载器Platform Cable USB的几个问题ID check failed这个问题有时候看似是Flash的锅实际上是下载器的问题。Platform Cable USB这种下载器在USB连接状态下如果供电不足JTAG信号的电平就会不稳定导致FPGA回读的数据出错表现出来就是ID不对。遇到电压不稳定的情况可以尝试换一个USB口最好用电脑后置的USB口不要用前置面板的接口。还可以检查一下下载器的JTAG线序TCK、TMS、TDI、TDO、GND、VREF这六根线VREF是参考电压必须连接到板子上FPGA的同一个电压域。如果VREF悬空下载器输出的电平就不知道是多少读回来的ID大概率是乱的。下载器速度设置在iMPACT里其实可以调默认的时钟频率在比较恶劣的布线情况下可能会出问题。打开iMPACT的Cable Setup把Line Speed降低一档再试。这个设置不影响正常烧录速度但是在排除故障时值得一试。在我自己的项目里遇到ID check failed时我现在的排查顺序是这样的先确认是不是数据库里没有这个型号如果是就优先用Generic方式跳过如果Generic也失败就检查配置引脚和下载器连接最后才会考虑是不是板子硬件问题。这套流程帮我省了很多冤枉时间。最后再分享一个小技巧在数据库文件里添加新Flash型号时建议把同一品牌、不同容量的型号一起加进去。比如你这次用的是GD25Q128顺手把GD25Q64、GD25Q256的定义也写了下次换容量就不用再改文件了。多花两分钟省得以后被同样的问题再绊一次。