Tessent Scan与ATPG实用指南:从扫描链设计到测试向量生成避坑手册

发布时间:2026/10/15 2:08:04
Tessent Scan与ATPG实用指南:从扫描链设计到测试向量生成避坑手册
简介这是 Mentor Graphics现西门子EDA发布的《Tessent Scan and ATPG Users Manual》官方用户手册 PDF对应软件版本 2017.3文档修订于 2017 年 9 月面向芯片设计、DFT 与测试工程师。内容系统梳理了 ATPG 自动测试模式生成的原理、Tessent Scan 扫描链的设计与调试流程并对故障建模、覆盖率分析、诊断方法等关键环节做了具体说明能够帮助读者在实际项目中快速定位测试问题。整个资料包仅含一个 PDF 文件大小约 10.33MB体量适中可在桌面端与移动端方便保存、检索和按章节阅读。手册既提供了软件的操作指南与命令参数说明也给出了多种测试场景下的流程建议方便工程人员理解从设计到测试验证的完整思路。如果你是正在搭建 DFT 流程的芯片工程师或需要查阅 Tessent Scan 工具用法可以将这份原厂手册作为第一手参考资料。截至目前已有 683 人学习浏览这份文档在 IC 测试与可测性设计领域具备较好的参考价值。1. Tessent Scan and ATPG数字芯片 DFT 工程师绕不开的那份手册做数字芯片的人对 Tessent Scan 和 ATPG 这套流程大概都不陌生。拿到一块综合完的网表要插扫描链、要做设计规则检查DRC、要跑自动测试模式生成ATPG最后还要把测试向量丢给 ATE 去执行——这套链路里每一步都有玄学成分为什么规则检查报了几百条 violation为什么某个故障模型覆盖率死活上不去为什么生成的 pattern 在仿真里就是跟预期对不上这份 2017.3 版用户手册算是把 Scan 和 ATPG 的工具用法、故障模型、规则检查、测试程序文件的写法都系统过了一遍。它不是给你讲 DFT 概念而是直接对着工具界面和命令行告诉你这一步该敲什么、那一步报错该往哪查。适合刚接手 DFT 项目的新手也适合要查边界参数的老手。我当初第一次把扫描链插坏、pattern 仿真全红就是靠翻这份手册的规则检查章节找回的节奏。2. 扫描设计与 ATPG 原理从 scan cell 到故障模型的完整链条2.1 Scan Design 的基本结构Master、Slave 与 Shadow Element扫描设计是整个 ATPG 的地基。手册里把扫描单元拆得很细Master Element 是主锁存器Slave Element 是从锁存器Shadow Element 是影子锁存器Copy Element 是复制单元Extra Element 是额外单元。这几类元素在扫描链上扮演的角色不同命名规则和替换策略也不一样。我一般会先把设计网表里所有时序单元列出来确认哪些能替换成扫描单元哪些不能替换。供应商库里的扫描单元一般都有对应的非扫描版本比如 DFF 对应 SDFF带 Scan Enable 引脚。工具做扫描替换时会把普通 DFF 映射成带扫描功能的 SDFF同时保留原有的 D 端逻辑不动。# 读入门级网表和库文件 read_netlist $PRIM_LIB read_netlist $DESIGN_NETLIST read_netlist $TEST_LIB # 添加顶层设计并做链接 add_clusters 0 top add_design top # 设置扫描单元映射关系 set_dft_scheme sdf set_scan_cell_ident SDFF* set_scan_cell_replace DFF* - SDFF* # 执行扫描替换 insert_scan这段命令交互做的是读库、读网表、绑定顶层设计然后声明扫描方案sdf告诉工具哪些单元是扫描单元SDFF*哪些普通单元要替换成扫描单元DFF* - SDFF*最后insert_scan触发替换。替换完成后要检查Scan Cell Count是否符合预期如果替换数量对不上多半是库文件里缺了某些扫描单元的映射定义。Shadow Element 的处理是很多人忽略的点。它一般用于异步置位/复位的锁存器在扫描链上会被单独对待。如果设计里混用了主从结构的锁存器规则检查时就要确认 Shadow Latch 的识别结果是否正确否则后面测试程序文件Procedure File里的时序会跟你 setup 的扫描时钟对不上。2.2 扫描链与扫描组时钟域分割和链均衡扫描链Scan Chain的插入不是简单地把所有扫描单元串起来而是要综合考虑时钟域、功耗、布线拥塞和测试时间。手册里专门讲了 Scan Group 的概念——同一组扫描链通常共享同一组扫描时钟和测试控制信号。我通常的做法是先按时钟域划分扫描组再在组内做链均衡。一个 100K 门的 block如果只有一条扫描链测试时间会非常难堪拆成 8 条或者 16 条链每条链长度差不多测试时间就能缩短到原来的 1/8 或 1/16。但链数也不是越多越好扫描输出引脚和测试时钟树的开销会跟着涨。# 设置扫描链配置 set_scan_group_configuration -type scan_group \ -clock $TEST_CLK \ -chain_count 8 \ -chain_length 200 \ -balance_chains yes # 指定扫描输入输出端口 set_scan_port_configuration -type scan_in -port {SCAN_IN0 SCAN_IN1 ... SCAN_IN7} set_scan_port_configuration -type scan_out -port {SCAN_OUT0 SCAN_OUT1 ... SCAN_OUT7} # 执行扫描链插入 insert_scan_chains这段命令做了两件事一是声明扫描组共享TEST_CLK时钟链数是 8目标链长 200且要求链均衡二是把 8 个扫描输入端口和 8 个扫描输出端口绑定到对应引脚。-balance_chains yes是关键参数它让工具自动把扫描单元分配到 8 条链里尽量保证每条链长度接近避免某条链特别长而拉高整体测试时间。插入完扫描链后要用report_scan_chains检查每条链的长度分布和扫描单元构成。如果发现某条链特别短、另一条特别长说明链均衡算法被某些约束卡住了常见原因是某些扫描单元被 pin 端位置约束钉死在特定区域或者是层次化设计中子模块的扫描端口没有正确穿过边界。2.3 Test Procedure FileATPG 的时序黑匣子设定测试程序文件是连接扫描设计与 ATPG 之间的桥梁。它描述了测试过程中各个时钟、控制信号、扫描使能、复位信号的时序关系相当于告诉 ATPG 工具测试时应该怎么操作这些引脚。手册里对 Procedure File 的语法和用法讲得比较细包括timeset、force、measure、load_unload、shift、capture这些语句。实际项目中最常见的就是timeset定义时钟周期和波形。比如系统时钟是 100MHz测试时钟是 50MHz捕获脉冲的宽度、扫描移位的边沿位置都要在这里定义清楚。很多 ATPG 生成出来的 pattern 在仿真里跑不过就是 Procedure File 里的 timeset 跟仿真 testbench 里的时钟沿设置不一致。timeset TS_CLK period 20ns { force_pin TEST_CLK 0 at 0ns force_pin TEST_CLK 1 at 5ns force_pin TEST_CLK 0 at 10ns force_pin TEST_SE 1 at 0ns force_pin TEST_SE 0 at 12ns }这段 timeset 定义了一个 20ns 周期的时钟TEST_CLK前半个周期拉低、中间拉高、后半个周期再拉低同时定义了扫描使能TEST_SE在 0ns 时拉高移位模式在 12ns 时拉低捕获模式。ATPG 工具会根据这组时序去布置扫描移位和捕获脉冲的位置仿真 testbench 也要严格对齐这组沿来产生激励否则 pattern 会因建立时间违例而仿真失败。我强烈建议在项目目录里维护一份Procedure File 与 Testbench 对照表把 timeset 里的每个沿时刻、每个 force 动作跟 testbench 里对应的(posedge)、(negedge)、force语句逐行对照。每次改设计或改时钟方案先改表再改文件能省掉大量 pattern 仿真的调试时间。2.4 故障模型与故障分级为何 stuck-at 只是起点故障模型决定了 ATPG 工具朝着哪个方向去生成测试模式。手册里列出的故障模型包括 stuck-at、transition delay、path delay、IDDQ、bridge通过用户自定义故障模型 UDFM 实现、cell-internal 等。其中 stuck-at 是最基础的只考虑节点固定为 0 或 1 的故障transition delay 则考虑跳变沿的慢速需要两个连续向量——第一个向量建立初始值第二个向量在捕获沿处检查跳变。故障分级Fault Grading指的是每条测试向量能检测到多少故障。ATPG 工具会报告 detected检测到、undetected未检测到、untestable不可测这几类。这里的分类映射到手册里的 Fault ClassesTestableTE包括 detected_faultDS等子类UntestableUT包括 stuck_untestableSU等子类。覆盖率报告里的 98%、99% 就是基于这些分类算出来的。# 建立故障列表这里用 transition fault 模型 set_fault_model transition add_faults -all # 运行故障模拟覆盖率评估 run_fault_simulate # 查看故障分级报告 report_faults -class detected_fault -n这段命令先把故障模型切到transition然后添加设计里的全部故障点接着跑故障模拟最后只报告detected_fault这一类的故障明细。故障模拟的作用是在没有真正做 ATPG 之前先看当前测试向量集能覆盖多少故障通常用来评估随机 pattern 或已有向量的覆盖率。-n参数表示报告里不打印太多细节只看数量和覆盖率。跑完故障模拟后要重点看两个数字测试覆盖率Test Coverage和故障覆盖率Fault Coverage。前者是检测到的故障数除以可测故障数后者是检测到的故障数除以总故障数——包括那些不可测的故障。很多项目签收标准写的是测试覆盖率 98%那么 designer 要关注的就不是 Fault Coverage 那个数字而是 Test Coverage 因为不可测故障会被剔除掉松很多。3. 设计规则检查DRC把扫描链问题挡在 ATPG 之前3.1 通用规则检查时钟、复位、三态总线的潜在坑ATPG 设计规则检查是跑 ATPG 之前必须过的一道关卡。手册里把规则检查分成通用检查General Rules Checking、程序规则检查Procedure Rules Checking、总线互斥分析Bus Mutual Exclusivity Analysis、扫描链追踪Scan Chain Tracing等几类。通用检查主要排查时钟信号是否被逻辑驱动、复位信号是否合规、三态总线是否有多个驱动源同时驱动等。最常见的错误是时钟信号被组合逻辑驱动。例如某个模块内部通过AND门把系统时钟门控后送到触发器DRC 会报出时钟不是来自时钟端口或 PLL而是来自组合逻辑。Tessent 工具要求测试时钟必须直接来自时钟端口或经过明确的测试时钟树不能在数据路径里处理时钟。# 运行设计规则检查 check_design_rules -type general # 只显示错误级别的 violation report_design_rules -severity error # 如果规则检查报太多 violation加一个豁免文件仅限已验证的例外 # exempt_design_rules -file exempt_rules.defcheck_design_rules -type general跑的是通用规则检查report_design_rules -severity error把严重级别为 error 的 violation 过滤出来。exempt_design_rules通常是最后手段不要一上来就用——豁免的理由要写在注释里工程评审时要能讲清楚为什么这个 violation 不影响测试。另外一个很容易翻车的是异步复位信号的检查。如果设计里存在异步复位且复位信号直接来自触发器输出或组合逻辑DRC 会报 violation。正确做法是让异步复位信号也只来自顶层输入端口或者在测试模式下用ATPG_RESET这样的专用测试复位信号旁路掉异步复位路径。3.2 程序规则检查与总线互斥仿真失败的两大根源程序规则检查Procedure Rules Checking关注的是测试程序文件里定义的时序和工具推导出的扫描时序是否一致。这里最常见的问题是load_unload扫描加载/卸载操作时某些扫描单元的时钟沿设置跟移位时钟沿冲突导致扫描移位时数据还没有稳定就被时钟采走。报告里会指向具体的 timeset 和 scan cell需要回头去改 Procedure File。总线互斥分析是另一个高频问题点。设计里常有三态总线多个模块的输出通过三态门挂到同一根线上。ATPG 生成测试模式时要确保在任何时刻只有一个驱动源是使能状态。如果两个三态门的使能信号在某个状态下同时有效总线冲突仿真就会出 X 态pattern 结果全是 X。# 检查总线互斥 report_bus_conflicts # 查看具体冲突点 report_bus_conflicts -detail # 如果使能信号由扫描单元控制检查其控制逻辑是否满足互斥约束 report_bus_enable_logic -node BUS_A -commonreport_bus_conflicts会列出设计里所有三态总线冲突的候选点-detail把它对应的驱动单元和使能信号都打印出来。report_bus_enable_logic -node BUS_A是看某个具体总线的使能逻辑结构。出现冲突时典型的修法是给三态使能信号加互斥约束或者通过扫描单元的复位值保证默认状态下所有三态驱动都关闭。3.3 扫描链追踪失败从 report 到定位的全流程扫描链追踪Scan Chain Tracing是用来验证插入后的扫描链是否真的连通。工具会从每个 Scan In 端口出发沿着扫描链逐级追踪到 Scan Out 端口。如果中途某个扫描单元的时钟不是来自声明的扫描时钟或者某个单元的输出没有连到下一个单元的输入追踪就会失败。# 追踪扫描链 trace_scan_chains # 报出完整追踪结果 report_scan_chain_trace # 当追踪失败时查看日志里 ERROR 附近的扫描单元名称 # 定位到单元后用网表浏览器如工具自带的 schematic viewer查连接追踪失败时错误信息里通常包含出错单元的层次化路径名比如top/U1/U2/SDFF_X1_inst。定位的方式是打开网表浏览器看这个单元的Q脚连到哪里CK脚接的什么时钟SE脚接的什么信号。如果是手工改过网表后导致的连接断裂追踪失败非常正常如果插入流程是自动的追踪失败多半是时钟域划分出了问题比如某个扫描单元被错误地放到了另一个时钟域的扫描组里。4. 避坑指南ATPG 项目里最容易翻车的五个现场4.1 现象一扫描替换后仿真直接变红替换扫描单元后跑功能仿真结果大量 X 态。原因是扫描单元的复位/置位引脚没有接对测试模式下的信号导致扫描链上某些单元在捕获阶段被意外复位。解决方法是检查扫描单元在插入时的-reset或-set连接选项确保在测试模式下这些引脚不参与动作。# 查看扫描单元的复位连接 report_scan_cells -verbose | grep -i reset # 在插入时明确指定复位处理方式 set_scan_cell_configuration -reset_handling tie_off -reset_value 04.2 现象二ATPG 生成的 pattern 仿真覆盖率远低于报告值工具报告的覆盖率跟仿真验证覆盖率对不上差好多个点。原因通常是仿真 testbench 里没有正确处理双向引脚或者三态总线导致一部分 pattern 在仿真时被 X 态吞掉了观察点实际检测的故障数比工具期望的少。解决方法是把仿真日志里的X态统计打开逐条对比出现 X 的 pattern 和故障报告里的故障点。4.3 现象三跑 check_design_rules 报出超多时钟相关 violation一个项目里用了 PLL 分频出来的内部时钟DRC 报了几百条 violation。原因是测试模式下内部时钟路径没有被隔离PLL 的配置寄存器状态在扫描移位时不确定造成时钟沿抖动。解决方法是给 PLL 输出加测试时钟旁路 MUX测试模式下直接把外部测试时钟引到内部时钟网络上。4.4 现象四同一个 pattern 在同一仿真平台上结果不一致同一份 pattern同一个 testbench换了仿真版本就挂。原因是 Procedure File 里 timeset 的沿位置定义依赖于仿真器的精度和分辨率不同的timescale设置会改变事件队列的时序精度。解决方法是把 testbench 的timescale固定到一个比 pattern 时序精度更细的粒度比如 pattern 最小脉冲是 1nstestbench 就声明timescale 1ns / 1ps保证沿能对齐。4.5 现象五故障模拟跑几个小时都不结束故障列表太大故障模拟时间爆炸。原因是没做故障压缩或等效故障合并导致工具对大量等价故障反复模拟。解决方法是开启故障压缩fault collapsing只保留每个等价类的代表故障另外可以用set_fault_simulate_effort -medium这类参数控制模拟强度别一开始就跑最高精度。4.6 现象六扫描链报告里的链长度分布严重失衡插完扫描链后报告显示某条链只有 20 个单元另一条有 300 个单元。原因是锁存器和触发器的混合或者是某个子模块的包围链Wrapper Chain抢走了大量扫描单元导致主扫描链失衡。解决方法是检查顶层设计里是否混入了芯粒chiplet级的测试包装逻辑必要时把 wrapper 链和内部链分开做均衡约束。5. 从 DRC 通过到 Pattern 生成一套可复现的 ATPG 运行流程5.1 建立端口约束与时钟约束别让工具猜你的设计意图跑 ATPG 之前端口约束和时钟约束是最重要的准备步骤。你需要明确告诉工具哪些端口是测试时钟、哪些端口是测试数据、哪些端口在测试模式下必须固定。如果工具靠猜测去推断这些生成的 pattern 往往在你的设计里根本跑不起来。# 指定测试时钟端口与频率 set_test_clock -port TEST_CLK -frequency 50MHz # 指定测试控制端口 set_test_control -port TEST_SE -active high set_test_control -port TEST_RESET -active low # 指定在测试模式下需要固定值的端口 add_atpg_constraints -port DEBUG_MODE -value 0 add_atpg_constraints -port SCAN_MODE -value 1这段命令把TEST_CLK声明为 50MHz 测试时钟TEST_SE高有效TEST_RESET低有效然后把DEBUG_MODE固定为 0、SCAN_MODE固定为 1。add_atpg_constraints的目的是把功能模式下悬空的调试端口在测试模式下固定到一个确定值避免 ATPG 去猜这些信号。约束加错会导致生成的向量里某些引脚上出现不可能存在的逻辑值仿真同样会挂。5.2 生成 Stuck-at 和 Transition 测试向量参数选择与覆盖率权衡生成测试向量是 ATPG 的主输出。stuck-at 和 transition delay 是最常用的两种向量。stuck-at 向量关心的是节点固定故障transition 向量关心的是跳变时间过长。两者的生成参数有差异主要是向量长度、捕获方式、是否需要 launch 时钟等。# 切换故障模型并生成测试向量 set_fault_model stuck_at add_faults -all create_patterns -class stuck_at -name top_stuck_at # 统计向量数和覆盖率 report_patterns -summary # 如果覆盖率不够增加向量生成努力等级 set_atpg_effort -high create_patterns -class stuck_at -name top_stuck_at_highset_atpg_effort -high会提高 ATPG 的搜索深度和回溯次数生成的向量数可能变多但对提高覆盖率几乎到头时收益有限。真正卡覆盖率的时候要回头去看哪些类别的故障是 untestable是不是因为设计里有没法控制或观察的状态而不是盲目加高 effort。transition 向量的生成要额外指定 launch 类型例如 broadside译码宽侧或 skewed load偏移加载两种方式对时钟沿和捕获时序的要求不同。5.3 向量仿真验证Pattern 与 Testbench 的时序对齐生成的 pattern 必须在仿真环境里验证一遍不能直接信任工具的报告。通常做法是工具导出 WGLWaveform Generation Language或 STILStandard Test Interface Language格式的向量文件然后 testbench 读入这些向量逐条驱动仿真。# 写出 STIL 格式的测试向量 write_patterns top_stuck_at.stil -format stil # 写出 WGL 格式供老式 ATE 或仿真台用 write_patterns top_stuck_at.wgl -format wgl导出 STIL 之后testbench 里的capture_clk和shift_clk的沿位置写 testbench 之前先读一遍timeset定义STIL 文件的时序定义会覆盖 testbench 里的默认时序仿真时注意 log 里的 timing override 警告。那一次我折腾了大半天后来强制自己每次写 testbench 都先对照 Procedure File 的 timeset 定义再也没出过这种低级问题。6. 测试模式生成后的三件事IDDQ向量、故障字典与覆盖率审计6.1 IDDQ 测试靠静态电流发现的短路故障IDDQ 测试的思路是在 CMOS 电路稳定后测静态电源电流如果有故障导致原本不该导通的管子漏电电流就会变大。它不需要高速时钟但要求向量让电路进入一个确定的静态状态把所有动态节点稳定下来。Tessent 工具里生成 IDDQ 向量的方式和普通时序向量不同通常在扫描链加载完后把扫描使能关闭、主时钟停振等几个微秒再测电流。# 生成 IDDQ 测试向量 set_fault_model iddq add_faults -all # 设置等待时间和电流阈值与 ATE 的能力有关 set_iddq_config -wait_time 10us -current_threshold 50uA create_patterns -class iddq -name top_iddq-wait_time 10us是让电源电流在向量施加后稳定下来所需要的时间由工艺库和芯片功耗决定。-current_threshold 50uA是判断故障和正常的电流分界线由 ATE 的测量精度和芯片的静态漏电流共同决定。IDDQ 向量不会太多因为它的目的在于测静态电流而不是测逻辑功能几百个向量通常就足够覆盖主要的短路型缺陷。6.2 故障字典与诊断从 Fail Pattern 反推物理位置故障字典Fault Dictionary是把每个可测故障跟它对应的测试向量结果联系起来的一张表。当 ATE 测出某个 pattern 失败时根据失败的 pattern 编号和观测到的输出引脚就能在故障字典里反查出最可能的故障点。工具里对应的是 diagnosis诊断流程需要读入 ATE 的失败日志通常叫 failing log 或 datalog。# 读入 ATE 失败日志 read_fail_data top_stuck_at.fail -format datalog # 执行故障诊断 diagnose_failures # 输出候选故障列表 report_diagnostics -candidate_limit 5read_fail_data读入的是 ATE 回传的失败信息diagnose_failures把失败 pattern 跟故障字典做匹配report_diagnostics -candidate_limit 5列出每个失败 pattern 对应的候选故障最多 5 个。诊断结果的质量取决于故障字典的完整度和失败日志的观测点数为了提升分辨率可以在生成 pattern 时额外跑一份 multiple detect 的向量集让每个故障被多条 pattern 观察多次失败信息变多反推位置更准。6.3 覆盖率审计签收前最后一道防线覆盖率审计不是看一眼报告数字就完事而是要分模块、分故障类型做交叉核对。我的做法是先按顶层接口把设计切成几个子模块然后用report_faults分模块统计故障数和检测数再跟功能仿真里实际观测到的控制/观察能力做对比。如果一个模块的覆盖率明显偏低先看这个模块的输入输出是不是都被扫描单元包裹住了没被包裹的组合逻辑锥就会产生大量不可测故障。此外签收前还要跑一遍report_design_rules把 error 和 warning 分开归档确认 error 清零、warning 有明确解释。像-severity warning的未识别时钟或者悬空端口这类问题如果不管会导致后续物理实现阶段或 ATE 上出现莫名其妙的失败到时候再回头查就晚了。从那以后我每次拿到流片回来的芯片做测试准备时都强制自己先翻一遍 DRC 报告里的 warning 清单和覆盖率的分模块统计确认没有任何灰色地带然后再把测试向量签收出去。这个习惯救过我两次——一次是某个子模块的时钟在测试模式下没被正确旁路一次是 IDDQ 阈值设太紧导致芯片在常温都过不了测。希望这份手册的使用经验和这些坑位能帮你在接 DFT 任务时少绕几次弯路。本文还有配套的精品资源点击获取