第四章 DFT设计:扫描链插入与ATPG,为芯片植入可测试性基因

说实话,很多工程师觉得DFT是后端的事,跟我前端设计没关系。这个想法很危险。我见过不止一个项目,RTL仿真跑得飞起,结果流片回来一上ATE测试机,良率惨不忍睹。为什么?因为芯片内部那些节点,你根本观测不到。

DFT,说白了就是给芯片装上一套「体检系统」。没有它,芯片就是个黑盒子。你只能看输入输出,里面出了什么妖蛾子完全不知道。今天我们就聊聊怎么给芯片植入可测试性基因——扫描链插入和ATPG。

核心观点:DFT不是后端的事,也不是测试工程师的事。它是芯片设计的一部分,必须在RTL阶段就开始规划。越早考虑可测试性,后期流片风险越低。

4.1 为什么需要扫描链?

先想一个问题:芯片里有几百万个触发器,你怎么知道每个触发器都能正常工作?

功能仿真只能覆盖你写的那些测试用例。但芯片内部有很多状态,你根本没法通过外部引脚直接访问。比如一个藏在深层的状态机,它的某个状态翻转对不对?你测不到。

扫描链的思路很简单:把所有触发器串成一条链。正常工作时,各干各的。测试模式下,它们变成一条移位寄存器。你可以把测试向量从外部灌进去,再把结果扫出来看。

我在一个AI加速器项目里遇到过这种情况。芯片回来,功能基本正常,但某些边界条件下会死机。查了两个月,最后靠扫描链定位到是一个触发器的setup违例。如果没有扫描链,这个bug可能永远找不到。

对比项 功能模式 扫描测试模式
触发器连接 组合逻辑之间 串成移位寄存器链
时钟行为 正常功能时钟 扫描时钟,可暂停
数据来源 前级组合逻辑 扫描输入引脚
主要目的 执行功能 测试制造缺陷

4.2 扫描链插入的实战要点

扫描链插入不是简单的「把触发器串起来」。这里有很多坑,我一个个说。

4.2.1 扫描链的类型选择

常用的扫描链有两种:muxed-D和clocked。muxed-D最常用,每个触发器前面加一个2选1MUX。正常模式选功能数据,测试模式选扫描数据。

clocked扫描链用两个时钟域来控制,面积小一点,但时序约束更复杂。我个人习惯用muxed-D,因为时序好收敛,后端工具支持也成熟。

实战建议:扫描链的插入时机很重要。我建议在综合完成后、布局布线之前做。太早插入,RTL里全是扫描MUX,代码可读性差。太晚插入,后端工具优化空间小。

4.2.2 扫描链的划分与平衡

一个芯片可能有几十条扫描链。怎么划分?

  • 按时钟域划分:同一个时钟域的触发器放一条链。跨时钟域的触发器不要混在一起,否则时序分析会疯掉。
  • 链长度平衡:每条链的触发器数量尽量接近。我见过一个项目,一条链3000个触发器,另一条链50个。测试时间完全被长链拖死。
  • 物理位置考虑:物理上靠近的触发器放同一条链,减少绕线拥堵。

嗯,这里要注意。链长度不是越短越好。太短的链,测试引脚太多,封装成本上升。一般每条链500-2000个触发器比较合理。

4.2.3 扫描使能信号的处理

扫描使能(scan_enable)是测试模式的控制信号。它必须在整个芯片内同步切换。我踩过一个坑:scan_enable用组合逻辑产生,结果在切换瞬间,部分触发器已经进入测试模式,部分还在功能模式,数据全乱了。

避坑指南:scan_enable必须用寄存器同步输出,而且要用两级同步器跨时钟域。不要图省事直接用组合逻辑。我曾经因为这个原因,ATE测试时扫描链死活不工作,查了三天才发现是scan_enable的glitch问题。

4.3 ATPG:自动测试向量生成

扫描链插好了,接下来就是生成测试向量。ATPG工具会分析芯片的网表,自动生成能检测制造缺陷的测试向量。

ATPG的核心是故障模型。最常用的是 stuck-at 故障模型,假设某个节点 stuck-at 0 或 stuck-at 1。工具会生成向量,让这个节点翻转,然后观察输出是否变化。

我刚开始做ATPG时,总觉得覆盖率做到99%就万事大吉了。后来发现,stuck-at覆盖率99%不代表芯片没问题。还有transition delay fault、bridge fault等等。所以现在我做项目,至少跑两种故障模型:stuck-at和transition delay。

