做DFT这几年我统计过一个不算严谨的数据大多数测试工程师日常接触的ATPG pattern85%以上是Basic Scan。这本身没毛病——标准扫描结构下Basic Scan的生成流程最成熟、pattern体积最可控、解析也最省心。但一碰到两类设计Basic Scan就开始露怯一类是内部有时钟生成逻辑的另一类是嵌了几块RAM却没有独立BIST的。前者要么覆盖率趴窝要么pattern在仿真和ATE上反复横跳后者直接给你报一堆unobservable。这篇就专门拆这两种模式Clock PO和RAM Sequential。它们不像Basic Scan那么“百搭”但针对的场景非常明确——Clock PO解决的是内部时钟的可控和可观测RAM Sequential解决的是存储阵列的读写序列测试。我会把它们的原理、工具约束方式、以及我在实际项目中怎么组合使用一次讲清楚。文章里的命令写法参考了TetraMAX和Tessent的通用风格具体到某个版本项目里还是要以自己的库和脚本为准但思路是通用的。1. Basic Scan的边界在哪为什么它覆盖不了时钟逻辑和存储阵列1.1 Basic Scan的经典时序Shift、Launch、CaptureBasic Scan之所以能成为ATPG的事实标准核心在于它把复杂的时序逻辑测试问题转换成了组合逻辑测试问题。扫描链把所有触发器串成一条或者几条超长的移位寄存器测试过程分成三个大阶段Shift阶段scan enable拉高所有扫描单元首尾相连。测试时钟连续翻转每来一个沿就从主输入移入一位数据同时把上一轮捕获的响应往主输出方向推。shift的频率通常比功能时钟低很多常见10MHz到50MHz之间目的是绕开扫描链布线的时序收敛问题。Capture阶段shift完毕scan enable拉低。此时每个扫描单元的Q端输出已经稳定组合逻辑开始工作。给一个或几个capture脉冲让组合逻辑的响应在时钟沿处被捕获回扫描单元。Unload阶段scan enable重新拉高响应数据一边从扫描链末端移出一边把下一条向量移入这一过程是重叠的所以吞吐率很高。对stuck-at faultcapture只需要一个脉冲对transition fault需要两个脉冲——第一个脉冲launch第二个脉冲capture。这就是为什么TDF pattern的capture窗口比SAF复杂得多也更容易出问题。很多人在Clock PO模式上的困惑恰恰是从这里开始当capture时钟是由内部PLL分频产生的时候你到底该让工具怎么理解这条时钟路径1.2 覆盖率上不去的三类典型未覆盖点在纯数字逻辑设计里Basic Scan覆盖90%以上的可测故障是常态纯逻辑甚至能推到99%。但真实芯片很少这么干净。我总结下来Basic Scan覆盖率卡住通常就是三类东西在拖后腿第一类是内部时钟生成逻辑。PLL、分频器、时钟门控单元ICG的使能端、以及时钟MUX的选择端这些逻辑要么在测试模式下被固定死要么因为时钟路径太深扫描链观测不到。尤其ICG的EN端stuck-at故障如果没有对门控时钟做特殊处理Basic Scan基本无能为力。原因很直白捕获窗口就那么几个沿时钟门的EN信号变化还没来得及传到数据路径捕获已经结束了。第二类是存储单元阵列。RAM的核心阵列不是标准单元触发器扫描链根本伸不进去。Basic Scan能把读写逻辑、地址译码逻辑外围的故障模型抽出来但一旦涉及位线短路、存储单元交叉耦合反相器的制造缺陷扫描链没有任何观测点。工具报unobservable都算客气有些情况下它直接把你RAM相关逻辑的全部故障都标记成uncontrollable。第三类是模拟/混合信号接口。这个场景更复杂但通常的处理方式是在接口处插隔离逻辑让数字侧能看到一个确定值。Basic Scan能做只是需要额外DFT设计支持不是pattern本身能解决的。1.3 一个反直觉的事实扫描链越长测RAM越难以前有朋友问我芯片里RAM本身测不到那我把它周围多插几层扫描寄存器是不是就能间接提高RAM的测试质量答案是能提高但代价很高而且有边界。RAM的读写行为是顺序的。你要验一个地址能不能正确写入必须先在某个周期把地址和数据送到RAM端口写使能拉有效等待写完成再把读使能拉起来读出数据才能判断。这一套动作在Basic Scan的capture窗口里根本做不完——capture脉冲通常就一两个周期RAM还没来得及把数据写进去捕获就结束了。扫描链插得再多capture窗口也撑不住整个写-读序列。所以对付RAM要么上Memory BIST靠片上状态机自己跑March算法要么用RAM Sequential模式让pattern在多个时钟周期里完成写-读序列。后者不需要额外硬件但对工具约束和pattern长度控制的要求高得多。这个我会在第三章展开。2. Clock PO模式当内部时钟必须被“看见”并“接管”2.1 Clock PO在ATPG工具里到底是什么意思很多人第一次看到Clock PO这个词以为就是把时钟引脚当作普通输出看一眼。这个理解方向对但不够深。在ATPG工具的术语里Clock PO的意思是时钟信号不仅作为扫描链和捕获时钟存在还要作为一个可观测的主输出被pattern显式地检查和比对。换句话说工具会在生成的pattern里为这个时钟信号单独记录期望值ATE在跑pattern的时候会像检查data_out一样检查这个时钟节点。为什么需要这么做因为可观测性是覆盖率的前提。一个内部时钟信号如果既不控制任何扫描单元又不被主输出采样那它对ATPG来说就是盲区。盲区意味着潜在缺陷可能在测试中漏掉。把时钟配成PO之后工具就有了“眼睛”去看这个时钟是否按预期翻转、是否在预期时刻出现了正确的边沿。在TetraMAX和Tessent里把内部时钟设为PO的常见做法包含两个层面一是网表级别把PLL输出或者分频器输出引到某个测试专用主输出引脚上或者通过MUX接到已有的观察引脚二是在约束文件里用set_dft_signal / add_clock这样的命令声明该时钟的观察属性。具体命令语法各版本有差异但思路一致让工具知道这个节点既当钟用也当信号采。2.2 测试时钟直通方案从PLL输出直接引到测试引脚实际项目里用Clock PO最常见的一个场景是测试的时候不想依赖内部PLL直接把外部测试时钟引进去。芯片进入test mode后ICG和时钟MUX把PLL路径断掉功能时钟全部由外部测试时钟引脚接管这样时序上完全可控pattern在ATE上也稳定。这个过程中有一层MUX逻辑是必须被测试的——test mode选择信号、MUX的输入输出。如果不做任何处理这个MUX的select端通常可以由扫描单元控制但时钟MUX的输出如果直接驱动整个时钟树那这个输出节点本身的值变化在Basic Scan的capture窗口里是“看不见”的。解决方案就是把这根时钟线在测试模式下接成可观测的Clock PO要么引到专门测试引脚要么在MUX输出处加一个观测寄存器。我这里有一个真实踩过的坑。某个项目的PLL在低速测试模式下输出本身就是不稳定的——PLL的锁定需要时间如果pattern一开始就期望它输出规整时钟Capture阶段很容易采到毛刺。后来我们把PLL输出配成Clock PO并且在pattern开头预留了锁定等待周期让ATE多等几个毫秒再开始比对那个PO点上是否有期望时钟翻转问题才彻底消失。这个等待时间的设置在Basic Scan里完全用不上但一旦Clock PO上场就必须考虑。2.3 复用功能时钟树的方案约束的内部细节另一种做法是不切外部测试时钟让功能时钟树在测试模式下也工作由PLL正常供钟。这种方案对at-speed test很有价值因为功能频率下时钟树的真实延迟、skew、以及门控逻辑的时序行为都更接近实际使用。但复用功能时钟树对ATPG约束的挑战是工具必须清楚每个capture沿是从哪一级分频来的。如果你有四路分频时钟每一路都驱动着不同的扫描链工具在生成transition pattern时必须保证launch沿和capture沿来自同一条时钟路径否则捕出来的响应没有意义。这个时候Clock PO的作用从“观测”变成了“锚点”。工具会把多条分频时钟的叶子节点分别设成PO并在pattern里记录它们的翻转相位。我做过的方案里最稳妥的做法是给每一路分频时钟都加一个独立的Clock PO并且在约束里明确声明它们的相位关系同沿翻转还是不同沿翻转。如果不声明工具默认它们同相一旦实际相位差半拍整个TDF pattern在仿真阶段就会暴露出一堆伪失败排查起来非常痛苦。2.4 实测中Clock PO常被忽略的时序坑第一个坑是毛刺捕获。时钟信号在翻转过程中会有短暂的中间电平或振荡如果ATE采样点刚好落在毛刺上pattern比对就会失败。这种失败不是真故障是采样时机问题。解法有两条一是调整ATE上的采样沿把采样点靠近期望电平稳定区域二是对Clock PO做mask窗口只在特定周期观察其他周期不比对。第二个坑是时钟树的RC延迟导致路径不匹配。同一个时钟源经过两级缓冲到达PO节点的时间和到达触发器时钟端的时间可能差几百皮秒。对于慢速shift没问题at-speed capture时这个差异会让工具误判时钟沿。这不是pattern生成错误而是约束里的时序信息不够精确。把SDF反标做完整或者在工具里设置时钟树延迟的保守值能缓解。第三个坑藏在仿真里。很多RTL仿真环境的时钟是ideal的RC延时为零Clock PO的期望值在仿真中很容易比对通过但到了ATE上因为真实延迟就挂掉。所以一旦启用Clock PO我建议在仿真阶段就加一些人为的时钟偏斜约束而不是全默认ideal。别问我为什么推荐这么做——你要是见过一次仿真全绿、ATE全红的场面你也会这么干。3. RAM Sequential模式动手构造写-读序列来测存储器3.1 为什么RAM绕不开Basic Scan的盲区RAM的基本存储单元是交叉耦合反相器加访问管它的制造缺陷模式很特殊字线开路、位线短路、单元下拉管驱动能力不足、访问管泄漏过大等。这些缺陷在逻辑测试里会表现为一个个具体的stuck-at或transition点但问题是你根本控制不了存储单元内部节点。更麻烦的是RAM在未初始化时输出是X态。Basic Scan的capture周期如果落在RAM读路径上扫描链捕获回来的可能是X这个X会在整个扫描链上传播导致大量其他本可以正常捕获的故障也被标记成未知。这也是为什么很多ATPG报告里一旦RAM出现在设计中即使面积占比很低coverage数字也会很难看。所以RAM要么用BIST要么用RAM Sequential。BIST需要额外硬件状态机、比较器、BIST接口大RAM上划算小RAM或者寄存器堆上很多前端团队不愿意为此多花面积这时候RAM Sequential是现实的选择。3.2 RAM Sequential的激励序列设计从写0/读0到地址扫描RAM Sequential模式的基本思路并不复杂通过扫描链把地址、写入数据、写使能、读使能全部加载好然后产生一个写周期把值写进RAM再把地址、读使能加载好产生一个读周期读出数据和期望值比对。听起来简单但真正生成pattern时要考虑的序列比想象中多最基本的是写0读0、写1读1这能覆盖存储单元的stuck-at fault和位线的stuck-at fault。为了覆盖位线短路需要棋盘格数据背景比如0x55和0xAA交替这样相邻位线的期望电平相反短路才可能被暴露。为了覆盖地址译码逻辑需要对地址做遍历组合常见的有递增地址、递减地址、walking 0/1、以及格雷码跳变。地址跳变幅度越大对译码逻辑的翻转覆盖越好。为了覆盖数据线上的transition fault——也就是某根线从0变1或从1变0的过程太慢——需要连续写两个互补值然后马上读出来这就是“写0写1读”的三步序列。这里有一个关键点RAM Sequential的pattern数量不是由逻辑故障决定的而是由地址深度决定的。一个4K深的RAM如果每个地址都要走一遍比较完整的写-读序列那么单是这一个RAM就可能导致几千条pattern。实际项目中必须权衡全地址遍历可能让pattern量爆炸而只抽测部分地址又可能漏掉某些译码故障。我见过比较保守又合理的做法是对小容量RAM比如深度小于2K做全地址遍历大容量RAM只做边界地址加随机抽样地址把完整的March测试交给BIST去跑。3.3 工具里的memory model与pattern生成机制在TetraMAX和Tessent里RAM Sequential模式的生成依赖memory model。工具需要知道RAM的端口时序、时钟边沿、读写控制信号的关系才能规划出合理的激励序列。这个model通常有两种来源一是标准单元库厂商提供的lib模型附带memory信息二是在工具里手动定义规则。手动定义的阶段最容易出问题。比如一个双端口RAM工具默认的读写时间窗口只有几纳秒但实际设计中写脉冲可能需要更长时间才能稳定也可能反过来RAM的实际建立时间比工具模型里的默认值短导致pattern过于保守、测试覆盖率下降。这些参数没有统一标准完全依赖后端时序报告来校准。我习惯在一个新的RAM型号接入测试流程时先跑一个“探针pattern”仅对RAM写一个地址读回来用仿真工具看数据是否正确。如果探针通过再把RAM加入正式ATPG流程如果探针都过不了说明memory model的参数配置有问题这时候强行生成大量pattern只会浪费跑机时间。3.4 RAM Sequential与MBIST的适用边界对比RAM Sequential和MBIST是并存关系不是替代关系。我做了个简单对比对比维度RAM SequentialMemory BIST额外硬件无需要BIST控制器和比较器面积成本零每个RAM约增加2%~5%面积测试时间pattern数多测试时间较长片上自动跑时间短故障覆盖重点RAM I/O逻辑、互连、基本阵列SAF存储单元阵列内部缺陷适用场景小容量RAM、寄存器堆、无BIST设计大容量RAM、需要at-speed March对ATPG工具依赖依赖memory model准确度不依赖仿真验证即可从这个表能看出来RAM Sequential最大的优势是零硬件开销尤其是寄存器堆和微小的FIFO上BIST简直是大炮打蚊子。而RAM Sequential最大的短板是pattern体积和测试时间——所以生产测试中大RAM用BIST小RAM用RAM Sequential两者把覆盖率拼起来才是效率最高的组合。4. 一个混合测试方案实例时钟管理单元加四块SRAM的覆盖率突围4.1 项目背景和初始覆盖率瓶颈去年经手的一个老项目翻新版芯片规模不算大但内部结构挺典型一颗通过外部晶振输入、内部PLL产生四路分频时钟的SoC四块RAM——两块512x32的单端口SRAM一块256x16的双端口SRAM还有一块1Kx8的FIFO。没有Memory BIST。第一轮Basic Scan结果跑出来stuck-at总覆盖率89.7%transition coverage只有78.4%。项目TE只给了一句备注“覆盖率不达标请分析”后面的活儿全落在我们DFT团队头上。把ATPG报告里未覆盖故障按模块归拢之后原因很清楚时钟管理单元占了未覆盖故障的22%。PLL分频寄存器的部分输出、ICG使能逻辑、以及时钟MUX的select逻辑都是扫描可控但不可观测或者捕获时序上根本来不及。RAM相关逻辑占了未覆盖故障的31%。四块RAM的输入输出逻辑虽然接了扫描链但捕获窗口内的X态传播太严重工具在生成时直接放弃了一大片区域。这两个问题正好对应Clock PO和RAM Sequential两种模式。4.2 Clock PO和RAM Sequential的加入方式我们先处理时钟管理单元。设计里有一个测试模式信号test_mode拉高之后PLL输出和四路分频时钟都通过MUX切换到外部测试时钟。我的操作是在RTL里把四路分频时钟的输出节点引到一组测试观察引脚上——这组引脚平时不用只在测试pattern里被观察。在ATPG约束里把这四个节点分别声明为Clock PO并且注明四路时钟的相位关系。对于ICG单元不直接把它们全设为PO而是选择ICG输出端的时钟叶子点做PO——因为ICG使能端的故障会在时钟是否翻转上体现盯住叶子点就够了。RAM这边做RAM Sequential。因为容量都不大我决定对四块RAM全部做全地址遍历。FIFO因为是1K深度也做全地址。扫描链结构里RAM的地址、数据、写使能、读使能都接到了扫描单元上所以加载激励不需要额外硬件工具自动安排。约束上有一个细节RAM的输出在未初始化时是X为了避免X态污染扫描链我在RAM输出端加了一个扫描测试专用的bypass逻辑——测试模式下RAM输出被一个可控的MUX钳到固定值只有需要读比较的时候才把RAM的输出真正接到扫描链上。这个bypass逻辑不算大但对pattern可靠性提升非常明显。4.3 最终覆盖率、pattern体积和测试时间的实测数据改完约束重新跑结果如下指标仅Basic Scan增加Clock PO再增加RAM SequentialStuck-at覆盖率89.7%93.4%96.8%Transition覆盖率78.4%84.1%88.7%Pattern数量3,4123,9876,352ATE测试时间5MHz1.21s1.36s1.47s需要说明的是这个测试时间是在慢速shift频率下的估算不是at-speed。但趋势很清楚加入Clock PO之后覆盖率提升的性价比极高pattern只增加了不到600条RAM Sequential把pattern数量推高了将近60%但测试时间只增加了约8%——因为RAM这条路径不需要每条pattern都走完整的shiftunload很多RAM相关的激励周期数比较短整体上还是划算的。这次经验让我确认了一件事遇到覆盖率瓶颈时先看未覆盖故障都长在哪里再决定上哪种pattern模式而不是盲目堆pattern或者调压缩选项。工具压缩开得再高盲区还是盲区。5. 选型判断、高发故障与操作清单5.1 场景化的pattern类型选择表把三种模式放到一个表里平时做方案评审时直接对着查设计特征推荐pattern模式关键原因标准扫描逻辑占绝对主导Basic Scan效率最高pattern体积最小内部有PLL/分频时钟且需要验证Clock PO让内部时钟可观测、可控ICG门控时钟大量存在Clock PO Basic Scan覆盖ICG使能端和时钟叶子小容量SRAM/寄存器堆无BISTRAM Sequential零硬件成本覆盖RAM I/O逻辑大容量RAM建议补Memory BISTRAM Sequential会pattern爆炸双端口RAMRAM Sequential要校准模型两个端口时序窗口不同模拟/混合信号接口先插隔离逻辑再做Basic Scan消除X态源头组合使用的时候order也很关键。我的习惯是先跑Basic Scan基线把稳定覆盖率和未覆盖故障分布拿到手再用Clock PO去清理时钟相关的盲区最后才把RAM Sequential加进来。顺序反过来的话RAM带来的X态会污染前面所有的分析。5.2 高发故障排查从X态到仿真不匹配我在多个项目里总结过几类高频问题几乎每次和RAM Sequential打交道都会碰上X态从RAM传出来芯片仿真时RAM没有初始化直接跑pattern仿真结果里一片X。解决办法两个方向一种是在pattern最前面加一段初始化序列把目标RAM全部写成固定值另一种是用仿真工具的memory初始化命令在跑patttern之前在RAM模型里填入期望值。后者省pattern时间但生产ATE上用不上只能在验证环境里用。RAM Sequential的pattern在读周期的时序窗口偏窄工具按库模型给的读写建立保持时间去规划激励但实际后端的时钟树延迟偏大导致仿真里能过、板上跑挂。碰到这个情况优先看库模型的memory timing参数是不是被覆盖了而不是直接调pattern的频率。Clock PO和Basic Scan共享引脚导致冲突如果一个测试引脚既要当主输入又要当Clock PO的观察输出工具会报drive conflict。我的经验是尽量物理分开实在分不开就用MUX控制方向不同pattern段里切换。TDF pattern下Clock PO的期望值与仿真不匹配这个问题通常出在工具对时钟翻转沿的默认理解和实际设计不一致。解决方式是显式约束Clock PO的观测时刻别让工具自由发挥。5.3 给DFT工程师的落地清单最后说几条我自己的习惯不算标准答案但对新项目有一定参考价值项目一开始就做pattern类型规划不要等覆盖率报告出来才补。时钟生成模块、RAM模块、门控时钟密度这些在设计调研阶段就能看到。所有内部时钟的PO观测点尽量在RTL阶段就加好测试引脚。版图完成之后再想引出来走线成本会翻倍。对RAM Sequential的pattern量要提前估算。估算公式很简单地址深度 × 数据背景种类 × 读写序列步数乘以平均故障密度就是大致的pattern量。如果这个数量超过你测试时间预算的1/3就要考虑是不是该上BIST了。每一次新增pattern模式都要在仿真阶段完整跑一个回退验证别只在ATE上去赌。多花半天仿真能省下整个流片后debug的周期。工具报告里的unobservable不是终点它是一张地图。把未覆盖点按模块、按器件类型、按故障模型三个维度透视图导出来很快就能定位到是模式选型的问题还是网表约束的问题。做测试这行很多人容易陷入一个误区以为覆盖率上不去就是pattern数量不够于是拼命开压缩、加pattern结果只是把同一个盲区测了一百遍。其实换个pattern类型有时候比多跑一千条pattern管用得多。这篇文章提到的Clock PO和RAM Sequential就是我在实际项目里最常用的两把“备用钥匙”。无论你用的是TetraMAX还是Tessent只要理解它们各自在解决哪个层面的问题——时钟可观测还是存储可测试——很多看似刁钻的覆盖率数据都能对着光看出门道来。
阅读完成 · 觉得有帮助?