☰
Tessent ATPG Verify Test Pattern:DFT工程师上ATE前必须守住的最后关卡
2026/10/8 15:16:01 网站建设 项目流程

从某个项目的周一开始讲起吧。那一次,ATE机台上刚跑完第一批pattern,我盯着fail记录,整整一片红色。问题不在ATPG覆盖率,也不在scan chain,而是我们跳过了Verify Test Pattern,直接把工具生成的pattern丢去了机台。DFT工程师都懂,pattern在Tessent工具内部生成、内部“确认”过覆盖率,但这不代表它在真实门级仿真器里能原样跑通。X态传播、掩码位置、compare沿的对齐,这些细节都可能让pattern在仿真阶段就崩掉,更别说上ATE。所以我才在5.1 Tessent ATPG系列的第八章里,专门把Verify Test Pattern拿出来讲透——这是Test Pattern Generation之后、ATE之前绝对不能省的关卡。

1. 为什么Pattern生成了还要再Verify一遍:上ATE前的最后一道安全网

1.1 ATPG流程中Verify的位置:从内部计算到真实仿真的跨越

先回顾一下整个Tessent ATPG的正常路径。前面几章我们经历过setup、read_design、DRC、add_faults、run_atpg,最后用run_dtp生成确定性的测试向量。很多工程师走到这里就觉得“完事了”,接下来把pattern转成WGL或STIL格式,丢给ATE就结束。但这里有一个非常关键的认知断层:

工具在run_dtp阶段计算出来的每个pattern,背后都有一个“good machine”响应。这个响应是工具在理想化的逻辑模型下,通过fault simulation推演出来的期望值。问题是,这个理想模型和真实门级网表之间存在差异——最典型的就是X态。真实的门级仿真环境里,没有初始化的触发器、memory单元的输出、未约束的模块端口,都可能产生X;而工具在生成pattern时,是通过逻辑值0/1来运算的,它也会做X处理,但处理的结果需要拿到真正的仿真器里去验证一次。

Verify Test Pattern这一环,就是把Tessent内部生成的test pattern放到真实仿真器(VCS、Questa、Xcelium这类)里,构建一个testbench,逐条或并行地加载pattern,跑完整个scan shift、capture、compare流程,看实际电路响应和工具的期望值是否完全一致。不一致的地方,就是必须在去ATE之前解决的问题。

1.2 Pattern里不止有01序列:时钟、掩码、非扫描单元状态

很多人对pattern的理解是“一串scan in的01数据”,这个理解太窄了。一个完整的pattern文件里,起码包含这几层信息:

  • scan chain的load和unload序列,也就是SI/SO的数据流
  • capture时钟的发出位置和脉冲宽度,shift时钟和capture时钟之间的切换时序
  • 非扫描单元(比如异步复位、memory的test mode控制信号)的初始化序列
  • compare窗口,也就是在哪个时间点采样scan out的值
  • 掩码信息,哪些位被mask掉、不参与比较

这里面,最让verify阶段难受的是后三类。Capture时钟发出的时候,组合逻辑传播出来的值是不是稳定,取决于门级网表的仿真模型和单元延迟;compare窗口如果落在时钟沿的边缘,仿真器的精度稍微差一点,采样到的值就会抖动;异步复位信号在pattern最前面的初始化阶段如果没建立起来,整个仿真环境就带着X跑,后面全是白搭。

工具在内部计算的时候,它自己的delay model和真实门级模型不可能完全一致。工具认为稳定的时序窗口,到了仿真器里,因为有真实的单元延迟和传播路径,可能出现毛刺或延迟,最终导致比较点的实际值和期望值不一致。这些不一致如果在仿真阶段发现,我们还能通过调整pattern生成约束来解决;如果等到了ATE,就只能烧钱烧时间在机台上慢慢调。

1.3 跳过Verify直接上ATE的成本账

我见过不止一个项目,为了赶交付时间,把verify这步给跳了,理由很统一:“反正工具已经算过覆盖率了,pattern肯定是对的。”

这个想法非常危险。ATE机台是按小时计费的,一条pattern挂了,不是重新跑一遍那么简单。你需要先做failure log分析,判断是contact问题还是pattern问题;如果是pattern问题,可能要重新生成向量、重新仿真,甚至可能牵扯到DFT约束的调整。一轮下来,两到三周的额外周期是保守估计。而Verify Test Pattern这一步,跑一次的时间是小时级的,换来的是把风险全部挡在机台之外。这个账怎么算都是划算的,特别是现在先进工艺节点的测试成本水涨船高,一颗芯片在机台上的时间就是真金白银。

2. Verify Test Pattern的命令语义:serial和simultaneous到底差在哪

2.1 两种仿真模式的本质区别

