FPGA JTAG 链概念:TAP 状态机、多器件菊花链与调试入口
入门阶段,JTAG 在你眼里可能就是板子上那根 10 pin 排线:插上下载器,在 Vivado Hardware Manager 里点 Program Device,比特流就进去了;烧完不拔出,ILA 抓的波形还能从同一根线读回来。等到一块板上挂了两三颗 FPGA、或者 FPGA 和 CPLD、CPU 的调试口共用一个插座时,工具突然要求你填「链上器件顺序、各自 IR 长度」,接反了还整链失联——这时候就必须补一堂 FPGA JTAG 链概念的机制课。
本篇是 JTAG 主题的入门概念文,只讲机制与多器件链的基本直觉。下载与固化的操作步骤见 FPGA 入门 32:比特流下载与固化,JTAG 与 SPI/SelectMAP 等配置方式的横向对比见 FPGA 配置方式有哪几种,ILA 在线抓波形见 FPGA 入门 31:ILA 第一次用;BSDL 产线测试、JTAG-to-AXI、SVF 等高级用法在专家层 JTAG 链高级用法 展开,本篇不重复。
本文要回答的问题
- JTAG 只有 TCK/TMS/TDI/TDO 四根信号线,下载器凭什么能指挥链上的某一颗器件,而不影响其他器件?
- TAP 状态机的十六个状态在干什么,为什么工具连不上时老手总说「先让 TMS 保持五个 TCK 高电平复位」?
- 多器件菊花链物理上怎么串?IR 长度、BYPASS 旁路、IDCODE 在寻址中各自扮演什么角色?
- 边界扫描(boundary scan)不接示波器就能测管脚连通性、观察 pin 电平,它是怎么做到的?
- JTAG 和主串 SPI、SelectMAP 这些配置口是什么关系?链上器件顺序接反了怎么排查?
一、四线与 TAP:一条移位寄存器串成的总线
JTAG 这个名字最早来自 1985 年成立的 Joint Test Action Group,它制定的测试访问接口后来被收编为 IEEE 1149.1 标准,正式名称叫测试访问端口(Test Access Port,TAP)。记住标准号即可,对 FPGA 工程师真正有用的是它的物理形态:四根信号线 + 链上每个器件内部一个小状态机。
| 信号线 | 方向(相对下载器) | 作用 |
|---|---|---|
| TCK | 输出 | 测试时钟,链上所有动作都由它拍动,时钟由下载器提供 |
| TMS | 输出 | Test Mode Select,在 TCK 上升沿被采样,决定状态机怎么走,全链共用 |
| TDI | 输出 | Test Data In,串行数据入链,每个 TCK 移进 1 bit |
| TDO | 输入 | Test Data Out,串行数据出链,每个 TCK 移出 1 bit |
另有一个常见的低电平有效异步复位脚 TRST(Test Reset),属于可选引脚,很多板卡根本不接——因为仅靠 TMS 序列就能复位状态机,这一点第二节会讲到。下载器插座上还常有 VTREF(电平参考)脚,用来让下载器适配板卡的 I/O 电平,它不参与协议。
先给一张全篇地图。下载器要对链上某一颗器件做一次动作,数据在 FPGA JTAG 链概念里经历的收窄过程就是下面四层:
读这张漏斗抓住一个反直觉点:整条链上没有一根片选信号线。SPI 总线靠 CS 脚选中从机,JTAG 没有,它的「选中」是移位移出来的——同一条 TDI 水流过所有器件,谁的指令寄存器(IR)里收到的不是全 1,谁就被选中,其余器件把自己缩成 1 位的旁路寄存器,像水管里的直通接头。这个机制是理解多器件链的总钥匙,第三节会拆开讲。
二、菊花链拓扑:TCK/TMS 并联,TDI/TDO 首尾相串
多器件 JTAG 链的物理接线只有两条规则,画成图一目了然:
读这张图区分两类线:TCK 和 TMS 是广播网,下载器并联接到每一颗器件,所有 TAP 在同一个 TCK 边沿采样同一个 TMS,因此链上所有器件的状态机任何时刻都处在同一个状态——它们是齐步走的;TDI 和 TDO 是串行链,下载器的 TDI 进器件 A,A 的 TDO 接 B 的 TDI,B 的 TDO 再接 C,最后一颗的 TDO 回到下载器。于是三颗器件内部当前被选中的移位寄存器(IR 或某个 DR)首尾拼接,在外部看来就是一个超长移位寄存器。
由此直接推出两个工程结论。第一,移位有进出延迟:向链中送入 N bit,最早送入的 bit 要经过 N 个 TCK 才从 TDO 出现,链越长、各片数据寄存器越宽,一次事务的时钟数越多,这就是 JTAG 操作给人「慢」感觉的根本原因。第二,也是最常见的板级事故:链上任一器件没供电、没释放复位或焊接不良,它的 TDO 输出级不工作,串行链就在那里断开,下载器看不到链上任何后级器件。TCK/TMS 广播线出问题往往是全链一起异常,而 TDO 串联通道出问题表现为「只能看到链上前几颗」,这个症状差异在第七节排查时直接可用。
链上挂的不一定都是 FPGA。任何带 IEEE 1149.1 TAP 的芯片都可以挂上来:CPLD、带 JTAG 调试接口的 CPU、FPGA 配置用的串行 Flash(通过 FPGA 间接访问)甚至一些接口芯片。多器件共链时彼此的调试事务互不干扰,前提是工具知道完整的链描述(器件顺序与各自 IR 长度)。
三、TAP 状态机:TMS 在十六态里导航
每个 TAP 内部是同一个状态机。完整状态机有 16 个状态,初学时不必全背,抓住主干上的六个路标和两条对称支路即可:

