把 USB-JTAG 下载器插到板子上,打开 Vivado Hardware Manager,Target 列表里刷出来的不是期望的 xc7z020,而是一串 00000000;或者设备认到了,Program Device 也报告成功,可板上 DONE 灯就是不亮,PS 端连串口打印都没有。这类问题我在调板过程中遇到过不止一次,最后发现每次都不是 bit 流的问题,也不是 RTL 代码的问题,而是三个特别容易被忽略的物理和配置条件在捣乱:JTAG 的 VREF 参考电压、芯片的启动模式引脚、以及上电复位时的时序握手。这篇文章把这三条隐藏条件一条条拆开讲透,并且给出一套从 Vivado Hardware Manager 界面到示波器探头的完整排查流程,帮你把原本可能花一下午的定位过程压缩到半小时以内。
1. 现象背后的真相:Hardware Manager 认识芯片,不等于 FPGA 能正常启动
1.1 JTAG 连接和 FPGA 启动,本质上是两条不同的链路
很多新手甚至不少有经验的工程师,会把“JTAG 能连接上”和“FPGA 能启动”画上等号,这是一个非常危险的误解。要理解为什么,得先分清两条链路。
第一条链路是 JTAG 边界扫描链路。USB 口出来,经过下载器转成 TCK、TMS、TDI、TDO 四根信号,进入 FPGA 的 TAP 控制器。TAP 控制器是芯片内部一个独立于配置数据路径的状态机,它只需要 TAP 电源域工作就能响应指令。Hardware Manager 里 的 Auto Connect、IDCODE 读取、设备列表扫描,全部走的是这条链路。
第二条链路是 FPGA 的配置启动链路。上电后,芯片内部 POR 复位,释放 PROGRAM_B 引脚,配置逻辑开始采样启动模式引脚,然后根据模式从 JTAG、SPI Flash、SD 卡或其它源加载配置数据,加载完成后内部 CRC 校验,最后拉高 DONE,进入用户模式。
这两条链路在芯片内部共享一部分引脚和电源域,但逻辑上是可以“半通”的。TAP 控制器活着,不代表配置状态机是健康的。我见过太多情况:Hardware Manager 能读到 IDCODE,看着一切正常,但 FPGA 实际上从未进入用户模式,DONE 引脚被外部电路或者启动模式卡死在低电平。这也是我要写这篇文章的原因——你在图形界面上看到的“成功”,往往只是一个局部成功。
1.2 把失败现象分成三类,定位效率立刻翻倍
我先给故障分个类,后面所有排查都围绕这三类展开。这是我在工作室白板上反复用过的一张表,现在直接放出来给你参考。
| 故障类型 | 表面现象 | 本质原因方向 |
|---|---|---|
| A 类:链路完全不通 | Open Target 失败,目标列表为空,提示 no cable / no target | USB 驱动、下载器损坏、TDI 到 TDO 链路断裂、VREF 完全没接 |
| B 类:链路能通,但数据混乱 | 目标能打开,设备列表读出 00000000 或 Unknown Device;或 IDCODE 时对时错 | VREF 电平异常、TCK 频率过高、扫描链上其它器件未供电 |
| C 类:链路正常,启动失败 | IDCODE 正确,Program 报告成功,但 DONE 不亮、功能不工作、上电后反复失败 | BOOT_MODE/M 启动模式错误、上电时序违反、PROGRAM_B/DONE 被外部电路钳位 |
你会发现,A 类和 B 类问题大多集中在 JTAG 物理链路本身,C 类问题才是真正意义上的“启动失败”。而本文要讲的三个隐藏条件里,前两个(VREF、启动模式)分别对应 B 类和 C 类,第三个(上电时序)是 C 类里最隐蔽的元凶。把这些条件提前排掉,很多疑难杂症根本不会发展到让人挠头的地步。
1.3 为什么这三个条件算“隐藏”?因为它们不在报错文本里
Vivado 的报错信息其实很“诚实”,但它只能报出它能观测到的东西。如果 VREF 电压接错,适配器感知到的逻辑电平阈值不对,Hardware Manager 可能会报出“设备不支持”或者“IDCODE 无效”,但不会告诉你“你的 VREF 电压错了”。如果启动模式引脚被板上的拨码开关设成了 QSPI 启动,而 Flash 里是空的,Hardware Manager 只会看到 FPGA 一直在等配置数据,最多给你一个超时,不会告诉你“请检查拨码开关”。
这三个条件都是在设计的原理图、PCB 布局、硬件上电顺序里埋下的坑,Vivado 作为软件工具只能看到结果,看不到原因。所以它们不是软件能自动检测出来的,必须靠人带着清单去查。下一节开始,我按优先级一个一个拆。
2. 隐藏条件一:VREF 参考电压没给对,JTAG 链路的“高电平”就是空中楼阁
2.1 VREF 的物理作用,以及最常见的接法
先说清楚 VREF 是什么。在 Digilent HS3、Xilinx Platform Cable USB II 这类下载器上,都会有一个名为 VTref 或者 VREF 的引脚。这个引脚的作用,是让下载器感知目标板上的 I/O 电压水平。下载器内部的输出驱动器会根据 VREF 的电压值,调整 TCK、TMS、TDI 这些输出信号的逻辑电平,同时也会参考 VREF 来判断 TDO 回传信号的高电平阈值。
打个比方,VREF 就相当于两个人的握手暗号。你和对方约好了用 3.3 V 来表示“1”,结果 VREF 给下载器报了一个 1.8 V,下载器就会按 1.8 V 的门限去驱动信号,对 3.3 V 的 FPGA 来说,这个信号可能根本够不到高电平的门限,握手自然就崩了。
最常见的正确接法,是把 VREF 引脚连接到 FPGA 的 Bank 0 的 VCCO 电压上。FPGA 的配置引脚(包括 JTAG 引脚)在电气上归 Bank 0 管,Bank 0 的供电电压决定了这些引脚的实际 I/O 电平。7 系列和 Zynq-7000 的 Bank 0 通常工作在 3.3 V 或 2.5 V,少数板子用 1.8 V。设计上 VREF 和 VCCO_0 直接相连,是最稳妥的方案。
但问题恰恰出在这里:很多板子在调试阶段,VCCO_0 这路电源压根就没被正确使能,或者供电顺序还没调好,而 VREF 又直接从 VCCO_0 上取,于是 VREF 就是 0 V。TAP 控制器只要 VCCAUX 有电就能工作,所以 JTAG 链路上其他信号是活的,但下载器的输出驱动参考电压是 0,整个 JTAG 链路实际处于“悬空”状态。
2.2 VREF 异常时的三种典型表现,对照你的现场情况
VREF 异常不会每次都报同样的错,它有三种典型表现,你可以对照一下自己遇到的现场:
第一种,链路完全识别不到。VREF 为 0 V 或者过低时,下载器根本不知道目标板上的高电平是几伏,TCK/TMS 信号驱动不出去,Hardware Manager 直接报连接失败。这种情况最容易被人误判成“下载器坏了”或者“USB 线有问题”。
第二种,IDCODE 读了全零或者随机值。这种情况最迷惑人,因为你说它完全不通吧,偶尔又能扫到一点影子;你说它通了吧,读出来的设备列表根本不对。实质是信号电平处在逻辑阈值边缘,采样结果不稳定。我遇到过一次,同一个板子上午能连,下午不能连,最后发现是实验室空调温度变化导致某个电平裕量本来就很小的电路彻底飘了。
第三种,连接正常、IDCODE 正确,但 Program 到一半失败。很多人不理解,为什么 VREF 会影响编程?因为编程过程中大量数据要通过 TDI/TMS 移位进入芯片,任何一个 bit 的电平没有达到门限,就会导致移位数据错位。数据一旦错位,芯片内部的状态机立刻乱套,报错信息千奇百怪。这种问题用示波器看 TCK/TMS 波形最容易暴露:如果波形幅值明显偏低,或者上升沿有明显台阶,基本就是 VREF 没接对。
2.3 从原理图到示波器:VREF 的排查与修复实操
如果现场遇到类似问题,我建议按这个顺序查:
先看原理图,JTAG 连接器上有没有 VREF 引脚。很多自制的 JTAG 排针只有 2x5 共 10 脚,里面第 1 脚(右上角)往往就是 VTref。找到后确认它连到哪里去了。
用万用表直流电压档量 VREF 对地电压。对 7 系列和 Zynq-7000 的板子,正常情况下应该等于 Bank 0 的 VCCO。如果测出来是 0 V,先查这路电源是否使能,再查这一路电源的 LDO/DC-DC 有没有输出。
如果 VREF 和 VCCO_0 是分开的,就要确认板子上是否有跳线帽或者零欧电阻把它们连起来。我见过不少板子原理图里画了“SB1 默认断开”,结果焊接时没焊,整个调试阶段 JTAG 都不稳定。
用示波器看 TCK 波形。正常情况应该是干净的数字方波,高电平接近 VCCO,低电平接近 0 V。如果看到高电平只有 1.5 V 左右,而 VCCO 是 3.3 V,几乎可以断定 VREF 环节出了问题。
临时修复的办法:如果 VCCO_0 已经正常输出 3.3 V,可以用一根飞线把 VCCO_0 接到 VREF 引脚上,然后重新扫描。这个方法虽然不优雅,但在调试阶段非常有效,能快速验证是不是 VREF 的问题。
注意:有些板载下载器(比如 FT2232 方案的)不一定有独立的 VREF 引脚,它的 I/O 电平直接由板上的 3.3 V 供电决定。这种情况下 VREF 问题出现的概率会低一些,但不代表没有——如果 FPGA 的 Bank 0 用的不是 3.3 V,而是 1.8 V 或 2.5 V,FT2232 的固定 3.3 V 输出依然存在电平不匹配的问题。这种设计我会在画板阶段就尽量避免。
3. 隐藏条件二:BOOT_MODE/M 引脚把芯片领上了一条错误启动路径
3.1 启动模式引脚是上电瞬间被“定格”的一排开关
FPGA 支持多种配置源:JTAG、SPI Flash、BPI Flash、SD 卡、SelectMAP 等。芯片在上电复位释放之后,做的第一件事不是配置自己,而是采样启动模式引脚。对 7 系列 FPGA 来说,这个引脚组叫 M[2:0];对 Zynq-7000 来说,对应的是 BOOT_MODE 引脚,实际是 MIO[5:4] 为主的一组信号。它们在上电瞬间被采样后,就决定了后续配置数据要从哪个口进来。
这里有一个关键认知:这个采样只在特定的复位释放窗口内有效。也就是说,你把板子断电重来,模式引脚才重新采样;如果你用 JTAG 在线下载 bit 流,软件并不会去重新触发这个采样过程,它走的是 TAP 控制器指令,跟启动模式没有直接关系。
这里面就藏着一个巨大的坑:Hardware Manager 里 Program Device 走的是 JTAG 通道,所以不管启动模式引脚是什么,它都能往 FPGA 里灌 bit 流。但如果你断一次电,FPGA 重新上电,启动模式引脚就会把芯片引向 SPI 或者 SD 模式。如果那个模式下没有任何有效配置数据,芯片就一直在那里傻等,表现为“启动失败”。
简单说:JTAG 能绕过启动模式直接配置芯片,但上电自动启动绕不过启动模式引脚。
3.2 三个现场高频场景,每一个我都实际踩过
场景一:Zynq 板卡 BOOT_MODE 拨到了 QSPI,Flash 里是空的。现象是:JTAG 能连上,PL 的 bit 流也能通过 Program Device 灌进去,DONE 瞬间亮了,但只要你一断电重启,所有现象全部恢复原样,板子依旧不工作。很多人的第一反应是“固化步骤出错了”,其实固化没错,错的是拨码开关。Zynq 上电后 BootROM 会按 BOOT_MODE 决定从哪启动,如果选了 QSPI,而 QSPI 里没有 FSBL,BootROM 就卡死了,PS 不启动,PL 也不会被自动配置。
场景二:Artix-7 板卡 M[2:0] 被默认电阻拉到 SPI 模式,SPI Flash 为空。此时你上电后立刻用 JTAG 去编程,会遇到一个比场景一更隐蔽的现象——Device 能识别,但 Program Device 偶尔失败,偶尔成功。原因是 FPGA 上电后先进入了主 SPI 配置状态,一直在等 Flash 返回数据,而这个等待过程还没结束,你的 JTAG 指令插了进去。TAP 控制器和配置状态机在内部争抢资源,结果就是行为不稳定。
场景三:板子上的 BOOT_MODE 引脚悬空。设计时以为“不接就是默认 JTAG”,实际悬空引脚的电平可能是随机的,或者被内部弱上拉拉到某个不期望的组合。调试的时候一切正常,换一批板子同一批物料就偶发启动异常。这种问题用肉眼看不出来,必须上电后用示波器量引脚电平。
3.3 如何验证启动模式,以及临时纠正的手段
排查方法不复杂,但需要你有意识去做:
首先,翻开原理图,找到模式引脚的连接关系。7 系列看 M[2:0] 有没有通过电阻上拉/下拉到固定电平,Zynq 看 BOOT_MODE/MIO 对应的拨码开关或者电阻网络。
然后用万用表或者示波器,在 FPGA 上电复位完成的瞬间测一下这几个引脚的电平。注意是“瞬间”,因为一部分引脚在配置完成后可能切换为普通 IO 功能,比如 Zynq 的 MIO 引脚一旦进入用户模式就可能作为 PS 外设使用,电平会被软件改写。所以测量时机要选在上电初期。
拿到电平组合后,对照芯片手册的启动模式表。以 Zynq-7000 为例,BOOT_MODE[2:0] 常见组合如下(具体以你要用的型号手册为准):
| BOOT_MODE | 启动源 | 备注 |
|---|---|---|
| 000 | JTAG | 调试首选 |
| 001 | QSPI | 板载 Flash 启动 |
| 010 | SD | SD 卡启动 |
| 011 | NAND | NAND Flash 启动 |
如果排查发现板卡默认不是 JTAG 模式,但现阶段只想验证逻辑功能,最快的办法是用飞线或者改拨码开关,把模式强行切到 JTAG,然后重新上电。这里要注意的是,改完模式引脚之后必须断电再上电,让它重新采样,只按一下复位是不够的。
如果是你的正式固件就打算从 SPI Flash 启动,那就不是切模式的问题,而是要先把正确的镜像固化进 Flash。调试阶段最省心的做法是:先把 BOOT_MODE 切到 JTAG 做逻辑验证,验证通过后再改回 SPI 模式,然后用 JTAG 或者 SD 卡把镜像烧到 Flash,最后断电重启确认。
提示:很多量产板为了方便调试,会专门设计一个 3 位拨码开关给 BOOT_MODE。如果你的板子已经画完了,却没有预留这个开关,那调试会非常痛苦。我的习惯是哪怕量产版要贴电阻固定模式,也至少留一组测试点或者 0 欧电阻位,方便后续换配置。
4. 隐藏条件三:上电时序和 PROGRAM_B/DONE 的握手窗口被破坏
4.1 为什么 JTAG 能枚举 IDCODE,配置状态机却可能没复位
第三个隐藏条件比前两个更底层,它直接关系到芯片内部状态机是否健康。很多人会问一个很有道理的问题:如果 TAP 控制器能枚举 IDCODE,说明芯片的 JTAG 域是有电的,为什么还会启动失败?
答案是:JTAG 域和配置状态机域虽然共用一部分引脚,但两者的复位条件不完全一样。TAP 控制器只要 VCCAUX 电压满足要求就能工作,而完整的配置启动流程依赖 POR 复位电路、电压监控、INIT_B 握手、DONE 握手这一整套流程。其中任何一环被破坏,配置状态机都可能处于“看起来活着,其实没就绪”的状态。
最容易出问题的是上电时序。7 系列 FPGA 的上电要求一般是 VCCINT 先上电并稳定,其次是 VCCBRAM、VCCAUX,最后是 VCCO。如果 VCCAUX 先于 VCCINT 爬升,或者 VCCO_0 明显滞后,POR 电路的行为就可能不符合数据手册要求。某些情况下 POR 会提前释放,配置状态机在电源还没稳定时就开始采样模式引脚,采到一个错误的值,后面自然起不来。
更隐蔽的是“慢爬坡”。如果 VCCINT 用了软启动能力很强的 LDO,并且输出电容特别大,电压从 0 爬到 1.0 V 花了 200 ms,而 VCCAUX 的 DC-DC 100 ms 就到位了,这时 POR 逻辑的阈值比较器动作就会异常。JTAG TAP 依然可以工作,因为 VCCAUX 已经稳定,但配置状态机的复位释放可能提前或滞后,导致后续所有动作错拍。
4.2 示波器要抓哪几个点,以及判断波形是否合格的依据
遇到 C 类问题(IDCODE 正常,Program 报成功但 DONE 不亮),我最推荐的手段不是打开一堆软件日志,而是直接用示波器抓硬件时序。四通道示波器足够用,建议这样分配:
| 通道 | 建议节点 | 观察目标 |
|---|---|---|
| CH1 | VCCINT(通常是 1.0 V 或 0.85 V) | 是否最先爬升,是否有跌落 |
| CH2 | VCCAUX(1.8 V) | 是否在 VCCINT 之后稳定 |
| CH3 | VCCO_0(通常 3.3 V) | 是否最晚到位,是否达到标称 |
| CH4 | PROGRAM_B | 是否在电源稳定后被释放为高电平 |
示波器触发方式建议选正常触发,触发电平设为 VCCO 的 50%,时基放在 200 ms/div 到 1 s/div,首先观察整个上电过程。重点看两个东西:一是各电压轨的爬升顺序和时间差,二是 PROGRAM_B 有没有出现异常的低电平脉冲。
如果 PROGRAM_B 是直接由板上的复位芯片控制的,要看它是不是在上电后保持了足够长的高电平。FPGA 规格书上一般会给出 PROGRAM_B 脉冲宽度要求,比如某些 7 系列器件要求最小的低电平脉冲宽度在几百纳秒到微秒级。但更常见的故障不是程序脉冲太窄,而是复位芯片在系统运行过程中周期性把 PROGRAM_B 拉低,导致 FPGA 反复重启,外部看到的现象就是“DONE 没稳定”。
另一个要抓的信号是 DONE。配置成功时 DONE 应该从低电平跳变到高电平。如果 DONE 在 PROGRAM_B 释放后很快就变成高电平,然后又掉回低电平,说明内部配置流程启动后又中断了,多半跟外部 Flash 或者启动模式有关。如果 DONE 从头到尾都没有跳变,优先怀疑配置数据源、模式引脚或者电源时序。
4.3 常见的破坏性设计,以及对应的修复方向
这里列几个我实际见过的问题,都属于“原理图看着没问题,一上电就翻车”的类型:
第一种,DONE 引脚被外部逻辑强制拉低。DONE 是开漏输出,正常需要接到 VCCO_0 并接一个上拉电阻。如果你的板子上 DONE 恰好接到了一个外部芯片的输出引脚,而那颗芯片恰好输出低电平,那 FPGA 就算配置成功,DONE 电压也起不来。排查方法是把 DONE 上的外部连接断开,或者用示波器确认 DONE 引脚到外部芯片之间有没有电平冲突。
第二种,PROGRAM_B 被复位芯片拉得太久。很多设计喜欢用一颗复位芯片统一控制整个板卡的复位,FPGA 的 PROGRAM_B 也接在上面。但复位芯片的复位超时时间如果设置得特别长,比如 500 ms,而上电时序要求 PROGRAM_B 在电源稳定后必须释放,否则可能错过配置窗口。建议 FPGA 的 PROGRAM_B 不要跟整个板级的复位逻辑绑在一起,至少要保持独立可控。
第三种,电源监控芯片的上电顺序和 FPGA 要求不一致。这个问题在 Zynq 板卡上尤其常见,因为 Zynq 有严格的电源时序要求。解决方向有两种:一是调整电源管理芯片的配置,让它按 VCCINT → VCCAUX → VCCO 的顺序输出;二是如果电源芯片本身不支持顺序控制,只能在硬件上增加延时电路或者使用电源时序控制器。软件再怎么调,硬件时序不对都会在某个角落埋雷。
5. 从 Hardware Manager 报错到示波器波形:一套可复现的完整排查流程
5.1 第一步:先给故障归类,不要直接重刷 bit 流
很多人拿到板子的第一反应就是重新烧一遍 bit 流,或者换一台电脑重装驱动,这种操作不是不行,而是效率太低。更合理的做法是先按第一节的三类故障做初步归类。
- 如果 Open Target 都成功不了,优先查 USB 枚举、驱动、物理连接和 VREF。
- 如果 Open Target 成功但设备列表不对,优先查 VREF、TCK 电气质量和扫描链配置。
- 如果设备正常、Program 报成功但功能不工作,优先查启动模式、DONE 电平和上电时序。
在 Vivado Hardware Manager 里,最简单的分类方法是看“目标打开之后,Device 列表里的 IDCODE 是否可读”。这个操作能区分 A/B 类和 C 类。归类正确,后面排查大概率不会跑偏。
5.2 第二步:用几条 Tcl 命令代替图形界面,效率会高很多
Vivado Hardware Manager 的图形界面固然清晰,但很多操作用 Tcl 命令更快,而且更容易复现和记录。我常用的一组诊断命令大概是这样:
# 打开硬件管理器对象 open_hw_manager # 连接本地硬件服务器 connect_hw_server # 打开 JTAG 目标 open_hw_target # 查看当前扫描到的所有目标 get_hw_targets # 查看目标上扫描到的所有设备 get_hw_devices # 设置当前设备(用扫描到的实际设备号替换 xc7z020_1) # current_hw_device [get_hw_devices xc7z020_1] # 查询当前目标的属性,观察是否有异常值 get_property PROTOCOL [current_hw_target]如果连接失败,先用get_hw_targets看看硬件服务器是否枚举到了目标。如果枚举到了目标,但get_hw_devices返回空或者全零,重点查 VREF 和 TCK 回路。如果设备列表里出现了期望 IDCODE,但后续编程失败,再结合示波器查启动模式与 DONE。
某些版本的 Vivado 支持通过 Tcl 设置 JTAG 频率参数,如果怀疑 TCK 频率过高导致采样错误,可以尝试降低频率后重新扫描。这个参数在你连接目标之前设置比较合适,界面位置在 Open Target 对话框的高级设置里。很多二手板卡、杜邦线连接的目标,把频率从默认值降一半甚至降一个数量级,问题立刻消失。
5.3 第三步:一张根因判定表,逐列排除
我到现场调板,习惯把下面的表打印出来放在示波器旁边。它基本能覆盖 90% 的 JTAG 连接和启动失败问题。
| 现象 | 优先怀疑 | 验证动作 | 修复方向 |
|---|---|---|---|
| Open Target 失败,无目标 | USB 驱动 / 下载器 / VREF 全无 | 换 USB 口、重装驱动、量 VREF | 修复 VREF、换下载器 |
| 目标找到,IDCODE 全零 | VREF 异常 / TCK 不稳 / 链上其它器件断电 | 量 VREF、降低 TCK 频率 | 重接 VREF、降频 |
| IDCODE 正确,Program 超时 | 启动模式引脚冲突 / 配置状态机未就绪 | 确认 BOOT_MODE、看 PROGRAM_B | 切 JTAG 模式、复位时序 |
| Program 报成功,DONE 不亮 | DONE 电平冲突 / Flash 无镜像 / 电源时序 | 示波器抓 DONE、检查电平 | 修 DONE 外部电路、固化 Flash |
| Program 成功,功能随机异常 | 电源纹波 / 时钟不稳 / 部分引脚冲突 | 看电源纹波、核对引脚分配 | 优化电源、检查硬件 |
这张表的作用不是让你机械套用,而是帮你建立一套“现象 → 假设 → 验证”的思维习惯。实际调试时,往往是两三个因素叠加到一起的,比如 VREF 本身就临界,同时启动模式又不对,两个问题一起处理才能看到效果。所以不要在一个现象上钻牛角尖,按表扫一遍,再交叉验证。
5.4 两个真实案例复盘,看懂整套流程怎么用
案例一是一块 Zynq-7010 板子,现象是 Hardware Manager 能认出 xc7z010,Program Device 也报告成功,但板级功能完全没反应,PS 端没有串口输出。我按上面的流程,先确认不是 A/B 类问题,然后把目光放到 C 类。示波器抓 DONE,发现 Program 瞬间 DONE 能拉高,但断电重启后 DONE 就再也不动了。查 BOOT_MODE 拨码,发现默认在 QSPI 模式,而 QSPI Flash 里没有镜像。把 BOOT_MODE 切到 JTAG 模式再断电重启,板子才恢复正常。这个案例说明一个简单的拨码开关状态,就能让所有硬件看起来“坏了”。
案例二是 Artix-7 板子,现象更诡异:JTAG 时好时坏,偶尔识别出 IDCODE,编程时随机失败,有时直接报 Target connection lost。一开始怀疑下载器问题,换了一根线,还是不行。后来量 VREF,发现它被板上一个电阻网络分压到了大概 1.2 V,而 Bank 0 实际是 3.3 V。适配器按 1.2 V 的门限去驱动信号,FPGA 收不到稳定的高电平。用飞线把 VREF 直接接到 3.3 V 后,JTAG 链路立刻稳定。这个案例说明,VREF 不匹配的表现不一定是一开始就完全不通,更常见的是“间歇性神经病”。
6. 调板一年后,我想留给大家的几个习惯
6.1 原理图阶段就给自己留好后路
很多板级问题都是在原理图阶段埋下的,等到贴片回来才发现就很被动。关于 JTAG 和启动,我强烈建议在原理图里做这几件事:JTAG 连接器的 VREF 引脚不仅要接对,还要单独引出一个测试点;BOOT_MODE/M 引脚不要只靠电阻焊死,至少要留一组跳线或者 0 欧电阻的选择位置;DONE 和 PROGRAM_B 都引出测试点,方便示波器夹探头;电源时序如果用的 PMIC 芯片,确认配置引脚留了可编程控制。
这几个改动在原理图里加起来不超过十个网络,但能让你在调试阶段省下大量时间。我见过太多板子,功能设计没问题,就是因为没留 JTAG 调试测试点,最后调板时只能拿镊子戳芯片引脚,既危险又低效。
6.2 现场调试的五步检查顺序
到了实验室,拿到一块“启动失败”的板子,我建议按下面的顺序过一遍,不要跳跃。
第一步,接好下载器后先量一下 VREF 对地电压,确认它和目标 Bank 0 电压一致。这一步 30 秒就能完成,能排除 20% 以上的莫名其妙连接问题。
第二步,确认板子当前供电状态。用万用表量 VCCINT、VCCAUX、VCCO 是否都到位,如果哪一路缺失,整块板子的行为都会异常,JTAG 也不能幸免。
第三步,查启动模式引脚的电平组合。翻原理图,量拨码开关或电阻网络的输出,确认当前模式是 JTAG 还是其它。如果是量产板,直接看默认焊接方式。
第四步,连上 Hardware Manager,读取 IDCODE。能正确读到目标型号,基本排除 VREF 全断和 TDI/TDO 链路断裂;读不到或者全零,回头查第三步之前的物理层。
第五步,结合示波器抓 PROGRAM_B 和 DONE 波形。单独用软件看信息已经不够了,硬件时序才是启动成败的最终裁判。
6.3 关于“三个隐藏条件”的总结性经验
这三个隐藏条件我在实际项目中遇到的比例大约是:启动模式问题占四成,VREF 问题占三成,电源时序问题占两成,剩下的一成才是乱七八糟的下载器、USB 或者芯片本身损坏。所以如果你时间有限,优先排查启动模式和 VREF,这两项都不需要昂贵设备,万用表和飞线就能搞定。
最后再分享一个小技巧:当你实在定位不到问题,怀疑是上电时序时,可以试试用实验室稳压电源手动给板子供电,做一个非常缓慢的爬坡,同时抓 FPGA 的 DONE 和 PROGRAM_B。如果慢上电时板子行为变好,说明问题大概率就出在电源时序和 POR 上。这个办法我用过很多次,虽然看起来原始,但在没有高级电源分析仪的场合非常管用。