// ATPG脚本示例(TetraMAX)
set_context patterns -scan
add_scan_chain chain1 -clock clk -reset rstn -enable scan_en
add_scan_chain chain2 -clock clk2 -reset rstn -enable scan_en
add_faults -module core_top -type stuck
run_atpg -auto_compression
report_faults -summary
report_coverage
write_patterns test_patterns.stil -format stil

4.4 扫描链与ATPG的常见问题

做多了你就会发现,扫描链和ATPG的问题往往出在几个地方。

4.4.1 扫描链的时序问题

扫描链的时序约束和功能模式不一样。功能模式下,数据路径经过组合逻辑,延迟大。扫描模式下,数据直接从触发器到触发器,延迟小。但扫描链的时钟树可能和功能时钟树不同,hold time容易出问题。

我记得有个项目,功能时序全过了,扫描链的hold violation有上千条。后来发现是扫描时钟树没有做balance。解决办法是在扫描路径上手动插入buffer。

4.4.2 ATPG覆盖率低的原因

ATPG覆盖率上不去,通常有几个原因:

  • 未扫描的触发器:有些触发器被工具忽略了,比如异步复位触发器、门控时钟下的触发器。检查一下是不是所有触发器都进了扫描链。
  • 黑盒模块:第三方IP如果没提供扫描模型,ATPG工具没法测。需要手动写wrapper逻辑。
  • 冗余逻辑:有些逻辑在功能上就是冗余的,比如ECC校验的某些位。这些节点stuck-at故障测不出来,覆盖率自然低。

经验数据:一个成熟的DFT流程,stuck-at覆盖率应该做到98%以上,transition delay覆盖率做到90%以上。低于这个数,流片风险会显著增加。

4.5 扫描链设计的完整流程

下面这张图展示了扫描链设计与ATPG的完整流程。从RTL设计开始,到综合、扫描链插入、ATPG、仿真验证,最后到ATE测试。

扫描链设计与ATPG完整流程 RTL设计 逻辑综合 扫描链插入 ATPG向量生成 仿真验证 ATE测试 关键检查点 • 所有触发器是否可扫描? • 时钟域划分是否合理? • scan_enable是否同步? 常见问题 • 扫描链hold violation • ATPG覆盖率低 • 测试时间过长 覆盖率目标 • stuck-at > 98% • transition delay > 90%

4.6 扫描链的验证与调试

扫描链插完、ATPG向量生成后,一定要做仿真验证。我见过有人直接拿ATPG向量去跑ATE,结果芯片根本不工作。为什么?因为仿真没跑过,向量本身就有问题。

验证步骤很简单:

  1. 扫描链完整性检查:把一串0和1灌进去,看能不能完整扫出来。这叫flush test。
  2. ATPG向量仿真:用ATPG工具生成的向量做gate-level仿真,检查输出是否匹配。
  3. 时序仿真:带上SDF反标,检查扫描路径的时序是否满足。

调试技巧:如果扫描链flush test失败,不要急着看整个链。从第一个触发器开始,逐级检查。用force命令把scan_in固定住,看scan_out能不能正确输出。一级一级排查,很快就能定位问题。

4.7 扫描链设计的进阶话题

如果你已经掌握了基础,下面几个话题值得深入研究。

4.7.1 压缩扫描链

芯片规模越来越大,扫描链的测试数据量也爆炸式增长。压缩扫描链技术可以在不降低覆盖率的前提下,大幅减少测试数据量和测试时间。

原理很简单:在扫描输入和输出端加压缩/解压缩逻辑。输入端的解压缩器把少量测试数据展开成完整的扫描向量。输出端的压缩器把扫描结果压缩成少量数据输出。

我建议在芯片规模超过500万门时,一定要考虑压缩扫描。否则ATE测试时间会变成瓶颈。

4.7.2 边界扫描

边界扫描(JTAG)是另一种DFT技术,主要用于测试芯片之间的互连。它和内部扫描链是互补的。内部扫描测芯片内部,边界扫描测芯片之间的连线。

做SoC项目时,这两个都要做。内部扫描保证每个die没问题,边界扫描保证die之间的互连没问题。

好了,扫描链和ATPG的内容就讲到这里。记住一句话:DFT不是可选项,是必选项。没有可测试性的芯片,就像没有体检报告的人——你永远不知道它什么时候会出问题。