读这张图先看颜色:灰色是复位态,绿色是空闲稳态,红色两个 Shift 态是真正发生数据移动的地方,橙色 Update 态把移进来的比特锁存生效,蓝色是路上的岔口。再看走路规则:每个 TCK 上升沿,状态机按 TMS 的 0/1 二选一。TMS=0 大多顺着支路「向里走」(Capture → Shift → 移位干活),TMS=1 大多「向外退」。DR 支路和 IR 支路完全对称,先有 Select-DR/Select-IR 这个岔路口决定你接下来操作的是数据寄存器还是指令寄存器。
三个关键机制细节:
- Test-Logic-Reset 是兜底入口。从任意状态出发,只要让 TMS 在连续 5 个 TCK 保持高电平,状态机必回到 TLR——这就是「链状态不明时先复位」的依据,工具每次打开链都会先发这串序列。TRST 脚只是把同一件事用电平异步做掉。
- Shift 态下每个 TCK 移 1 bit。进入 Shift-DR 后,TDI/TDO 通路逐拍移动,移出目标位数后把 TMS 拉高进入 Exit1,再到 Update-DR,移位期间在移位寄存器里的比特此刻才被锁存到真正的工作寄存器并生效。Shift-IR 同理,只不过移的是指令码。
- Capture 态装入串行移出的起点。进入 Capture-DR 时,当前数据寄存器的并行值被装入移位寄存器,随后移位时从 TDO 逐位读出来——读 IDCODE、读 ILA 采样数据都是这个套路:先 Capture 装值,再 Shift 读出。
四、IR、DR、BYPASS 与 IDCODE:链上寻址四件套
状态机是轨道,寄存器是货车。每个 TAP 里有一个指令寄存器(Instruction Register,IR)和若干数据寄存器(Data Register,DR),最常打交道的是这几个:
| 寄存器 / 指令 | 位宽 | 干什么 |
|---|---|---|
| IR(指令寄存器) | 各器件固定,常见 4–12 bit | 决定当前哪个 DR 接入 TDI→TDO 通路 |
| IDCODE | 32 bit DR | 器件身份证:厂商、型号、版本,复位后的默认接入寄存器 |
| BYPASS | 1 bit DR | 直通寄存器,让非目标器件在链中只占 1 bit |
| SAMPLE/PRELOAD | 边界扫描 DR | 采样引脚当前电平,或预装扫描链 |
| EXTEST | 边界扫描 DR | 从链上强制驱动引脚电平,做板级互连测试 |
| BOUNDARY | 数百 bit DR | 环绕所有引脚的边界扫描单元链,长度由 BSDL 描述 |
一次「只跟器件 B 说话」的移位序列这样构造:先进 Shift-IR,向整条链移入指令码——给 B 送目标指令(例如 IDCODE 或厂商配置指令),给 A 和 C 送全 1。全 1 是 BYPASS 指令的强制编码,这是 IEEE 1149.1 硬性规定的,因此工具不需要预先知道一颗陌生器件的指令集,也能保证让它旁路。之后进 Shift-DR 移动数据时,整条链的等效长度为:
链总 DR 长度 = A 的 1 bit(BYPASS)+ B 的目标 DR 位宽 + C 的 1 bit(BYPASS)IR 扫描同理:菊花链的总 IR 长度恒等于各片 IR 长度之和,谁也绕不过。工具链配置文件里填写的「器件顺序 + IR 长度」就是用来拼这些移位序列的;顺序错或长度错,指令码会在错误的片边界对齐,所有器件收到的都是乱码。
移位节拍上发生的事用一张波形看得最清楚。下图示意 Shift-DR 期间 TDI 上送入的比特如何延迟一拍从 TDO 流出,以及最后一拍 TMS 拉高退出移位:
读这张波形抓三点:TDI 的每个比特在 TCK 边沿被采样进入移位寄存器;TDO 相对 TDI 延迟,移出的是链中原有的旧内容——所以 JTAG 移位永远是「边读边写」,移进一串新比特的同时必然收回一串等长的旧比特,读 IDCODE 正是利用这个回程通道;最后一个 TCK 处 TMS 拉高,状态机离开 Shift-DR 走向 Update,本批比特随即锁存生效。IDCODE 还有一个贴心设计:器件复位后默认接入 TDI→TDO 通路的就是它,因此工具不需要任何先验配置,直接做一次足够长的 DR 扫描,就能从回收到的比特流里按 32 bit 切出链上所有器件的身份证,自动发现链拓扑。
五、边界扫描:不焊探头就能看见引脚
JTAG 最初是为板级测试而生的,「边界扫描」这个名字描述的是它的物理实现:在芯片内部、每个 I/O 引脚与核心逻辑之间,串入一个边界扫描单元(boundary scan cell),这些单元首尾相连,形成一条环绕芯片边界的长移位寄存器,也就是 BOUNDARY 寄存器。
通过 SAMPLE 指令,这些单元在器件正常工作的同时悄悄采样引脚电平;移出来就能知道某个 pin 此刻是高是低——不用焊探头、不用占用示波器通道。通过 EXTEST 指令,方向反过来:核心逻辑与引脚被断开,引脚上的电平改由扫描单元强制驱动,驱动值从 TDI 移入。于是测试软件可以做这样的无夹具测试:让 FPGA 某个输出脚驱动高电平,再采样与它板级相连的另一颗芯片输入脚的边界单元,如果采到高,说明这段 PCB 走线连通;采到恒低,可能开路或对地短路;驱动一个脚而相邻脚的采样值跟着变,说明相邻引脚短路或虚焊搭连。管脚连通性测试与 pin 电平观察,就是边界扫描在产线上的两大基本用途。
PRELOAD 指令负责在进入 EXTEST 前把安全电平预装到扫描链,避免强制驱动瞬间让引脚处于未定义状态。器件的引脚与边界单元编号如何对应、BOUNDARY 寄存器有多长,由厂商提供的 BSDL 文件描述——BSDL 的产线测试玩法属于高级话题,见 JTAG 链高级用法,本篇只要求建立直觉:JTAG 能「看见」甚至「拨动」引脚,靠的是芯片里那圈可移位的采样单元,而不是什么模拟测量能力。
六、作为 FPGA 下载与调试入口:JTAG 与 SPI/SelectMAP 的关系
对 FPGA 用户,JTAG 最高频的用途不是测试,而是配置与在线调试。综合实现产生的比特流,在 Vivado Hardware Manager(Intel 侧是 Quartus Programmer)里经 JTAG 直接写入 FPGA 的配置存储器;插在设计里的 ILA 在线逻辑分析仪,其采样到的波形数据也沿同一条 TDO 读回主机,VIO 虚拟引脚的强制值则沿 TDI 送入。操作层面见 ILA 第一次用,调试方法论见 上板调试思路。
JTAG 配置口与主串 SPI、SelectMAP 等配置方式的关系,是初学最容易混的点:
| 对比维度 | JTAG 口 | 主串 SPI / SelectMAP / BPI |
|---|---|---|
| 时钟谁提供 | 下载器提供 TCK,与模式脚无关 | 主模式 FPGA 自己发 CCLK;从模式外部主控发时钟 |
| 用途定位 | 开发调试、在线抓波形、链扫描、边界测试 | 上电自加载、量产固化、脱机运行 |
| 数据去向 | 直写配置 SRAM,掉电即失 | 从板载 Flash 读入配置 SRAM;Flash 内容掉电保留 |
| 引脚 | 固定四线(+可选 TRST) | 模式脚 M[2:0]/MSEL 选择,占用专用配置脚组 |
| 优先级 | 始终可被下载器接管,可打断重配 | 上电时按模式脚设定的方式自动推进 |
二者不是竞争关系,而是共用芯片内部同一条配置电路、两个不同入口:JTAG 事务最终也是把比特流喂给配置引擎,和从 Flash 读入的数据走同一个加载过程;JTAG 的优先级更高,配置完成后仍可随时打断重新配置。掉电不丢的固化流程是「JTAG 先把镜像写进板载 QSPI Flash,下次上电 FPGA 再以主串 SPI 方式自己读回」,两个入口协作而非互斥,完整步骤见 比特流下载与固化,多镜像启动与在线升级见 FPGA 在线升级与 multiboot,五类配置方式的机制对比见 FPGA 配置方式有哪几种。
七、链上器件顺序接反与整链失联:排查路径
多器件链最典型的故障有两类:工具一个器件都看不到,或者看到的 IDCODE 序列与原理图对不上。前者多为物理层问题,后者基本是链描述错误。
| 症状 | 最可能原因 | 处理 |
|---|---|---|
| 完全看不到任何器件 | 链上某器件无电/未释放复位,TDO 输出级不工作 | 先逐颗查供电与复位,再查下载器 VTREF 与接线 |
| 只能看到前 N 颗 | 第 N 颗与其后继间 TDO 串联断开(虚焊、串联电阻) | 断点就在「最后能看到的器件」之后,量这一段 |
| IDCODE 全是 0 或全 1 | TDI/TDO 某一线固定电平、接反或短路 | 量线;TDI 与 TDO 接反是新板常见错误 |
| IDCODE 数值张冠李戴、位数错位 | 链描述里器件顺序或 IR 长度填错 | 以自动扫描出的实测链拓扑为准,与原理图逐颗对 |
| 低速正常高速失败 | TCK 过快,长排线/多器件下移位误码 | 降低 TCK 频率,缩短排线 |
| 单器件正常、共链异常 | 链上有器件 IR 长度声明不对,把全 1 误当有效指令 | 核对该器件手册的 IR length 与 BSDL |
排查的总体策略是「先物理后描述、先看见后选通」:跑一次工具的链自动扫描(IDCODE detection),让实测结果说话——扫描得到的器件数量与顺序是客观事实,原理图和链配置文件谁和它不一致就改谁。下载器层面的驱动与识别问题(电缆根本检测不到)是另一条独立线索,按 JTAG 下载器识别不到 的驱动、链路与电平顺序排查。
这一篇在知识体系里的位置
- 操作下游:FPGA 入门 32:比特流下载与固化 讲 JTAG 下载与写 Flash 的具体步骤;FPGA 入门 31:ILA 第一次用 讲同一根线上如何抓波形。
- 配置机制同簇:FPGA 配置方式有哪几种 给 JTAG/SPI/SelectMAP/BPI 的完整对比与上电配置时序;FPGA 在线升级与 multiboot 讲双区 Flash 与 fallback。
- 调试与排错:上板调试思路 给证据驱动的总体方法;JTAG 下载器识别不到 管电缆层面的失联。
- 进阶与专家层:ILA/VIO 高级调试 涉及 JTAG 带宽与资源规划;JTAG 链高级用法 展开 BSDL 产线测试、JTAG-to-AXI、SVF/XSVF 与自定义调试 IP;处理器 JTAG/调试口上原型 讲 CPU 的 TAP 与 FPGA 共链时的工程处理。
总结
FPGA JTAG 链概念的核心可以收成一句话:它是一条 TCK/TMS 广播、TDI/TDO 菊花串联的四线移位总线,链上没有片选,选中目标器件靠「给它有效指令、给其余器件送全 1 进 BYPASS」的移位序列实现。每个 TAP 是同一个十六态状态机,TMS 在 TCK 边沿导航,Shift-IR/Shift-DR 移指令和数据,Update 锁存生效,连续五个 TMS 高电平是通用复位手段;菊花链的总 IR 长度恒为各片之和,IDCODE 扫描能自动发现链拓扑,顺序或 IR 长度填错的直接症状就是 IDCODE 张冠李戴。边界扫描靠环绕引脚的可移位单元实现 pin 电平观察与 EXTEST 互连测试,而对 FPGA 用户,JTAG 更是下载配置与 ILA/ VIO 在线调试的统一入口——它与 SPI/SelectMAP 共用内部配置电路但永远可优先接管,掉电固化则是两个入口协作完成的。