4、可测试性设计(DFT)基础:DFT的目的与类型、扫描链原理、ATPG与故障模型、BIST与边界扫描

可测试性设计,简称 DFT。说白了,就是给芯片装上一套「体检系统」。你想想看,一颗芯片流片回来,你怎么知道它里面几千万个晶体管有没有坏的?靠肉眼?不可能。靠功能测试?太慢,而且覆盖率低。

我入行那会儿,带我的老工程师跟我说过一句话,我一直记着:「设计做得再好,测不出来等于白做。」后来我自己带项目,有一次芯片回来功能全对,偏偏在客户那边高温下死机。查了三个月,最后发现是内部一个节点有桥接故障,但我们的测试向量根本没覆盖到。从那以后,我对 DFT 再也不敢马虎。

4.1 DFT 的目的与类型

DFT 的核心目的就三个:

  • 提高故障覆盖率——确保芯片内部绝大多数物理缺陷能被测试抓到
  • 降低测试成本——减少测试时间、简化测试设备要求
  • 支持诊断与良率分析——出问题了能定位到具体哪个 cell 坏了

常见的 DFT 类型,我整理了一张表:

DFT 类型 适用场景 核心思想
扫描链(Scan Chain) 逻辑电路测试 将寄存器连成移位链,外部可控制/观察内部状态
内建自测试(BIST) 存储器、高速接口 片上生成测试向量,片上分析结果
边界扫描(JTAG) 板级互连测试 芯片 I/O 之间串行扫描,检查焊点与走线
测试点插入(Test Point) 低可观测性节点 增加控制点或观察点,提升覆盖率
我的习惯:项目早期就要定好 DFT 策略。等 RTL 写完了再补 DFT,往往要改架构,代价很大。我一般会在综合前就把扫描链和 BIST 的方案定下来。

4.2 扫描链原理

扫描链是 DFT 的基石。它的原理其实不复杂:

正常模式下,寄存器正常工作。测试模式下,所有寄存器被连成一条或几条长移位寄存器链。测试向量从芯片引脚串行输入,经过所有寄存器,最后从输出引脚串行读出。

具体来说,每个寄存器被替换成带两个数据输入的扫描触发器(Scan Flip-Flop):

  • D 端——正常功能数据输入
  • SI 端——扫描数据输入
  • SE 端——扫描使能,控制选择哪个输入
  • Q 端——输出,同时接到下一个寄存器的 SI

测试流程分三步:

  1. 移位加载——SE=1,测试向量从 SI 串行移入所有寄存器
  2. 捕获——SE=0,一个时钟周期内组合逻辑计算结果被捕获到寄存器
  3. 移位卸载——SE=1,结果串行移出,同时加载下一个向量

关键指标:扫描链长度直接影响测试时间。一条链上有 10000 个寄存器,加载一个向量就需要 10000 个时钟周期。我一般建议把链长控制在 500~2000 之间,太长了测试时间受不了,太短了浪费 IO 引脚。

下面这张图展示了扫描链的基本结构:

扫描链结构示意图 Scan_In FF_1 (SI→Q) 组合逻辑 FF_2 (SI→Q) 组合逻辑 Scan_Out FF_3 (SI→Q) 组合逻辑 FF_4 (SI→Q) 说明: • 实线箭头:正常功能路径(组合逻辑 → 寄存器) • 橙色虚线箭头:扫描链路径(FF_1 → FF_3,FF_2 → FF_4) • 测试时,SE=1 激活虚线路径,SE=0 激活实线路径
我曾经踩过的坑:扫描链综合时没注意时钟域。两个不同时钟域的寄存器连到同一条链上,结果测试时时序乱套,覆盖率直接掉到 60%。后来我强制要求:不同时钟域必须分链,或者加同步器。

4.3 ATPG 与故障模型

ATPG,全称 Automatic Test Pattern Generation,自动测试向量生成。它的任务就是:给定一个故障模型,自动算出一组测试向量,让故障能被检测到。

最经典的故障模型是 固定故障模型(Stuck-at Fault Model)。它假设某个节点要么永远为 0(Stuck-at-0),要么永远为 1(Stuck-at-1)。

举个例子:一个两输入与门,输出端 stuck-at-0。要检测这个故障,你需要让两个输入都为 1,这样正常输出应该是 1,但故障输出是 0。ATPG 工具就会自动生成这样的向量。

除了固定故障,还有几种常见模型:

故障模型 描述 典型覆盖率目标
Stuck-at 节点固定为 0 或 1 ≥ 98%
Transition Delay 信号跳变太慢(上升/下降沿延迟) ≥ 90%
Path Delay 整条路径的累积延迟超标 ≥ 85%
Bridging 两条相邻走线短路 视工艺而定

ATPG 工具跑完后,会生成一个测试向量文件,通常叫 .stil 或 .wgl 格式。这个文件直接交给测试机台用。

我个人的经验:不要盲目追求 100% 覆盖率。有些节点天生难测,比如复位信号、时钟门控。硬要覆盖它们,测试向量数量会爆炸。我一般设目标为 98%~99%,剩下的靠诊断分析补。

4.4 BIST 与边界扫描

BIST,Built-In Self-Test,内建自测试。它让芯片自己测试自己,不需要外部测试机台生成向量。

BIST 最典型的应用是 存储器 BIST(Memory BIST)。芯片里的 SRAM 数量多、密度高,用扫描链测太慢。BIST 的做法是:

  • 片上集成一个控制器,自动生成地址、数据、控制信号
  • 按特定算法(如 March C-)对存储器进行读写
  • 比较读出结果,输出 Pass/Fail 信号

March C- 算法是业界最常用的。它包含几个 march 元素,每个元素对每个地址执行一组操作:

March C- 算法步骤:
1. 对所有地址:写 0
2. 对所有地址:读 0,写 1
3. 对所有地址:读 1,写 0
4. 对所有地址:读 0,写 1
5. 对所有地址:读 1,写 0
6. 对所有地址:读 0

这个算法能覆盖固定故障、转换故障、耦合故障等多种缺陷。

边界扫描 则是基于 JTAG 标准(IEEE 1149.1)。它主要用来测试芯片之间的互连,比如 PCB 上的焊点有没有虚焊、短路。

边界扫描的核心结构:

  • TAP 控制器——状态机,控制测试流程
  • 指令寄存器——选择要执行的测试操作
  • 边界扫描寄存器——每个 I/O 引脚旁都有一个移位寄存器单元
  • 旁路寄存器——跳过不需要测试的芯片,缩短链长

测试时,通过 TDI(Test Data In)串行输入指令和数据,通过 TDO(Test Data Out)串行读出结果。TCK 提供时钟,TMS 控制状态机跳转。

实际项目中的应用:我做过一个 SoC 项目,集成了 8 颗 DDR 控制器。每颗控制器的 PHY 之间都有大量互连。我们用边界扫描做板级测试,一次扫描就能查出哪根数据线断了。如果没有边界扫描,这种问题排查起来简直噩梦。

最后,我把三种 DFT 方法的特点做个对比:

方法 测试对象 测试速度 面积开销 外部设备需求
扫描链 逻辑电路 慢(串行移位) 5%~15% ATE 测试机
BIST 存储器、接口 快(并行测试) 1%~5% 仅需启动信号
边界扫描 芯片互连 中等 2%~8% JTAG 控制器

嗯,DFT 这部分内容不少,但核心就这些。你想想看,没有 DFT 的芯片就像没有仪表盘的汽车——能跑,但你永远不知道它什么时候会出问题。做后端设计,DFT 不是可选项,是必选项。