Tessent的verify命令,核心是verify test_patterns,但真正影响效率和使用场景的,是它下面的仿真模式选项。多数项目里,主要接触的是serial和simultaneous两种。

Serial模式,顾名思议,是逐条pattern单独仿真。每一条pattern都会构建独立的仿真条件,DUT重新初始化、应用该pattern、比对结果、生成报告。这种模式跑起来慢是肯定的,但好处是干净——某条pattern挂了,报告里能直接对应到pattern编号,不会跟其他pattern混在一起。它非常适合debug场景,比如工程师需要定位某一条具体的failing pattern,或者某条pattern的mismatch到底发生在哪个compare点。

Simultaneous模式就不一样了。它把多条pattern打包到一个仿真session里,通过某种“并行化”的方式在同一个testbench中连续应用多条pattern,甚至利用仿真器的多线程/并行特性去加速。这个模式下,仿真吞吐量比serial高一个量级以上,适合做大数量的全量回归。代价是debug的时候没serial那么直观——多条pattern在同一个session里连续跑,日志里pattern之间的边界需要额外去区分。

下面这个表是我项目里常用的模式选择逻辑:

维度Serial模式Simultaneous模式
仿真速度慢,逐条独立仿真快,批量并行处理
内存占用每条单独,峰值较低多条并发,峰值较高
Debug友好性高,pattern边界清晰中,需要额外定位pattern边界
典型场景新增pattern验证、debug全量回归、版本更新后快速验证
资源需求单机即可需要多核或多机并行环境

2.2 仿真器接口与版本匹配

Verify Test Pattern本身不是一个仿真器,它是Tessent和外部仿真器之间的桥。Tessent会根据你选择的仿真器类型,生成对应的仿真脚本、testbench和pattern格式,然后调起仿真器去跑。所以你的环境里必须装好了对应仿真器,并且Tessent能找到它。

这里有一个非常容易被忽视的点:仿真器版本和Tessent版本的兼容性。Tessent的verify模块在调起VCS或Questa时,生成的是特定版本语法风格的testbench。如果仿真器版本太旧,可能不支持某些结构;如果太新,一些老语法可能被废弃导致编译报错。我建议在使用之前,去确认一下Tessent版本对应的release note里列出的支持矩阵,把仿真器版本稳定在一个已验证过的组合上。这种问题一旦遇到,报错信息往往很诡异,排查起来会绕很久。

2.3 关键选项的含义:不只是一个开关那么简单

verify test_patterns命令下的选项,很多都不是可有可无的。举个我常用的例子:

verify test_patterns -tool vcs -serial -pattern_summary -output_file verify.log

这里的-pattern_summary会在验证完成后输出一个概要统计,包括验证的pattern总数、通过数、失败数、覆盖率对比等。它们是快速判断一次验证是否干净的入口。另一个常见选项是控制仿真精度的,这直接关系到X态和时序毛刺的判断。不同的仿真器对时间精度的处理方式不同,Tessent默认会按照工具内部设定的精度生成testbench,但某些极端情况下需要你手动指定更细的精度档。别看这个选项不起眼,在遇到“compare窗口边缘采样不确定”这类问题时,调整它有时候比改pattern快得多。

还有一个值得了解的选项是与waveform dump相关的。打开waveform dump后,verify过程中会生成FSDB或VPD波形。这玩意儿debug的时候是神器,但不开的话,你只能靠日志里的mismatch信息去反推问题,效率会差很多。我个人的习惯是:第一次跑通某条pattern或某个模块时必开waveform,全量回归的时候关掉。

3. 一份可以直接抄的Verify Dofile:从读设计到出Waveform的完整配置

3.1 环境准备与库文件加载

先放一份我在实际项目中用到的简化版dofile,读者可以根据自己的流片工艺和设计结构调整。它覆盖了从读入库文件、读网表,到生成pattern、执行verify的完整闭环。

# verify_run.dofile set DESIGN_NAME top_chip set NETLIST_FILE ../netlist/${DESIGN_NAME}_scan.v set CELL_LIB ../lib/tsmc55_lvtt.lib set SDF_FILE ../sdf/${DESIGN_NAME}_scan.sdf.gz set PATTERN_FILE ./patterns/${DESIGN_NAME}.tstl2 set WAVE_FILE ./waves/${DESIGN_NAME}.fsdb # 1. 环境初始化 setup -product tessent_atpg # 2. 读入库模型 read_cell_library -lib $CELL_LIB # 3. 读入门级网表 read_design -verilog $NETLIST_FILE -root $DESIGN_NAME # 4. 定义时钟和DFT信号 add_clocks -clock CLK -period 10.0 -waveform {0 5} add_dft_signals -scan_enable SE -scan_reset SR # 5. DRC检查 run_drc # 6. 故障与ATPG add_faults -all run_atpg -auto_compression -effort high # 7. 生成确定性的测试pattern run_dtp # 8. 输出pattern文件 create_test_patterns -format tstl2 -output_pattern_file $PATTERN_FILE # 9. 串行验证,并输出波形 verify test_patterns \ -tool vcs \ -serial \ -pattern_summary \ -waveform_file $WAVE_FILE \ -output_file ./logs/verify_serial.log

