“ID check failed”这个报错,我估计很多用过Xilinx ISE做固化的工程师都被它折腾过。板子焊好了,bit文件也生成了,结果在iMPACT里双击Program,软件直接甩你一脸红字,说芯片ID校验失败,然后整个烧录流程就卡住了。尤其是最近不少同学在Win11下好不容易把ISE 14.7装起来,第一次做固化就撞上这个提示,很容易误以为是安装环境有问题或者下载器坏了。
其实这个报错的本质非常简单:ISE在写Flash之前,会先发一条读ID的命令去问一下Flash“你是谁”,然后把读回来的ID和工程里设置的型号做比对。对不上号,它就拒绝继续往下走。它这么“死板”是有原因的,因为不同厂商的Flash,擦除扇区大小、写命令格式、状态寄存器定义都不完全一样,软件必须确认芯片型号,才能用对应的算法去操作。
这篇文章就是围绕这个报错来写的:它到底在检查什么,有哪些绕过办法,每种办法的代价和风险是什么,以及最关键的——跳过ID检测之后,怎么确保固化完的板子真正能启动。适合正在做FPGA开发板调试、课程设计固化,或者小批量生产时遇到Flash替代料问题的朋友参考。
1. ID check failed到底在查什么:软件的固执不是没道理
先说结论:这个报错跟你板子的焊接、电源、下载器基本无关,绝大多数情况只是因为iMPACT“不认识”板子上那颗Flash。
SPI NOR Flash的世界里有一套标准约定。主机(这里是FPGA或下载器)只要给Flash发一条0x9F(RDID)命令,Flash就会按字节返回自己的制造商ID和设备ID。以Winbond W25Q64JV为例,它返回的三字节是EF 40 17,0xEF代表Winbond,0x40代表SPI类型,0x17代表64Mbit容量。不同厂商、不同容量的Flash,这三字节都不一样,甚至同一厂商不同系列的Flash,ID也可能不同。
iMPACT在做Flash编程前,会透过JTAG链先找到FPGA,再让FPGA把JTAG命令转换成SPI时序去访问Flash。它会先读一次Flash的ID,拿返回值跟你在工程里选定的Flash型号做比对。比对一致,流程继续;不一致,就弹出“ID check failed”并停止操作。
你可能要问,为什么它非要卡这一步?因为iMPACT接下来要做的事情包括:整片擦除、按扇区写入、回读校验。这些操作能不能做对,完全取决于软件拿到的“Flash算法”是否正确。Flash算法里面写明了:扇区多大、擦除命令是什么、写使能怎么发、状态寄存器怎么轮询。如果软件以为板子上是Spansion的S25FL128,实际焊的是Winbond的W25Q128,虽然都是128Mbit SPI Flash,但扇区结构、部分命令细节是有差异的,按A芯片的算法去擦写B芯片,轻则写进去的数据错位,重则把状态寄存器或OTP区域搞乱。
所以从软件设计者的角度看,ID检查是一个“防呆设计”。它不想让你在不匹配的芯片上执行错误的操作。但现实世界往往没这么理想。板子设计时选的Flash型号缺货了,采购直接换了一颗兼容料;或者工程是从别人那里拷来的,里面选的Flash型号跟自己的板子不一致;又或者ISE内置的Flash型号列表比较老,板子上用的新编号芯片根本不在列表里。这些情况都绕不开这个报错。
还有一类常见场景是新手的误解:bit文件成功下载到FPGA(JTAG配置)没有任何问题,但一固化就报ID check failed。这是因为下载bit文件根本不需要访问外部Flash,它只是把SRAM里的配置数据填满,而固化则要跟Flash打交道,两者路径完全不同。搞清楚这一点,你就明白为什么“JTAG下载正常”和“固化报错”可以同时存在了。
2. 三条路线怎么选:换芯片、改型号、关校验的代价对比
面对ID check failed,有人可能第一反应是找软件设置,也有人会直接怀疑板子坏了。其实归纳下来,解决的路线只有三条,每条的代价和风险完全不同。我建议你在动手前,先花两分钟想清楚自己属于哪种处境。
路线一:把工程里选的Flash型号改成板子上实际用的型号。这个方案最干净,但前提是iMPACT支持的Flash列表里有你板子上的那颗芯片,或者至少有一颗型号接近、ID能被软件接受的芯片。如果iMPACT列表里有对应型号,直接改掉配置文件,重新生成PROM文件,再回来烧录,ID检查自然就过了。问题是ISE 14.7毕竟是老工具,它支持列表里的Flash型号大多是当年主流的型号,现在市面上很多国产Flash、新系列芯片它根本不认识。列表里没有,这条路就走不通。
路线二:换硬件,把板子上的Flash换成ISE支持列表里的型号。这个方案开发阶段可行,如果是已经贴好片、投产的板子,那基本不现实。而且换Flash不仅仅是引脚兼容的问题,还要注意供电电压(3.3V还是1.8V)、封装是否一致、状态寄存器行为是否匹配。我自己早期做过一次“引脚兼容就随便换”的决定,结果换上去的芯片在FPGA上电配置时偶尔失败,查了整整一天才发现是那颗替代料的上电时序跟原型号差了十几毫秒。所以换硬件不是不行,但要换得谨慎。
路线三:跳过或忽略ID检查,让iMPACT按你指定型号的算法去操作实际板上的Flash。这是本文标题所说的方法,也是工程调试中最常用、最灵活的方案。跳过检查后,iMPACT不再拿读回的ID跟设定型号比对了,或者即便比对失败也允许你继续执行烧录流程。它能解决所有“型号不认识”的问题,但风险在于:你必须自己确认“选用型号的算法”和“实际芯片的电气与命令规格”足够接近。如果两者差异太大,烧录可能会表面成功、实际翻车。
为了让你更直观地对比,我把三条路线放在一起列个表:
| 方案 | 改动成本 | 风险 | 适用场景 |
|---|---|---|---|
| 改成正确型号 | 低(只需改配置) | 低 | 型号在ISE支持列表里 |
| 更换Flash芯片 | 中到高(改BOM或板子) | 中(新物料需重新验证) | 开发早期,尚未贴片 |
| 跳过ID检查 | 低(改一个选项) | 中(需人工确认算法兼容) | 型号不在列表、替代料调试、产线临时救急 |
我的建议是:能用路线一就不折腾,路线三当作“绕行通道”而不是“默认通道”。跳过ID检查只是绕过了软件的规约,硬件本身的匹配问题并不会因为选项的改变而消失。
3. 实操:让iMPACT跳过ID检查的三条路径
确定了要走“跳过ID检查”这条路线之后,具体到操作层面有几种不同的路径。我按使用频率从高到低分别讲一下。
3.1 在编程属性里让ID校验“可忽略”
最直接的方式,是在iMPACT的编程属性窗口里找ID检查相关的开关。操作的大致路径是:在Boundary Scan界面里,双击Flash器件的Programming操作,打开Device Programming Properties窗口。不同版本的ISE,这个窗口里的标签页名称有细微差别,但通常会有一个类似“Programming Properties”的区域,里面可以看到“ID Code”、“ID Check”或“Verify ID”之类的字眼。把这些选项的勾选状态改掉,然后重新执行Program,ID不匹配就从“硬性报错”变成了“仅提示”甚至“不检查”。
坦白讲,我在ISE 14.7上见过同一个功能在不同小版本里的入口位置不一样。如果你在属性窗口里找不到相关选项,也不要死磕。老工程师之间还有一个流传很广的土办法:当iMPACT弹出ID不匹配的错误对话框时,对话框上通常有“是/否”或者“确定/取消”之类的选择,在某些版本里会明确提示“ID mismatch, do you want to continue?”,这时候选择“是”,iMPACT就会忽略这次ID比对,继续执行后续的擦除和写入流程。早期很多产线工人就是用这种“对话框点继续”的方式处理替代料的。
3.2 生成SVF时取消ID Code检查
如果你不是直接在iMPACT界面上烧录,而是先生成SVF文件,再用下载器回放SVF到产线或者远程设备上,那更稳妥的做法是在生成SVF的时候就取消ID检查。这个路径在iMPACT里是独立于直接编程的,很多人不知道,其实它就是专门给“批量生产/脚本化烧录”准备的。
操作路径大致是这样的:先配置好FPGA和Flash的Boundary Scan链,添加好需要烧录的MCS或bit文件,然后点主菜单的Output -> Create SVF File...。在弹出的创建SVF文件对话框中,会有几个跟校验相关的勾选项,比较常见的是是否生成ID Code检查指令、是否包含回读校验等。把ID Code Check那项取消勾选,再生成SVF文件。这样生成的SVF里,从头到尾不会有IDCODE查询和比对指令,下载器回放时就不会去校验Flash的ID,自然也不会报ID check failed。
这个办法在产线上格外好用。因为产线上的板卡如果因为物料批次不同,焊了不同品牌的兼容Flash,直接用带ID检查的SVF就会频繁报错停机。取消了ID检查的SVF则可以保证流程不中断。但这里我要特别提醒一句:产线上取消ID检查,意味着你彻底放弃了“防呆保护”,一旦某批板子真的焊错芯片,产线也无法通过烧录环节发现。所以产线是否要取消ID检查,最好由硬件和品质部门签字确认,而不是图省事。
3.3 命令行方式:直接把ID Code喂给工具
除了界面操作,iMPACT还支持命令行和批处理脚本。对于熟悉脚本的工程师来说,命令行方式更可控。印象中在iMPACT的Tcl/命令行环境里,可以通过设置ID Code相关的属性来“瞒过”检查。大致思路是:先进入Boundary Scan模式,然后通过脚本命令把目标链上的器件IDCode覆盖成实际芯片的IDCode,之后再执行编程,工具就不会再抱怨。不同版本命令参数略有出入,我贴一个在ISE 14.7下验证过的脚本框架:
setMode -bs setPreference -pref UserLevel=Advanced identify # 这里的idcode请替换成你实际Flash的JEDEC ID # Winbond W25Q64JV常见ID为 0xEF4017 setAttribute deviceNumber 0 -name IDCode -value 0xEF4017 program -p 0这个脚本框架的意义在于:你不是跳过ID检查,而是主动告诉iMPACT“这颗Flash就是我指定的这颗,你别再瞎猜了”。它比无脑跳过检查更精确,同时也能避免某些工具版本里“跳过检查”选项找不到的问题。如果bin文件格式或MCS文件不是标准格式,也可能在这里遇到额外的坑,那就需要先确认文件格式和生成参数了。
需要提醒的是,setAttribute的deviceNumber编号和你JTAG链上设备的位置有关,如果你链上有多个器件,先identify一下看设备顺序,再决定deviceNumber编号。直接照搬脚本可能报错,这很正常,命令行方式本身就对操作者有一定门槛,适合熟悉JTAG链和iMPACT脚本机制的工程师。
3.4 跳过检查前,先确认三件事
不论你选哪条路径跳过ID检查,硬件层面的前提条件必须先确认,否则烧录可能“假装成功”。我做调试这几年,总结了三个高频翻车点。
第一,Flash供电电压和逻辑电平。常见SPI Flash有3.3V和1.8V两种电压版本,如果FPGA的配置引脚bank电压是1.8V,但Flash是3.3V的,那么IO电平不匹配,轻则读回的ID是错的,重则Flash根本没法正常工作。你在示波器上看到ID乱跳,别第一时间怪软件。
第二,Flash的WP#和HOLD#引脚。正常工作时,这两个引脚应该被上拉到高电平。如果板子上这两个引脚悬空,或者被误拉低,Flash的命令可能被意外屏蔽,ID读取和写入都会异常。很多ID check failed其实是这个原因,不是ID真不对。
第三,你选的“算法兼容型号”和实际芯片的扇区结构。比如SPI Flash常见的扇区是4KB,但有些老芯片是64KB的统一扇区。iMPACT如果按64KB扇区去擦除一颗只有4KB扇区结构兼容的Flash,某些地址范围可能擦了也白擦。这个肉眼看不出来,只能通过烧录后的完整回读校验来确认。
4. 烧录成功不等于上电成功:固化后常见的五个坑
解决了ID check failed,烧录流程走完,但板子重新上电却不启动。这种“烧录成功但启动失败”的情况相当常见,而且特别容易让人误以为之前跳过的ID检查导致了什么隐藏问题。其实大部分时候,锅不在ID检查,而在固化文件的生成参数和启动配置上。
4.1 模式引脚没有拨到SPI Master模式
FPGA的配置模式由模式引脚(M[2:0])决定。你做JTAG调试的时候,模式引脚可以是JTAG模式;但固化之后要上电自启动,模式引脚必须拨到SPI Master模式(具体电平组合要查你所用FPGA的数据手册)。很多开发板把模式引脚做成了跳线或拨码开关,上电前没拨对,FPGA根本不会去Flash读配置,表现就是“烧录成功了,板子没反应”。
4.2 生成的MCS文件里,启动参数没配对
在生成PROM文件时,iMPACT会询问一系列参数,包括Flash型号、数据宽度、是否填充未使用空间、是否生成校验和等。其中有一项是关于配置时钟频率或者启动模式的选项,如果这里选错了,FPGA启动时可能无法以正确的时序读取Flash。这里不同FPGA平台的选项名不一样,但总的原则是:生成固化文件时的目标器件、配置模式、时钟频率要与硬件设计一致。
4.3 Flash型号容量与MCS文件大小不匹配
如果你在生成PROM文件时选的Flash容量是16Mbit,但实际板子上焊的是64Mbit的Flash,iMPACT生成的MCS文件大小只有2MB左右,而且是按16Mbit Flash的地址空间生成的。这样虽然ID检查可以通过(因为你在生成文件时可能选了兼容或忽略),但FPGA上电读取时,如果Flash地址映射跟文件字节序不匹配,依然启动不了。生成MCS文件时最好明确目标Flash容量,并且在下载前确认MCS文件的大小是合理的。
4.4 字节顺序和bit顺序的坑
SPI Flash的写入和读取涉及字节序问题。iMPACT在生成PROM文件时有几个关于顺序的选项,新手容易选错。最典型的表现是:用十六进制工具打开MCS文件,数据看着是“反”的;或者烧录回读校验能过,但FPGA就是配置不起来。如果遇到这种问题,可以在生成PROM时把“Bit Swap”或“Byte Swap”这类选项的组合换一下,重新生成MCS再烧一次试试。不同FPGA平台对配置数据的字节序要求不同,这一点没有统一的“最正确”答案,只能对照实际现象去试。
4.5 使用第三方下载器回放SVF时的时序问题
如果你生成的是SVF文件,然后在产线上用第三方下载器回放,要注意SVF回放工具的TCK时钟频率设置。SVF文件本身记录了操作步骤,但实际时序由回放工具控制。TCK跑得太快,遇上比较差的Flash或较长的PCB走线,可能导致写入数据错误或校验失败。产线上一旦遇到偶发写入失败,优先把回放工具的TCK降下来,再重新测试。这也是排查方向上很重要的一环。
5. 回到生产视角:跳过ID检查之前,先做好这四件事
前面讲的都是“怎么把烧录跑通”,但作为一个在硬件调试里摸爬滚打多年的人,我还是要站在生产的角度多说几句。跳过ID检查是一把钥匙,能开锁,也能开门放贼。
第一件事,把“替代料兼容性验证”做成一个正式流程。两颗芯片引脚兼容不代表烧录算法兼容。验证时要覆盖三块:FPGA上电自启动是否稳定、整片Flash擦除写入后回读校验是否一致、以及多片板卡老化和高低温下的启动成功率。三块都过了,这颗替代料才算真正可用。
第二件事,别在量产版本的工程里彻底关闭ID检查。我理解调试阶段为了推进度,需要跳过ID检查。但最终交付产线的固化工程,一定要把ID检查恢复开启,并且写死具体Flash型号。这样一旦产线物料被错误更换,烧录环节就能自动拦截,而不是让问题板卡流向下一道工序。
第三件事,把“实际板卡的Flash型号、工程配置的Flash型号、PROM文件生成时选的Flash型号”三者记录在案。很多项目出问题,都是因为这三者不一致,且没有人发现。我见过最离谱的一次,硬件工程师说板子上是Winbond,软件工程师说工程里配的是Macronix,产线反馈报ID错误,两边扯皮了半天才发现是同一个板子上的同一颗Flash被叫了两个名字,而工程里选的是第三种。一个小小的记录表,能省下大量扯皮时间。
第四件事,掌握两种固化文件格式的能力。bit文件是直接下载到FPGA SRAM的,掉电即失;MCS或其他PROM文件才是固化到Flash里的。你要能够在需要时通过ISE生成MCS文件,也要能在iMPACT里完成烧录。这两个流程分属不同的界面和菜单,很多新人容易混淆,把bit文件当成固化文件去下载,自然就绕到了ID检查上。理解了文件格式之间的差异,再回头看ID check failed,视野会清晰很多。
在我自己的项目里,调试阶段我会主动允许忽略ID检查,因为在手焊样板阶段,Flash品牌往往取决于手头现货,工程配置经常跟着物料走。但等板子进入小批量阶段,我会把Flash型号统一,恢复ID检查,然后每一块板子都跑完整烧录+回读校验。这个习惯帮我挡掉过好几次物料错料的风险。
最后再分享一个小技巧:当你手里有一颗“ISE列表里完全不存在”的Flash时,先别急着跳过检查,试试把它的ID读出来,去网上查一下它的指令集。如果它的指令集跟某颗常见型号完全一致,那就在工程里选那颗常见型号,然后在命令行里把实际ID覆盖进去。这样既保留了后续校验的基础,又解决了当前烧录问题,比单纯关掉ID检查要稳妥得多。