4、断言在扫描链测试中的应用
4.1 扫描链的基本原理
扫描链,说白了就是把芯片里的普通寄存器串成一个移位寄存器链。为什么要这么做?因为芯片正常工作的时候,内部状态你是看不到的。但测试时,我们需要把测试数据灌进去,再把结果读出来。
我刚开始接触DFT时,觉得扫描链就是个简单的移位寄存器。后来发现,事情没那么简单。每个寄存器都要换成带扫描功能的——也就是所谓的扫描触发器。它有两个数据输入:正常工作时的D端,和扫描模式下的SI端。通过一个控制信号SE(Scan Enable)来切换。
扫描链的工作流程其实就三步:
- 移位加载:把测试向量从扫描输入(Scan In)逐位移进去
- 捕获:切换回正常模式,让组合逻辑跑一个时钟周期
- 移位卸载:再把结果从扫描输出(Scan Out)逐位移出来
嗯,这里要注意:移位和捕获的时钟频率往往不一样。移位时可以用慢时钟,捕获时得用快时钟。为什么?因为捕获时组合逻辑的延迟可能很大,跑太快容易出问题。
核心要点:扫描链的本质,就是把时序电路测试问题,转化成了组合电路测试问题。你想想看,这招是不是很巧妙?
4.2 如何用断言检查扫描链完整性
扫描链本身也会出问题。我在项目中遇到过好几次,流片回来发现扫描链不通,结果整颗芯片都废了。所以,用断言来检查扫描链完整性,是DFT工程师的必修课。
常见的检查点有三个:
- 扫描输入到第一个触发器:确保数据能正确进入链
- 触发器之间的连接:确保移位路径没有断路或短路
- 最后一个触发器到扫描输出:确保数据能正确出来
下面是我个人习惯用的一个断言模板,专门检查扫描链移位功能:
// 检查扫描链移位完整性
// 原理:在移位模式下,每个时钟周期,数据应该从SI传到SO
property scan_shift_check;
@(posedge clk)
disable iff (!scan_mode)
// 假设链上有N个触发器
// 经过N个周期后,SI的数据应该出现在SO上
$past(scan_in, N) |=> scan_out;
endproperty
assert_scan_shift: assert property(scan_shift_check)
else $error("扫描链移位失败!");
我曾经踩过一个坑:这个断言在仿真时能过,但ATE测试时却报错。后来发现,是因为ATE的时钟抖动导致时序违例。所以,我建议在断言里加上时序裕量的检查:
// 带时序裕量的扫描链检查
property scan_timing_check;
@(posedge clk)
disable iff (!scan_mode)
// 检查建立时间裕量
$setup(scan_in, clk, 0.5);
// 检查保持时间裕量
$hold(scan_in, clk, 0.3);
endproperty
个人经验:扫描链的断言最好分两层。第一层检查功能正确性,第二层检查时序裕量。两层都过了,才能放心去流片。
4.3 扫描链测试中的常见故障模型
扫描链测试的故障模型,和普通逻辑测试不太一样。普通逻辑测试关心的是门级故障,而扫描链测试更关心的是链本身的问题。
我总结了一下,常见的故障模型大概有这几种:
| 故障类型 | 表现 | 断言检查方法 |
|---|---|---|
| 固定故障(Stuck-at) | 某个节点永远为0或1 | 交替输入0和1,检查输出是否变化 |
| 桥接故障(Bridging) | 两条信号线短路 | 检查相邻节点的电压/逻辑值是否异常 |
| 开路故障(Open) | 连接断开,信号悬空 | 检查高阻态或未知态(X态) |
| 时序故障(Timing) | 建立/保持时间违例 | 使用$setup/$hold断言 |
| 转换故障(Transition) | 信号变化太慢 | 检查上升/下降时间是否超标 |
你想想看,这些故障里最头疼的是哪个?我个人觉得是桥接故障。因为它往往不是固定的,温度和电压一变,可能就消失了。我曾经遇到过一个案例,芯片在常温下扫描链测试全过,但高温下就报错。查了两个月,最后发现是两条扫描链之间的桥接故障。
避坑指南:我曾经因为忽略了X态传播,导致扫描链断言误报。建议在断言中加入X态检查:
// 检查扫描链中是否有X态
property no_x_in_scan_chain;
@(posedge clk)
disable iff (!scan_mode)
not ($isunknown(scan_out));
endproperty
4.4 知识体系总览
说了这么多,我画了一张图来总结扫描链断言测试的核心逻辑。你看完应该就清楚了:
这张图把整个知识体系串起来了。从扫描链的基本原理出发,到断言检查的三个维度,再到最终的故障模型。你跟着这个思路走,基本不会跑偏。
最后说一句:扫描链断言不是写完了就完事的。我建议你在每个项目节点都跑一遍断言回归,特别是ECO之后。别问我为什么知道——我曾经因为一个ECO改了扫描链的时钟门控,结果断言没跑,流片回来才发现问题。嗯,那次的教训够我记一辈子。