这个dofile的每一步都不复杂,但有几个细节需要特别注意:

3.2 时钟定义与SDF反标:verify前先想清楚要不要

add_clocks里的时钟参数,一定要和实际测试模式下的时钟保持一致的频率和占空比。很多工程师在ATPG阶段用的是快时钟,到了verify阶段如果不显式修改,Tessent会沿用之前的定义。这本身没错,但你要确认一点:verify阶段要不要反标SDF。

这是我在多个项目中观察到的分歧点。有一部分工程师喜欢在verify时把SDF反标打开,理由是“这样仿真更真实”。但我的建议是,常规的ATPG pattern verify阶段,不要反标SDF,用unit delay或者零延迟跑就够了。原因是,ATPG pattern本身就是按照慢时钟全周期来设计的,它验证的是“逻辑功能是否匹配”,不是“STA时序是否满足”。时序分析应该交给专门的signoff工具,而不是在pattern verify里混在一起。一旦反标SDF,单元延迟加上时钟树延迟,很容易在capture沿附近产生各种亚稳态和毛刺,最后报出来的mismatch不是逻辑问题,而是时序伪报,会严重干扰判断。

3.3 Serial模式做Debug:波形文件是定位的第一抓手

如果你跑的是serial模式,那强烈建议在第一次验证时就把-waveform_file选项打开,并保持-pattern_summary。前面那份dofile里我已经把waveform dump打开了。跑完之后,从仿真器里导出的FSDB可以直接拉进Verdi之类波形工具里。一旦后续日志里出现某条pattern失败,你不需要重新跑一遍仿真,直接拿这次dump的波形,定位到对应时间点去观察SI/SO信号的翻转情况,和pattern文件里期望的load/unload序列做对比,很快就能看出是X态问题、时序问题还是掩码问题。

3.4 Simultaneous模式做全量回归:注意资源规划

Serial模式跑通了基本功能之后,正式大批量回归时我会切到simultaneous模式。命令上的差别很简单,就是把-serial换成-simultaneous,去掉waveform输出,把-output_file对应改个文件名。

verify test_patterns \ -tool vcs \ -simultaneous \ -pattern_summary \ -output_file ./logs/verify_simul.log

但simultaneous模式有一个隐藏的成本:资源占用。它会尝试并行起多个仿真任务,如果你所在的集群节点数有限,或者license数量有限,反而可能跑得比serial还慢。我建议先做一个小规模的并行度测试,确认当前环境能承受多少个并发任务,再确定全量回归时的资源分配。Tessent本身也会做任务调度,但底层还是要看你机器的真实负载。

4. 结果怎么看:日志、报告和Waveform里隐藏的信号

4.1 Verify日志里必须盯住的几个统计值

跑完verify不是看一眼“passed”就完事的,日志里的信息密度很高,但很多人不知道往哪儿盯。我一般会按从宏观到微观的顺序,依次看四类信息:

  • pattern总数和验证通过数是否一致。如果存在任何failing pattern,先记下编号。
  • coverage对比。Verify结束时Tessent会重新统计一次fault coverage,这个数字应该和run_atpg阶段报出的coverage基本一致。如果发现coverage明显下降,说明有一部分fault在真实仿真环境下没有被观察到,这是mask或X态处理引入的问题,不能无视。
  • DRC warning里有没有涉及到specific pattern的条目。有些DRC warning在pattern生成时被忽略,但在verify阶段会暴露出来。
  • 关键message里有没有出现“X”相关的警告。这个往往是mismatch的前兆,如果X传播到你关注的观察点,这条pattern的覆盖率统计就会被污染。

4.2 Pattern Summary表怎么读

开启了-pattern_summary之后,验证结束后会额外生成一个summary报告,通常是一个表格,列出每条pattern的编号、覆盖的fault数、pattern类型(比如是基本scan测试、还是capture补偿测试)、以及对应的仿真结果。表格里的信息可以快速筛出哪些pattern是“低质量”的——比如覆盖fault很少、但仿真时间很长的pattern,这类pattern优先考虑在后续优化中去掉。还有一类pattern需要特别留意,就是那些结果列里标记了“X”的。它们不是传统意义上的fail,但可能稀释整个coverage的准确性,需要结合波形去判断是否要保留。

4.3 用Waveform定位Mismatch的具体操作

