IJTAG网络解析:SIB开关机制与TDR数据访问实战 做了快十年DFT我最怕的不是某个IP的BIST逻辑写不出来而是新人一上来就对着IEEE 1687标准文档发懵。Tessent这套工具链里IJTAG网络中的SIB和TDR是让整个芯片测试体系“活”起来的关键节点也是很多工程师从入门到放弃的卡点。这篇就按我自己的实战经验抛开标准文档里绕口的表述把SIB和TDR这两个东西一次讲透。面向刚接触Tessent、正在做SoC DFT集成或者想把芯片内各种测试仪器统一管起来的工程师读完你至少能明白为什么要用IJTAGSIB的开关机制到底是什么TDR怎么接进去以及在Tessent里从零搭一个可用的网络大概要经历什么。1. 为什么芯片级可测性设计需要IJTAG网络1.1 一颗SoC里的“测试仪器”越来越多早年做DFT一颗芯片上挂的测试逻辑很有限无非就是扫描链、BIST控制器、再加一两个调试寄存器。用传统JTAGIEEE 1149.1的IR指令去选TDR几十条指令空间完全够用。但到了现在动辄几十个IP的SoC里情况完全变样了CPU子系统有MBISTGPU有MEMBISTSerDes有眼图监视器PLL有校准寄存器温度传感器有触发阈值配置功耗管理单元要控制各种电压域还有一堆第三方IP自带测试逻辑。这些东西如果每样都从JTAG TAP直接引出来做独立寄存器顶层TDO的mux会膨胀到没法布线IR译码器也会变成蜘蛛网。更麻烦的是IP来自不同厂商每个IP自带一套测试访问方式有的用私有协议有的要配合功能时钟才能访问有的连文档都只给寄存器表。想统一管起来靠传统JTAG已经不太现实了。1.2 IJTAG解决的是“统一访问”问题IEEE 1687标准IJTAG就是在这样的背景下推出来的。它的核心思想很朴素把芯片内部各种测试、调试、校准逻辑统一抽象成挂在一条可配置扫描网络上的“仪器”外部通过一个标准的TAP口就能访问到任意一个仪器。为什么说“可配置”这就是IJTAG区别于传统JTAG的最大特点。传统JTAG里TDR是固定挂在TAP下面的IR指令选中哪个就访问哪个数量受限且拓扑固定。IJTAG引入了一类特殊的控制节点通过改变扫描链的连接关系让整个网络在运行过程中动态重构。你可以把这条网络想象成城市供水管网主干管永远在支管上装了阀门需要给哪个小区供水就把对应阀门打开不需要的就关死。这样一来不管芯片内部挂了多少仪器外部看到的“路径”永远可控、可裁剪。IJTAG网络通常挂在整个JTAG TAP的User Data Register下面通过一条IR指令就能进入。所以从芯片外部看引脚没有增加还是那几根TCK、TMS、TDI、TDO但内部的世界完全不一样了。1.3 “SIBTDR”在网络里的定位IJTAG标准里的核心组件主要有三类TAP、TDR、SIB。TAP是门口的接待员负责接收外部命令TDR是实际干活的寄存器跟仪器直接交互SIB就是调控网络通断的开关。把这张网说成“SIBTDR两个关键节点”一点也不夸张。没有SIB所有TDR只能平铺直挂跟传统JTAG没区别没有TDRSIB控制的只是一堆空气。一个管通路一个管数据两者配合才构成真正“灵活可配置”的IJTAG网络。2. SIB控制网络通断的开关节点2.1 SIB的基本结构与状态切换SIB的全称是Segment Insertion Bit直译过来是“段插入位”这个名字其实很精确。它的物理实现非常小巧核心就三样东西一个1位的移位寄存器、一个1位的更新寄存器、再加一组控制旁路和接入的MUX。别看它小行为却很有意思。SIB在扫描链上工作时跟普通寄存器最大的不同在于它有两种状态。当SIB处于“未选中inactive”状态时它在扫描链上只占1比特它下游的TDR或子树被整体旁路掉数据直接从它这1比特溜走。当SIB处于“选中active”状态时它下游的TDR或子树才会被接入扫描链。状态切换依赖TCK驱动的三个时刻Capture捕获、Shift移位、Update更新。在Shift阶段数据从TDI串行移入SIB的移位寄存器在Update阶段移位寄存器的值被锁存到更新寄存器这个值直接控制MUX决定网络是否接入下游在Capture阶段SIB可以把当前更新寄存器的值抓回移位寄存器方便外部回读当前开关状态。用一句话概括移位是“准备动作”Update是“执行动作”Capture是“回读当前状态”。2.2 用铁路道岔理解SIB的旁路与接入我每次给新同事讲SIB都喜欢拿铁路道岔打比方。假设有一条主铁路线TDI到TDO的主扫描路径SIB就是道岔TDR就是旁边支线上的一座仓库。火车默认走主线直接通过这就是SIB的旁路状态。当调度员把道岔扳过去火车就会开进支线进仓库装货卸货然后再回到主线。这就是SIB的接入状态。调度员扳道岔的动作就是一次Update操作。扳成什么样取决于你之前移进SIB的那个bit是0还是1。这个过程如果用扫描链长度来表示就非常直观了。假设SIB本身占1bit下游挂了一个长度为16bit的TDRSIB inactive时整条路径长度就是SIB自己那1bitTDR被完全跳过扫描链构成为[SIB(1bit)]SIB active时路径长度变成11617bit扫描链构成为[SIB(1bit)] - [TDR(16bit)]这个看似简单的“1bit变17bit”变化换来的却是整条扫描链的动态重构能力。测试系统先短链访问SIB把它置成active再长链访问TDR用完再短链把它置回inactive。整个过程完全可以通过外部TCK控制不需要改动硬件。2.3 SIB的默认状态到底要设成什么这里有个特别容易被忽略的细节SIB的复位默认状态。行业规范和经验都强烈建议上电复位后所有SIB必须处于inactive状态也就是默认把所有TDR都旁路掉。原因很好理解。IJTAG网络是挂在TAP下面的测试逻辑它不应该在上电瞬间去打扰功能逻辑。如果某个SIB默认是active的它下游的TDR就会不合格地接入网络万一这个TDR还连着某段测试时钟或内部调试总线轻则多耗功耗重则直接干扰功能。早期项目里我真遇到过因为SIB异步复位端没接好导致PLL校准寄存器在正常工作时被动过值的事故。实现上要么给SIB的更新寄存器加异步复位明确复位成0要么在TCK时钟域做上电同步复位让网络在仿真和实际芯片行为一致。无论是哪种都必须在Tessent的约束文件里明确定义别指望工具自己猜。3. TDR测试数据的出入口3.1 TDR的结构与读写机制SIB把路指好了接下来数据要从哪里进出这就是TDR的活。TDRTest Data Register测试数据寄存器是挂在IJTAG网络上、与用户测试逻辑直接打交道的寄存器。它的结构可以理解成两层一层是外部可见的、串行移位寄存器scan register负责跟TDI/TDO打交道另一层是并行数据寄存器parallel register跟你设计中的被测信号直接连接。访问TDR的过程跟传统JTAG的DR操作很像。外部往TDR写数据时先在Shift-DR阶段把数据一位一位串行移进移位寄存器然后在Update-DR阶段一次性并行输出到被测逻辑。外部读数据时先让被测逻辑在Capture-DR阶段把状态抓到移位寄存器然后在Shift-DR阶段串行移出来。这个“串行移入并行输出并行捕获串行读出”的机制让一个TDR可以在不增加引脚的情况下同时控制或观测几十上百个内部信号。你可以把它理解成一台小型“并串转换闸口”虽然是串行访问但一进一出之间完成的是并行数据的传递。3.2 一个具体的16位TDR实例拿一个常见的场景来说PLL配置寄存器。假设一颗SoC里有三个PLL每个PLL需要一个16位的控制寄存器来配置分频比、锁相环带宽等参数。用IJTAG的做法就是给每个PLL配置寄存器封装成一个16位的TDR名字比如叫tdr_pll0_cfg、tdr_pll1_cfg、tdr_pll2_cfg然后分别挂在SIB网络的三个分支下。外部访问tdr_pll0_cfg的完整流程是这样的先把通向该TDR的SIB链路全部置为active。如果SIB是两级的就要先更新上级SIB再更新下级SIB。通过Shift-DR向TDR串行移入16位配置数据。执行Update-DR16位数据并行打到PLL0的控制引脚上。如果需要确认配置是否生效可以等PLL稳定后执行Capture-DR把PLL状态寄存器抓回TDR。再通过Shift-DR把16位数据移出TDO供外部比对。整个流程里SIB负责“让路”TDR负责“递东西”配合得清清楚楚。3.3 同名概念避坑IJTAG的TDR不是“时域反射法”这里必须插一嘴同名概念真的太容易坑人。在信号完整性圈子TDR是指时域反射法Time-Domain Reflectometry一种通过发送阶跃脉冲并分析反射波来测量传输线阻抗、定位PCB走线断点的方法。Cadence Sigrity里做的TDR仿真就是干这个用的。这两种TDR拼写一模一样但一个是DFT数据结构一个是测量物理方法毫无关系。我见过不止一个新手在查“TDR仿真教程”结果打开资料发现里面全是阻抗不连续性跟IJTAG半毛钱关系没有。所以看到资料时先确认语境讲IJTAG、Tessent、IEEE 1687的那个TDR是测试数据寄存器讲信号完整性、Sigrity、阻抗匹配的那是时域反射法。同一关键词两个圈子的用法分开记忆就不会乱。4. Tessent里如何搭建SIB与TDR网络4.1 Tessent工具链在IJTAG设计中的角色理论讲完落地到工具。Tessent处理IJTAG的模块主要是Tessent Shell和IjiTagBuilder。Tessent Shell是DFT的通用环境用于读取网表、加载设计规格、跑规则检查IjiTagBuilder则是专门的IJTAG网络构建工具负责把用户自定义的TDR和想要的SIB层级“翻译”成实际的扫描连接关系。使用流程大致分三步先定义TDR把设计中已有的可测性接口寄存器比如BIST控制器配置寄存器、校准寄存器、调试状态寄存器声明成标准IJTAG TDR再定义SIB层级明确哪些TDR挂在哪个SIB下面SIB之间怎么嵌套最后让工具自动插入网络生成带IJTAG的新网表同时输出仿真模型和测试协议文件。4.2 添加TDR与SIB的典型流程不同版本Tessent的命令名称会有些差异但大体流程一致。下面是一个工程中常见的命令序列模板不保证跟你的版本逐字一致用的时候要以对应版本User Manual为准。# 1. 定义TDR把PLL配置寄存器封装成16位TDR add_tdr -name tdr_pll_cfg \ -bits 16 \ -access read_write # 2. 定义TDR把MBIST控制器寄存器封装成32位TDR add_tdr -name tdr_mbist_ctrl \ -bits 32 \ -access read_write # 3. 创建第一级SIBSoC顶层开关 add_sib -name sib_soc # 4. 创建第二级SIB挂在sib_soc下面控制CPU子系统的开关 add_sib -name sib_cpu_ss -parent sib_soc # 5. 把TDR挂到对应SIB的active分支 set_sib_active_branch -sib sib_cpu_ss -tdr tdr_mbist_ctrl set_sib_active_branch -sib sib_soc -tdr tdr_pll_cfg # 6. 插入IJTAG网络指定TDI/TDO连接 insert_ijtag -top sib_soc -tdi tdi -tdo tdo这几条命令背后工具会自动生成SIB的旁路MUX、更新寄存器控制逻辑、以及TDR的扫描接口封装。真正需要你操心的是TDR的bit数别定义错SIB的父子关系别搞成环以及TDI/TDO在顶层的连接别跟已有JTAG TAP冲突。4.3 层级化网络设计从平铺到树形很多初学者第一次搭IJTAG网络恨不得把所有TDR都挂在一个SIB下面。这样做不是不行但会导致一个问题当你想访问其中任何一个TDR时网络上所有TDR都得跟着移一遍位测试时间成倍增加。实践证明更合理的方案是树形结构。举个例子顶层SIBsib_soc分三条分支CPU子系统、SerDes子系统、传感器校准。CPU子系统下再挂一个SIBsib_cpu_ss下面再接MBIST控制器TDR、功耗管理TDR。SerDes子系统下挂一个SIBsib_serdes下面接眼图监视器TDR和PLL校准TDR。传感器校准不需要再细分直接挂在顶层SIB下面。这样分层之后要访问MBIST控制器时只需要经过sib_soc和sib_cpu_ss其他分支的TDR全部旁路。扫描链长度被裁剪到最短测试时间也能省下来。树形结构本质上是拿SIB的面积换访问的灵活度层级越多网络定位越精确但相应的SIB数量和逻辑面积也会增加这个平衡要结合项目实际需求来定。有个工程经验值得参考树形层级一般不建议超过五到六层。层级太深从TAP到目标TDR的路径上串的SIB太多虽然其他分支旁路了但链路本身并不短反而丧失优势。4.4 网络优化与Scan链长度计算在Tessent里插入网络后工具通常会提供优化选项。最常见的是合并冗余SIB、调整SIB在扫描链上的位置以及把访问频繁的TDR尽量往靠近TAP的方向挪。任何时候都要能估算一条访问路径的扫描链长度。举个例子假设访问路径经过sib_soc1bit、sib_cpu_ss1bit、tdr_mbist_ctrl32bit且两个SIB都置为active那么这条路径的长度就是L 1sib_soc 1sib_cpu_ss 32tdr_mbist_ctrl 34bit如果sib_cpu_ss处于inactive那么tdr_mbist_ctrl被旁路链路长度就变成L 1sib_soc 1sib_cpu_ss 2bit这个2bit和34bit的差别就是SIB分层带来的实际收益。所以每次设计网络时建议列一张表把每条访问路径的bit长度算出来对比一下访问频率再做结构调整。别拍脑袋拿数据说话。5. 实操中的常见问题与排查经验5.1 一张问题速查表这几年跑过的IJTAG项目遇到过的坑五花八门但归结起来有共性。先把高频问题整理成一张速查表问题现象可能原因排查手段SIB无法按预期选中TDRSIB的更新寄存器没接好或时钟域不对检查TCK到SIB update寄存器的路径开Tessent仿真跟踪TDR捕获数据全0或全1Capture使能没接对或被测逻辑本身没工作确认Capture-DR时序单独读一下TDR回读路径上电后测试系统误挂TDRSIB复位默认值错误更新寄存器初始为1查异步复位连接约束网络上电默认inactive第三方IP集成后访问冲突两个IP的SIB/TDR路径重叠或拓扑未统一整理全局网络拓扑表按树形重新映射时序收敛差SIB层级过深或TDR过长导致移位路径太长优化层级拆分长TDR调整约束外部TAP访问不到内部TDRIJTAG网络没有正确挂到TAP的User DR检查IR指令映射和顶层连接5.2 设计阶段就该注意的五个细节这些细节如果等流片回来再发现代价非常大。第一SIB层级别贪深。前面说过五到六层是经验上限再深就不好收时序。第二全网络尽量统一在TCK时钟域。TDR如果跨时钟域捕获和更新要做同步处理否则采样到亚稳态数据的时候排查起来相当痛苦。第三维护一张全局TDR清单。每个TDR叫什么、多少bit、挂在哪颗SIB下、对应哪个测试仪器表格维护好。第四尽早把IJTAG网络加进RTL验证环境别等综合后再补否则验证周期会被压缩。第五SIB操作序列要固化成可复用测试序列库这样量产和调试时可以直接调用不用每次重新写。5.3 性能与面积的权衡经验SIB虽然只有1bit但它带来的面积不是1个寄存器这么简单。每个SIB需要配套的MUX、更新存储、可能还有时钟门控和复位逻辑。一颗大规模SoC里如果挂了几百个SIB面积开销还是需要认真算一笔账的。我自己的实践经验是能用两层SIB解决的就不要做成五层能用共享SIB路径控制的就别各自为政。特别是Test Compression和EDT这类对时序敏感的逻辑SIB网络插入后一定要重新检查一遍时序约束更别说还要重新跑一遍ATPG验证。谈到这块顺带说一句Shared Bus DFT的对比。有的团队喜欢直接复用内部APB总线来做调试寄存器访问因为速度快、支持随机访问。但它的前提是CPU和总线时钟必须能正常工作而这恰恰是芯片bring-up初期最容易出问题的部分。相比之下IJTAG走的是TCK独立时钟域不依赖功能时钟上电就能从外部访问这一点在调试早期是无可替代的。实际项目里两者可以共存功能调试走Shared Bus测试和硬件初始化走IJTAG互不干扰。6. 进阶方向从IJTAG到下一代可测性设计6.1 IJTAG与Shared Bus DFT的对比选择在做SoC DFT架构时经常要回答一个问题内部寄存器访问到底该用IJTAG还是直接挂功能总线Shared Bus DFT的核心逻辑是复用把芯片里已有的APB或类似总线接口挂到JTAG后面。好处是硬件成本低数据访问带宽高可以随便读写任意地址。坏处是它依赖功能逻辑正常工作CPU没起来、总线没初始化之前这套访问机制完全不可用而且在量产测试时功能总线上的协议仿真要做足ATP向量生成和仿真时间会显著增加。IJTAG的路径则由纯TCK时钟控制独立性强是真正意义上跟功能逻辑解耦的测试网络。代价是串行访问带宽有限每次读写都要先经过SIB链路的移位。选型上没有绝对优劣更多是场景问题。要做系统级bring-up和硬件初始化优先IJTAG要做实时的后门调试和高带宽寄存器读写Shared Bus更省事。多数产品里两者共存因为它们的互斥性不强而是互补的。6.2 智能化趋势DFT计算智能体与自动SIB规划再往前看一步DFT工具本身也在变聪明。以前搭SIB网络基本靠手工规划哪几个仪器放一组挂在哪层深度多少都要人肉估算。工具能做的最多是规则检查。现在EDA工具正往策略自动生成方向走用所谓“DFT计算智能体”的思路把芯片里所有测试仪器的清单、访问频率、位宽、时序约束喂给算法让它自动生成SIB网络拓扑、自动分配TDR在扫描链上的位置、自动优化访问序列长度。这个过程未来会越来越像编译器输入设计意图输出最优网络结构。不过我得泼一盆冷水智能体再厉害也替代不了DFT工程师对网络结构的整体判断。工具可以把127个SIB排成最优树但它不知道你的量产测试程序里哪条访问路径会反复执行也不知道明年可能会加进来什么样的新仪器。所以我的态度是把智能体当成一个强力辅助该手搓的细节还是得自己把关。6.3 系统级应用芯片-封装-板级-系统的全链条调试最后说一个大方向IJTAG的价值从来不止芯片内部。因为网络是按统一标准建的芯片封装后的测试、板级的调试、甚至系统现场维护都可以通过同一个扫描协议访问到芯片内部最深层的TDR。举个实际例子。项目量产半年后客户现场报了一个偶发的PLL失锁问题常规手段很难复现。我们在实验室通过板级JTAG口进入芯片的IJTAG网络直接读取温度传感器TDR和PLL状态TDR抓到了失锁时刻的内部状态问题定位只花了一个下午。如果没有当初把温度传感器和PLL状态寄存器做成TDR挂到网络上这活儿根本没法干。所以说SIB和TDR这两个节点往小了说是DFT工具里的两个术语往大了说是给整个芯片生命周期铺了一条可访问、可控制、可调试的通道。我个人在实际操作中的体会是IJTAG网络别只看成是测试逻辑它更像芯片的“神经系统”SIB是神经节点TDR是末梢器官。前期多花一点心思把网络树规划好后面测试调试能省出几倍的时间。最后再分享一个小技巧在Tessent里把SIB的控制序列封装成宏无论是仿真回归还是ATE调试都能直接复用这个看似不起眼的习惯能让你在项目后期少加无数个夜班。