第三章:扫描链设计(Scan Chain)

扫描链,说白了就是给芯片装上一套「体检系统」。

我刚开始接触DFT时,觉得这玩意儿挺玄乎的。后来做多了才明白,它其实就是把普通寄存器串起来,让测试时能像串糖葫芦一样,把数据一颗颗塞进去、再一颗颗掏出来检查。

3.1 扫描链原理

正常工作时,每个寄存器各司其职。但测试时,我们需要知道每个寄存器的状态对不对。怎么办?

答案很简单:给每个寄存器加个「开关」。

这个开关就是扫描模式。在扫描模式下,所有寄存器首尾相连,形成一条长长的移位寄存器链。测试数据从链头灌入,经过每个寄存器,最后从链尾输出。

我打个比方:就像一排士兵,平时各自站岗。集合时,他们手拉手连成一排,信息就能从第一个传到最后一个。

扫描链的核心操作就两个:

  • 移位(Shift):把测试数据串行灌入每个寄存器
  • 捕获(Capture):让芯片跑一个时钟周期,把组合逻辑的结果锁存到寄存器

然后,再把捕获到的结果移位出来,和预期值比对。这就是扫描测试的全部秘密。

关键点:扫描链的测试覆盖率,取决于你能控制多少内部节点。覆盖率越高,漏掉的缺陷就越少。

3.2 扫描触发器类型

扫描触发器,就是加了扫描功能的普通触发器。我见过好几种,常用的就下面这几类:

类型 结构特点 面积开销 适用场景
Muxed-D型 数据路径加一个2选1MUX 约10-15% 最常用,通用性强
LSSD型 双锁存器结构,无时钟竞争 约20-30% 高性能、高可靠性设计
时钟门控型 集成时钟门控逻辑 约15-20% 低功耗设计

Muxed-D型 是我用得最多的。它就是在普通D触发器前加一个MUX,选择信号是扫描使能(Scan Enable)。正常模式选D端,扫描模式选SI(Scan Input)端。

嗯,这里要注意:Muxed-D型有个坑——时钟竞争。如果扫描使能切换时机不对,数据可能出错。我早期一个项目就吃过这个亏,后来老老实实加了时序约束才搞定。

LSSD型 比较特殊。它用两个锁存器代替一个触发器,一个叫L1,一个叫L2。L1负责捕获,L2负责移位。好处是彻底避免了时钟竞争,坏处是面积大。

我记得有个客户做军工芯片,要求零缺陷,硬性规定必须用LSSD。那项目面积预算直接爆了,但测试覆盖率确实漂亮,接近100%。

时钟门控型 是低功耗设计的宠儿。它把时钟门控逻辑和扫描功能整合在一起,既省电又省面积。不过,这种触发器在ATPG时容易出问题,需要额外处理。

我的建议:除非有特殊要求,否则优先选Muxed-D型。它成熟、稳定、工具支持好。LSSD留给那些对可靠性有执念的项目。

3.3 扫描链插入流程

扫描链插入,听起来高大上,其实就三步走:

  1. 准备网表:把综合后的门级网表拿过来
  2. 替换触发器:把所有普通触发器换成扫描触发器
  3. 连接成链:把扫描触发器的SI和SO首尾相连

我用一个简单的例子来说明。假设我们有三个触发器FF1、FF2、FF3:

// 原始网表(普通触发器)
DFF FF1 (.D(d1), .CK(clk), .Q(q1));
DFF FF2 (.D(d2), .CK(clk), .Q(q2));
DFF FF3 (.D(d3), .CK(clk), .Q(q3));

// 扫描链插入后
SDFF FF1 (.D(d1), .SI(scan_in), .SE(scan_en), .CK(clk), .SO(n1));
SDFF FF2 (.D(d2), .SI(n1), .SE(scan_en), .CK(clk), .SO(n2));
SDFF FF3 (.D(d3), .SI(n2), .SE(scan_en), .CK(clk), .SO(scan_out));

你看,FF1的SO连到FF2的SI,FF2的SO连到FF3的SI。这样,scan_in的数据就能一路传到scan_out。

实际项目中,扫描链插入通常用EDA工具自动完成。我常用的流程是:

  • 用Synopsys的DFT Compiler做综合和扫描插入
  • 用Mentor的Tessent做ATPG和仿真验证
  • 最后用Cadence的Conformal做形式验证,确保功能没被改坏

不过,工具不是万能的。我曾经遇到一个项目,工具自动插了100条扫描链,结果有一条链的时序怎么也修不好。最后我手动调整了那条链的寄存器顺序,把关键路径上的寄存器放在链尾,问题才解决。

避坑指南:扫描链插入后,一定要做后仿真。我曾经跳过这一步,结果流片回来发现有一条链的SO和SI接反了。那叫一个惨,整批芯片报废。

扫描链的条数和长度怎么定?这取决于你的测试时间和芯片面积。一般来说:

  • 链越长,测试时间越短(因为并行度高了),但每条链的时序压力越大
  • 链越短,时序好修,但测试时间会变长

我个人习惯是:先把所有寄存器按功能模块分组,每组内部连成一条链。这样既保证了时序,又方便调试。如果某条链的寄存器太多(超过500个),我会再拆成两条。

最后,别忘了给扫描链加上测试时钟和测试复位。很多新手会漏掉这个,导致扫描测试时寄存器状态不可控。

总结一下:扫描链设计,核心就是「串起来、灌进去、读出来」。选对触发器类型,走对插入流程,再留个心眼做验证,基本就稳了。

扫描链核心知识体系 扫描链原理 扫描触发器类型 扫描链插入流程 移位操作 捕获操作 测试覆盖率 Muxed-D型 LSSD型 时钟门控型 准备网表 替换触发器 连接成链 串起来 → 灌进去 → 读出来

可可精品资料库