定位mismatch时,只看日志往往不够直观,我的套路是这样的:先用日志里给出的pattern编号和simulation time,在波形里定位到对应位置;然后把Tessent pattern文件里该条pattern的期望scan_out序列打开,在波形里找到对应scan_out引脚的实际翻转序列,逐位对比。如果发现某一位对不上,继续往前追:该bit对应哪条scan chain、又是scan chain上哪个触发器、这个触发器在capture cycle前接收到了什么样的数据。这一步通常能快速判断,是capture沿打进去的值本身就不对,还是shifting过程中被X态污染了。

按照这种排查链路,大部分mismatch都能在一个小时内定位到根因,完全不需要“盲修”。

5. 我踩过的Verify坑:三类典型失败与完整排查链路

5.1 X态传播导致的Mismatch:根因定位全过程

有一类mismatch我遇到得最多,就是X态传播。表现为verify日志里哗哗地报几百条pattern全部fail,而且fail的位非常集中,总是落在某几个模块对应的scan chain上。

拿到这类问题,我不会先去看pattern,而是先去看X态是从哪里来的。做法是把waveform打开,在第一条failing pattern的compare时间点附近,查那几个观察bit的来源寄存器。通常追两步就能看到某个寄存器的D端是一个memory的输出,而memory在这个测试模式下没有被初始化,输出是X。X顺着组合逻辑一路传到了scan chain的输入端,又在capture沿被采样进触发器,最终在compare点被报出来。

这类问题的根因往往在DFT约束层面:要么是该memory的test mode信号没有在pattern初始化阶段被正确拉起,要么是ATPG阶段没有把该memory的cell库模型配好。解决方式也分两种,一是调整初始化序列,让memory在pattern开始时进入一个已知状态;二是在保证覆盖率损失可接受的前提下,通过工具设置把相关路径mask掉。但不管选哪种,我都不建议直接用外部脚本去改pattern文件里加掩码,那是治标不治本。

5.2 SDF反标引发的时序伪报

另一个容易踩的坑是SDF反标。有一段时间我们的项目为了“仿真更接近真实”,在verify时统一加了SDF。结果同一套pattern,之前零延迟仿真全过,一加SDF就fail掉一大片。

排查过程中我首先确认了一个现象:fail的pattern在时间上不是随机分布的,而是集中在capture沿附近的compare点。打开波形后,观察那几个出问题的scan_out bit,会发现它们并不是逻辑错误,而是在compare时刻附近有一个明显的跳变翻转。也就是说,信号在一点点延迟之后才稳定下来,刚好错过了compare窗口。

这个现象说明逻辑功能没有问题,是时序窗口冲突。ATPG pattern本身就是基于慢时钟周期设计的,逻辑在下一个沿之前早就稳定了;但反标SDF后,clock skew、cell delay组合起来,把正常窗口压缩了,甚至出现了竞争现象。对于ATPG pattern的verify来说,这属于伪报。我们最终的处理方式,就是回到不反标SDF、使用unit delay做逻辑验证。真正的时序signoff,交给PT这类工具去保证。

5.3 掩码缺失与Golden Value失配

还有一类问题比较隐蔽,是掩码相关的。一次验证新版本的pattern时,发现某一条pattern在几次重复仿真中,结果不稳定——偶尔pass,偶尔fail。这种“间歇性”问题是最折磨人的。

后来我仔细对比了Tessent生成的pattern文件和testbench中的compare逻辑,发现问题出在compare窗口设置上:该pattern的compare点刚好落在某个时钟沿附近,仿真器受限于时间精度,对沿上信号的采样值有微小的不确定性,导致golden value和实际峰值判断偶发不一致。

遇到这种问题,首先要调整compare窗口的生成方式,确保compare点避开时钟沿。如果工具不允许直接调整,可以尝试修改该pattern的生成约束,把capture沿和compare沿错开足够的裕量。另外一个思路是在不影响覆盖率的位上加掩码,但必须是工具层面生成的掩码,不是人为手工改文件,否则后续维护成本会很高。

这几种坑,基本就是我在多个项目里踩过的绝大部分verify问题。看起来五花八门,本质上都是同一个问题:工具内部模型、pattern文件、真实门级仿真环境这三者之间,存在细小的语义差异,而verify的价值就是把它们暴露出来。每次搞定一个case,我对“为什么Tessent要专门留一个verify环节”的理解就更深一层。

最后分享一个我的个人经验吧。现在我每次做完ATPG pattern,无论交付工期多紧,都坚持把Verify Test Pattern作为一个强制步骤写进checklist里,并且默认用simultaneous模式跑全量,用serial模式只针对增量pattern做验证。这样既不耽误效率,又能保证每一条上机台的pattern都是在真实仿真环境里验证过的。芯片测试这行,前期多花一个小时做仿真,后期就能省下机台上的一整天,这笔账,我算得滚瓜烂熟。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询