3、JTAG链式拓扑:多器件级联原理、IR/DR扫描、Bypass模式

好,咱们今天聊点硬核的。JTAG 链式拓扑,说白了就是怎么把好几个芯片串在一根数据线上,让它们乖乖听话。

我记得刚入行那会儿,第一次拿到一块四片 FPGA 级联的板子,看着原理图上 TDI 到 TDO 绕来绕去,心里直打鼓。后来调通了才发现,其实核心就三件事:链怎么连、指令怎么扫、数据怎么传。

3.1 链式拓扑:TDI→TDO 的串联游戏

JTAG 的物理层其实很简单。每个器件都有四个基本引脚:TCK、TMS、TDI、TDO。多器件级联时,前一个的 TDO 接到后一个的 TDI,最后一个的 TDO 回到调试器。就像串糖葫芦,一个接一个。

核心规则:链上所有器件共享 TCK 和 TMS,但 TDI/TDO 形成一条闭合的移位寄存器链。

你想想看,调试器往 TDI 送一串数据,这串数据会依次穿过每个器件的内部移位寄存器,最后从最后一个 TDO 出来。每个器件在链上占据一段固定的位置,这个位置由它的 IR(指令寄存器)长度和 DR(数据寄存器)长度决定。

我在项目中遇到过一块板子,链上有 5 个器件,但 TDO 死活没信号。查了半天,发现中间一个芯片的 TDO 虚焊了。嗯,这种问题用示波器量一下 TDO 波形就能定位,但前提是你得知道链上每个节点的预期行为。

3.2 IR/DR 扫描:TAP 控制器的核心操作

每个 JTAG 器件内部都有一个 TAP(测试访问端口)控制器。它是一个 16 状态的有限状态机,由 TCK 和 TMS 驱动。TAP 控制器的核心任务就是管理两种扫描操作:指令扫描(IR Scan)和数据扫描(DR Scan)。

扫描类型 目标寄存器 典型长度 用途
IR Scan 指令寄存器(IR) 2~8 位(常见 4 位) 选择要执行的测试指令
DR Scan 数据寄存器(DR) 1~数百位 传输指令对应的数据

流程是这样的:

  1. 进入 Shift-IR 状态:通过 TMS 序列将 TAP 控制器驱动到 Shift-IR。
  2. 移位指令:在每个 TCK 上升沿,TDI 上的指令位被移入 IR,同时 IR 的原内容从 TDO 移出。
  3. 更新指令:进入 Update-IR 状态,指令生效。
  4. 进入 Shift-DR 状态:根据已选指令,对应的数据寄存器被连接到 TDI 和 TDO 之间。
  5. 移位数据:移入新数据,移出旧数据。
  6. 更新数据:进入 Update-DR,数据生效。

我的习惯:调试时先用 IR 扫描读回 IDCODE,确认链上每个器件都能正常响应。IDCODE 是 IEEE 1149.1 强制实现的指令,所有合规 JTAG 器件都有。如果 IDCODE 读出来全是 0 或全是 1,那基本可以断定链断了或 TAP 没复位。

3.3 Bypass 模式:让不关心的器件透明化

链上有 5 个器件,但你只想操作第 3 个。怎么办?把其他 4 个设成 Bypass 模式。

Bypass 是 JTAG 的强制指令(指令码通常是全 1)。当器件进入 Bypass 模式时,它的 TDI 和 TDO 之间只连接一个 1 位的旁路寄存器。数据穿过它只需要 1 个 TCK 周期。

举个例子:

  • 链上有 3 个器件:A(IR=4 位)、B(IR=4 位)、C(IR=4 位)。
  • 你想给 B 发送一条指令,同时让 A 和 C 处于 Bypass。
  • 你需要往 TDI 送一串 12 位的指令序列(4+4+4),其中 A 和 C 的 4 位是 Bypass 指令码(全 1),B 的 4 位是你想要的指令。

我曾经调试一块 8 片 NOR Flash 级联的板子,每次擦除都要等很久。后来发现是因为链上所有 Flash 都处于正常模式,每次操作都要经过它们几百位的寄存器。把不操作的 Flash 设成 Bypass 后,速度提升了将近 10 倍。

注意:Bypass 模式下,器件仍然会消耗 TCK 周期。链上器件越多,移位延迟越大。对于高速烧录场景,建议尽量减少链上器件数量,或者使用硬件加速器。

3.4 链式拓扑的 SVG 结构图

下面这张图展示了三器件级联的 JTAG 链式拓扑,以及 IR/DR 扫描的数据流向。

JTAG 链式拓扑与 IR/DR 扫描 调试器 器件 A IR=4位, DR=16位 器件 B IR=4位, DR=32位 器件 C IR=4位, DR=8位 TDI TDO→TDI TDO→TDI TDO TCK / TMS(共享) IR/DR 扫描流程 1. 调试器通过 TMS 序列驱动 TAP 控制器进入 Shift-IR 状态 2. 在 TCK 驱动下,指令码从 TDI 依次移入各器件 IR,原 IR 内容从 TDO 移出 3. 进入 Shift-DR 状态,根据指令选择对应的数据寄存器进行数据移位 Bypass 模式 当器件处于 Bypass 模式时,TDI 与 TDO 之间仅连接 1 位旁路寄存器 数据穿过器件只需 1 个 TCK 周期,适合快速跳过不关心的器件

3.5 链式拓扑的避坑指南

调试 JTAG 链,我踩过的坑不少。挑几个典型的说说:

  • 链上器件顺序搞反:TDI→TDO 的方向不能错。我曾经把一块 Flash 的 TDI 和 TDO 接反了,结果链上所有器件都认不出来。用万用表量一下物理连接,比什么都管用。
  • IR 长度不一致:链上不同器件的 IR 长度可能不同。比如一个 4 位,一个 6 位。移位时必须按实际长度拼接指令序列,否则指令会错位。我习惯在代码里用一个数组记录每个器件的 IR 长度,动态计算总长度。
  • TCK 频率太高:链上器件越多,TCK 的负载电容越大。频率太高会导致信号失真。我一般从 1MHz 开始调试,稳定后再往上提。有些老器件只能跑到 10MHz,别硬来。
  • 复位状态不确定:上电后 TAP 控制器可能处于未知状态。我习惯在初始化时先发至少 5 个 TCK 周期且 TMS 为高,强制进入 Test-Logic-Reset 状态。这是 IEEE 1149.1 标准推荐的。

我的调试三板斧:

  1. 读 IDCODE:验证链上器件数量和顺序。
  2. 读 BYPASS:验证每个器件的 Bypass 响应(应该是一个 1 位寄存器)。
  3. 写 SAMPLE/PRELOAD:验证数据寄存器能否正常读写。

这三步走完,基本能确认 JTAG 链是健康的。

3.6 小结

JTAG 链式拓扑,说白了就是 TDI→TDO 的串联。IR 扫描选指令,DR 扫描传数据。Bypass 模式让不关心的器件透明化,节省移位时间。

嗯,这一章的内容就到这里。记住,调试 JTAG 链,耐心比技术更重要。有时候一个虚焊、一个频率不匹配,就能折腾你半天。但只要你理解了 TAP 控制器的状态机,理解了 IR/DR 的扫描流程,大部分问题都能迎刃而解。