第四章 时序电路ATPG:时序电路测试挑战、时序ATPG基本概念、时序ATPG方法分类、扫描链设计基础
好,我们进入第四章。前面几章我们聊的都是组合逻辑的ATPG,说白了就是没有记忆的电路。但现实中的芯片,九成以上都是时序电路——有触发器、有状态机、有流水线。这一章,我们就来啃这块硬骨头。
4.1 时序电路测试的挑战
为什么时序电路测试这么难?我刚开始接触ATPG时,也觉得组合逻辑搞明白了,时序不就是加个时钟嘛。结果第一次跑时序ATPG,工具跑了三天三夜没出结果……
核心问题在于:状态太多。
你想想看,一个时序电路,它的输出不仅取决于当前输入,还取决于之前的状态。一个只有10个触发器的电路,理论上就有2^10 = 1024个状态。如果电路有1000个触发器?嗯,2^1000,这个数字比宇宙中的原子数还多。
具体来说,时序ATPG面临三大挑战:
- 状态初始化困难:上电后,触发器的初始值是不确定的。你不知道它是0还是1,这就没法做测试。
- 状态可达性问题:有些内部节点,你可能需要经过几十个时钟周期才能把电路驱动到某个特定状态。这在ATPG里叫「状态空间爆炸」。
- 观测困难:组合逻辑的故障,输入一加,输出一测就知道了。时序电路的故障可能藏在某个触发器的输出端,你要等好几个周期才能把它传到芯片引脚上。
核心观点:时序ATPG的本质,是把一个「时间上的序列问题」转化为「空间上的组合问题」。说白了,就是要把过去几个周期的输入和状态,都当成当前周期的变量来处理。
4.2 时序ATPG基本概念
在深入方法之前,我们先统一几个术语。这些概念我在项目中吃过不少亏,尤其是刚入行那会儿,跟同事讨论时各说各的,后来才发现是概念没对齐。
4.2.1 时间帧展开
这是时序ATPG最核心的思想。什么叫时间帧展开?
就是把一个时序电路,按照时钟周期「复制」成多个组合逻辑副本。每个副本代表一个时钟周期,副本之间的连线代表触发器的状态传递。
举个例子:
原始电路(时序):
输入 -> [组合逻辑] -> 触发器 -> 输出
展开后(组合):
周期1: 输入1 -> [组合逻辑1] -> 状态1
周期2: 状态1 -> [组合逻辑2] -> 状态2
周期3: 状态2 -> [组合逻辑3] -> 输出3
这样一来,原本需要多个周期才能观测到的故障,在展开后的组合电路里,就变成了一个「多输入、多输出」的组合逻辑问题。ATPG工具就可以用我们之前学过的D算法、FAN算法来处理了。
我的经验:时间帧展开的深度(也就是展开多少个周期)直接影响ATPG的效率和故障覆盖率。我个人习惯先设一个较小的深度(比如5个周期),跑一遍看看覆盖率。如果覆盖率不够,再逐步增加。不要一上来就设100个周期,工具会跑死的。
4.2.2 时序深度与回溯
时序深度,指的是从故障点到可观测输出之间,需要经过多少个时钟周期。这个数字越大,ATPG的难度就越高。
我曾经遇到一个项目,某个内部节点的时序深度达到了47个周期。这意味着ATPG工具需要同时管理47个时间帧的状态,计算量呈指数级增长。最后我们不得不修改设计,在中间加了几个测试点,才把时序深度降下来。
4.2.3 故障模型扩展
时序电路的故障模型,除了组合逻辑的固定故障、跳变故障之外,还多了两类:
- 时序故障:比如触发器的建立时间/保持时间违例、时钟偏移导致的错误采样。
- 状态机故障:比如状态跳转错误、非法状态进入等。
嗯,这里要注意:大多数商用ATPG工具主要处理的是固定故障和跳变故障。时序故障和状态机故障,通常需要专门的DFT(可测试性设计)结构来覆盖。
4.3 时序ATPG方法分类
时序ATPG的方法,说白了就两大类:基于时间帧展开的方法和基于符号仿真的方法。我分别说一下。
4.3.1 基于时间帧展开的方法
这是最主流的方法,也是大多数商用工具的实现方式。它的流程是这样的:
- 确定需要展开的时间帧数N。
- 将时序电路复制N份,形成N级组合逻辑链。
- 在展开后的组合电路上运行组合ATPG算法。
- 将生成的测试向量按时间帧拆解,形成时序测试序列。
优点很明显:算法成熟,工具支持好。缺点也很突出:N越大,计算量越大。对于深度超过50的电路,基本就跑不动了。
避坑指南:我曾经在一个项目里,用时间帧展开法处理一个深度为80的电路。工具跑了整整一周,最后告诉我「内存不足」。后来我改用扫描链设计,把时序电路变成了组合电路,问题才解决。所以,如果你的电路时序深度很大,别硬跑ATPG,先考虑加扫描链。
4.3.2 基于符号仿真的方法
这个方法不太常见,但在某些场景下很有效。它的思路是:不展开时间帧,而是用符号变量来表示电路的状态,然后通过布尔推理来求解。
说白了,就是把「这个触发器在周期t的值是多少」这个问题,变成一个布尔表达式。然后通过SAT求解器或BDD(二叉决策图)来求解。
优点是可以处理任意深度的时序电路。缺点是:对于大规模电路,布尔表达式会变得极其复杂,求解时间也不可控。
我个人觉得,符号仿真法更适合学术研究和特殊场景。工业界的主流还是时间帧展开+扫描链。
4.4 扫描链设计基础
终于到了这一章的重头戏——扫描链。说实话,如果没有扫描链,时序ATPG在工业界根本没法用。扫描链的出现,彻底改变了测试的格局。
4.4.1 扫描链的核心思想
扫描链的思想其实很简单:把时序电路变成组合电路。
怎么做呢?在每个触发器的输入端加一个多路选择器(MUX)。正常模式下,MUX选择数据输入;测试模式下,MUX选择扫描输入。所有触发器的扫描输入串联起来,就形成了一条「扫描链」。
这样一来,测试时我们可以:
- 扫描输入:通过扫描链,把任意状态值「灌」进所有触发器。
- 扫描输出:通过扫描链,把触发器的当前状态「读」出来。
你想想看,有了扫描链,时序电路在测试模式下就变成了组合电路。ATPG的难度一下子从「指数级」降到了「多项式级」。
4.4.2 扫描触发器的结构
标准的扫描触发器,就是在普通触发器前面加了一个2选1的MUX。控制信号叫SE(Scan Enable)。
普通触发器:
D -> [FF] -> Q
扫描触发器:
D ----\
> [MUX] -> [FF] -> Q
SI ---/
SE ---控制端
当SE=0时,选择D(正常模式)。当SE=1时,选择SI(扫描模式)。
多个扫描触发器串联起来:
SI -> [FF1的SI] -> Q1 -> [FF2的SI] -> Q2 -> ... -> SO
这就是一条扫描链。SI是扫描输入,SO是扫描输出。
我的建议:在设计扫描链时,尽量把物理位置相近的触发器串在一起,可以减少布线长度。另外,扫描链的长度(即触发器的数量)会影响测试时间。一条链上挂1000个触发器,扫描一次就需要1000个时钟周期。如果芯片有10万触发器,你可以分成10条链,每条1万个,并行扫描,效率高很多。
4.4.3 扫描测试的基本流程
有了扫描链,测试流程就变成了四个步骤:
- 扫描输入:把测试向量通过SI端口,逐位移入所有触发器。这一步需要N个时钟周期(N是扫描链长度)。
- 捕获:切换回正常模式(SE=0),施加一个或几个时钟脉冲,让组合逻辑计算新的状态值。
- 扫描输出:切换回扫描模式(SE=1),把触发器的结果逐位移出到SO端口。同时,可以移入下一个测试向量。
- 比较:把扫描输出的结果与预期值比较,判断是否有故障。
嗯,这里要注意:步骤2的捕获阶段,时钟脉冲的数量很关键。对于固定故障测试,通常只需要一个捕获脉冲。对于跳变故障测试,需要两个脉冲——第一个用来初始化,第二个用来捕获跳变结果。
4.4.4 扫描链设计的注意事项
我在项目中踩过不少扫描链的坑,这里列几个重点:
- 时钟域问题:不同时钟域的触发器不能串在同一条扫描链上。否则,跨时钟域的时序问题会导致扫描测试失败。
- 异步复位/置位:有异步复位或置位的触发器,在扫描模式下要确保复位信号不生效。否则你刚扫进去的数据,一个复位就全没了。
- 三态总线:扫描链上的触发器如果驱动三态总线,在扫描模式下要确保总线不被多个驱动源同时驱动,否则会有短路风险。
- 扫描链的测试:扫描链本身也需要测试。通常的做法是扫入一串0101...的pattern,然后扫出来检查是否一致。这叫「扫描链完整性测试」。
避坑指南:我曾经在一个项目中,扫描链设计完成后,仿真时发现扫描输出全是X(未知态)。查了两天才发现,有一个触发器的时钟门控信号在扫描模式下没有被强制打开。结果那个触发器一直没收到时钟,数据根本传不过去。所以,扫描链设计完成后,一定要做「扫描链完整性测试」的仿真,这是最基础的验证。
4.5 小结
这一章我们聊了时序ATPG的挑战、基本概念、方法分类,以及扫描链设计的基础。说白了,时序ATPG的核心就是「如何把时间问题变成空间问题」。而扫描链,就是实现这个转化的最实用手段。
下一章,我们会深入扫描链设计的细节,包括多扫描链、压缩技术、以及如何与ATPG工具配合。到时候我会分享一些实际项目中的设计经验和调试技巧。
好,这一章就到这里。有什么问题,欢迎随时交流。