☰
DFT、OCC与ATPG协同:SOC流片前测试时序收敛的关键技术
2026/10/7 15:51:09 网站建设 项目流程

SOC流片前的DFT收敛,本质上是一场“测试时序”的博弈。我前后带过好几个量产项目,最深的体会就是:如果只是在RTL里插个扫描链、跑一遍ATPG就觉得完事,那后面等你的大概率是一连串的捕获窗口违例、过渡故障覆盖率不达标、ATE上fail乱飞。真正要把测试这块做稳,必须把DFT、OCC和ATPG这三件事放在同一条时间线上协同着设计。

这篇文章来自一个实际项目的复盘。芯片是典型的多时钟域SOC,内部有CPU簇、总线互联、各类外设IP,逻辑规模在千万门级。我们最终采用的是标准扫描加transition test的full-chip DFT方案,中间涉及OCC(On-Chip Clocking,片上时钟控制)的设计与验证,以及和ATPG(Automatic Test Pattern Generation,自动测试向量生成)流程的反复对齐。写出来主要是想帮两类人:一是做DFT、可测性设计或者芯片后端集成的工程师,二是刚接触测试还不明白“为什么非要OCC”的新人。全文按项目推进顺序组织,核心观点就一句话:OCC不是ATPG流程里的一个可选项,而是SOC能否实现高质量at-speed测试的地基。

1. 项目到底在解决什么问题:DFT、OCC、ATPG三者为什么会“打架”

1.1 从fault report倒推:DFT不只是“事后补救”

很多人把DFT理解成“给芯片插几根扫描链”,这其实窄了。DFT的全称是Design for Testability,它是一整套让芯片变得可测试、可诊断、可量产的设计方法。扫描链只是最基础的手段,真正复杂的是如何让扫描链在测试模式下按照想要的时序工作。

项目里我们吃过一次亏。早期版本在某个IP上只做了stuck-at测试,覆盖率虽然过了90%,但流片后跑过渡故障(transition delay fault)测试时fail率明显偏高。后来定位发现是数据路径上的长组合逻辑在功能频率下传播时间不够,而stuck-at测试根本测不出这种“速度”相关的缺陷。所以SOC量产测试必然要上at-speed测试,也就是在接近功能频率的时钟下捕获信号跳变。这时候问题就来了:扫描移位需要低速时钟,捕获需要高速时钟,两者之间谁来切换,切换得干不干净,这就是OCC的职责。

1.2 OCC:负责在测试模式中“切换时间尺度”

OCC本质上是一个位于功能时钟路径上的时钟控制模块,它接收来自PLL或其他时钟源的功能时钟,也接收低速测试时钟,然后根据测试控制信号决定输出哪个时钟、输出几个沿、什么时候停。最常见的用法是:扫描移相位用test_clk,SE信号拉低进入捕获相位后,OCC输出两个功能时钟沿,第一个沿叫launch,第二个沿叫capture,两个沿之间的时间间隔等于功能时钟周期,从而模拟真实工作频率下的数据传输。

没有OCC会出现什么情况?如果捕获还是用低速test_clk,过渡故障的检测窗口被拉长,很多在功能频率下会暴露的缺陷在低速下根本测不出来;如果直接用功能时钟做捕获,又没法准确控制脉冲数量,时钟一旦多跑了几个沿,捕获的数据就不是预期的状态,测试结果直接废。OCC就是那个“可控的闸门”,它保证在正确的时刻放出正确数量的高速沿。

1.3 ATPG:把故障变成一串0/1的调度器

ATPG工具做的事情可以概括为两件:一是基于网表和故障模型计算出能够检测故障的测试向量,二是把这些向量按照测试通道和扫描链的映射关系打包成可执行的pattern。在SOC芯片里,ATPG的输出通常包含stuck-at pattern和transition pattern两类。

transition pattern的生成逻辑和stuck-at完全不同。它需要先给定一个初始状态(launch),再观察一个相邻状态(capture),两个状态之间的信号变化必须跨越一个功能时钟周期。为了做到这一点,ATPG工具必须知道OCC在捕获阶段到底会输出几个时钟沿、第一个沿和第二个沿之间间隔多少时间,否则工具算出来的测试向量在硅片上执行时根本对不上时间窗口。这就是为什么OCC和ATPG必须协同:OCC是物理层的时间控制,ATPG是逻辑层的向量计算,两边对“什么时候launch、什么时候capture”的理解必须完全一致。

1.4 为什么必须“协同优化”

回到项目里,我们第一天写DFT plan时就把OCC、ATPG和DFT放到了一个大的约束体系里,而不是各自独立跑完再合。这么做的好处非常直接:时钟域的划分和OCC的插入位置在RTL阶段就确定,ATPG阶段才不会出现“这个域没有OCC导致transition无法测试”的尴尬;ATPG跑完后反馈的覆盖率数字又能反过来指导OCC是否需要调整。协同优化的本质是让“测试能力设计”和“测试向量生成”互相反馈,形成闭环。

如果拆开做,典型的失败路径是这样:DFT工程师插完OCC就交付,后端做时钟树时对OCC路径缺少额外约束,ATPG工程师拿到设计后跑覆盖率发现大量过渡故障测不到,回头排查发现是OCC的输出时钟在STA里没有被正确建模,最后只能通过禁掉一批路径换覆盖率,测试质量打了折扣。所以协同不是口号,而是要把OCC的约束条件同时渗透到DFT插桩、STA和ATPG三个流程里去。

2. OCC架构与ATPG配合关系的核心设计细节

2.1 一个典型OCC的内部逻辑拆解

我们项目里用的OCC是基于时钟门控单元加计数器的结构,逻辑并不复杂,但每个部件都不能省。最核心的部分包括三块:时钟选择MUX、捕获窗口计数器、同步与使能逻辑。

时钟选择MUX决定当前是输出test_clk还是func_clk。扫描移位阶段必须选test_clk,因为这个时钟来自测试引脚或者片上测试时钟源,速度低、相位可控;捕获阶段必须选func_clk,因为要模拟正常工作频率。MUX的切换不能让时钟毛刺落到寄存器上,所以需要一个比较讲究的切换窗口,通常是在SE稳定后再切换,而不是SE跳变的瞬间立刻切。

捕获窗口计数器用于控制输出多少个功能时钟沿。transition测试需要两个沿,stuck-at测试只需要一个沿,部分诊断场景需要更多沿,计数器的作用就是精确产生这些脉冲。实现时要注意,计数器本身也是时序电路,它的起始点应该以断言启动信号到达为准,而不是以PLL时钟的随机相位为准,否则会有亚稳态风险。我们加了一级两级同步器处理启动信号的跨时钟域问题,代价是多了几个触发器,但对稳定性帮助很大。

OCC输出还要过一道时钟门控,用专门的ICG单元而不是普通AND门来做,原因是ICG有内置的latch,可以保证时钟沿的完整性,普通组合逻辑门很容易在时钟高电平期间引入毛刺。这个细节在后端实现时经常被忽略,一旦OCC输出直接驱动扫描触发器组,毛刺就会导致扫描数据被错误捕获。

2.2 LOC和LOS:捕获策略到底选哪个

过渡故障测试有两种主流捕获策略:launch-on-capture(LOC)和launch-on-shift(LOS)。两者区别在于第一个launch沿的来源。

LOC模式是SE拉低后,由OCC输出的第一个功能时钟沿作为launch,第二个功能时钟沿作为capture,时序分布和功能模式接近,对后端实现友好,是SOC测试的主流选择。LOS模式是shift阶段的最后一拍时钟作为launch,捕获阶段只输出一个capture沿,优点是launch和capture之间的激励时间更短,更容易测出路径延迟缺陷,但它的时序模型和功能模式偏差较大,对扫描移位路径的hold time要求苛刻,后端收敛成本高。

对比项LOCLOS
launch沿来源捕获窗口第一个功能时钟沿扫描移位最后一个移位时钟沿
与功能时序接近度高低
OCC实现复杂度需要两个沿的精确控制只需要一个沿,OCC更简单
后端收敛难度相对低对hold要求极高
适用场景常规SOC多时钟域高速内核或少量IP的局部测试

我们的项目全部采用LOC。理由是SOC内部有大量跨时钟域路径和异步接口,LOC模式下的时序更贴近真实功能场景,ATPG工具对LOC路径的约束也更成熟。OCC在LOC模式下只需要保证从SE下降沿到第一个launch沿之间有一段可控间隔,以及两个沿之间的周期严格等于功能时钟周期,复杂度完全可控。

2.3 时钟域分组与跨域处理的协同

SOC芯片最麻烦的就是多个时钟域。我们的芯片有CPU集群使用的PLL时钟、外设总线的低频时钟、片上SRAM的独立时钟,还有部分纯异步逻辑。如果每一个时钟域都独立插入OCC,会带来很大的面积开销和时钟树压力;但如果合在一个OCC下管理,又无法保证不同频率时钟沿之间的同步关系。

我们采取的方案是“同频同相分组,异频异步隔离”。同频同相的时钟域共用一个OCC,ATPG工具把它们当作一个时钟组处理,transition pattern跨这些域的路径能正常覆盖。异频异步的域之间则用disable timing边界约束,在OCC和ATPG层面都不做跨域transition测试。跨域的路径如果确实存在,就把它们归到stuck-at或旁路测试,不给它们分配功能时钟捕获窗口。

这个分组决策要在项目早期定,最好是在DFT规划文档里把每个时钟域和OCC的映射关系明确画出来。后期改分组的成本非常高,因为OCC插入位置、时钟树约束、ATPG clock group定义全都跟着变。

2.4 给ATPG提供正确的时钟模型

ATPG工具本身不知道OCC是怎么工作的,它需要用户通过约束来告诉它哪些时钟是扫描移位时钟、哪些是捕获时钟、OCC输出在什么条件下有效。这个部分我们花了不少时间调试,核心是三组约束:时钟分组约束、OCC使能信号约束、测试模式定义。

时钟分组要做到同一OCC域内的时钟被识别为一个group,ATPG才会把它们当作同源时钟来计算捕获窗口。OCC使能信号要定义成测试可控制信号,这样ATPG才能在pattern里编排“拉低SE、启动OCC、输出两个捕获沿”的时序。测试模式定义要区分shift模式和capture模式,不同模式下时钟的mux选择不一样,约束不完整时ATPG会认为某些路径不可测。

有一次我们漏掉了某个IP内部OCC的使能信号约束,ATPG跑完transition覆盖率比预期低了十几个点,因为工具认定该IP域内所有捕获路径都无效。加上约束后覆盖率立刻回到正常水平。这个教训说明,OCC和ATPG的协同,重点不在工具本身,而在约束的完整性和一致。

3. SOC DFT OCC与ATPG协同的实操流程

3.1 DFT规划阶段:OCC数量和时钟域绑定

进入实操环节,第一步不是写代码,是先把测试策略文档做厚。我们的项目在RTL freeze之前就完成了DFT plan的初版,里面至少包含这几项:扫描链总条数和压缩比例、每个功能时钟域对应的OCC实例、OCC使用哪个PLL作为捕获时钟源、哪些路径不进入transition测试、pattern类型和覆盖率目标。

OCC数量并不是越多越好。我们的经验是,每个独立PLL输出域至少一个OCC,但对多个频率相近、相位可控的域尽量合并,这样可以减少时钟树上的OCC数量,也不用担心不同OCC之间的沿精度偏差。代价是合并后的域如果出现频率不匹配,ATPG就只能按最慢的域来定捕获周期,会削弱高频域的测试强度。所以这里是一个质量与面积的权衡,需要在项目例会里反复确认。

规划阶段还要确定每个OCC的PLL源和分频关系。ATPG计算launch-capture窗口时,默认使用PLL输出的功能时钟频率。如果深睡状态下PLL被关断,测试模式下要额外保证PLL处于有效状态,或者提供备用的测试时钟电路。这个在低功耗SOC里尤其重要,我们的芯片在实现时就把OCC的时钟源绑定到了常开的时钟网络,防止低功耗模式把关键时钟误关。

3.2 插OCC与DRC验证

规划完成后进入代码实现。我们用DFT编译器工具把扫描链插入和OCC实例化放在同一个flow里处理。OCC通常是独立RTL模块,预先写好参数化的时钟脉冲控制逻辑,在插桩时按规划例化到对应的时钟域边界。

插OCC并不是简单地把模块挂上时钟网络就结束,重点在DRC验证。工具会检查几个方面:OCC输入时钟是否来自合法的PLL或者测试时钟源,输出时钟是否覆盖了该域所有需要at-speed测试的寄存器,OCC的使能信号是否由测试控制器逻辑正确驱动,以及时钟切换时是否存在组合逻辑毛刺路径。任何一个问题不通过,都不能直接往后跑。

我们遇到最多的DRC问题是OCC输出时钟穿过了一层组合逻辑后才驱动扫描触发器,工具判定这不是合法的OCC输出负载,直接报错。解决方式是把OCC输出连接到后端专用的时钟树单元,或者把组合逻辑搬到OCC前面的选择分支里,确保OCC到触发器之间只有时钟树buffer。这类问题早期不清理,后端时钟树阶段代价翻倍。

3.3 约束、STA与SDC处理

OCC插入完成后,STA环节必须加入专门的约束。OCC路径上有几个典型的时序窗口需要验证:launch沿和capture沿之间的最小间隔、SE下降沿到launch沿的建立时间、capture沿之后OCC内部计数器恢复时间。这些约束在测试模式SDC里体现为test_clock和test_mode相关的设置。

我们在后端做时钟树综合时,给OCC的输入功能时钟路径做了0.5倍余量的setup约束。原因是OCC电路本身的门控逻辑会引入额外延时,如果时钟树综合阶段不给余量,流片后的Fmax会低于预期。实际项目中这个余量让我们避免了两次短期时序修不干净的问题,虽然代价是时钟树多插了一些buffer,但测试稳定性明显提升。

STA还要验证OCC模式下跨时钟域路径的异步约束。对不参与transition测试的跨域路径,在SDC里显式设置false path,并且要在ATPG的约束文件里同步disable,两边一旦不一致,后端时序和测试向量就会互相对不上。

3.4 从ATPG生成到动态仿真

ATPG阶段是把前面的协同设计兑现成最终pattern的地方。我们使用的流程是:读入带OCC和扫描结构的网表,指定故障模型为transition,设置时钟分组和OCC行为模型,然后跑向量生成。生成完后先看覆盖率报告,再逐条检查是否存在memory接口或者模拟宏的未知X状态干扰。

Pattern生成只是起点,真正的验证在动态仿真。我们会对生成的pattern做门级仿真,在网表路径上反标SDF延迟,模拟真实时序行为。仿真时重点观察OCC输出的时钟波形是否在预期的时间点产生两个功能沿,SE信号拉低后是否在OCC启动窗口内保持稳定。任何一个环节出现仿真与ATPG预期不一致,都要回到约束文件里排查。

动态仿真还会暴露X态传播问题。测试向量的初始状态来自扫描加载,但某些寄存器在测试模式下可能没有被完全初始化,仿真时会出现X。ATPG工具通常会通过仿真X处理机制在向量前后插入初始化序列,但如果OCC在某个域的使能信号也是X态,捕获时钟就可能不产生,导致覆盖率瞬间下降。

仿真通过后,pattern还要转换到ATE可用的格式,我们这边统一用WGL格式输出,再在机台上做电压和时钟频率的校准。这一步的细节和ATE资源强相关,但前面的协同设计如果做得好,得出的pattern在机台上基本不需要反复调试。

3.5 测试时间的量化估算与优化

协同优化最后要落到一个可以量化的指标:测试时间。测试时间直接关系到量产的芯片成本,而OCC和ATPG的协同设计能显著影响这个数字。

测试时间的粗略公式是:(pattern总数 × 单条pattern的移位周期数)+(捕获周期数)。频率一定时,影响时间的主要变量是扫描链长度和pattern数量。我们的芯片满规格扫描链长度约2000个扫描单元,移位时钟定在30MHz,单个transition pattern的移位周期数大约几千个,乘以数千条pattern之后,单颗芯片测试时间很容易突破几秒。

想要缩测试时间,可以通过提高压缩比、增加扫描通道、优化pattern顺序、降低重复覆盖率等办法。但这些优化和OCC设计有联动关系:压缩比提高后,单条链变长,OCC的捕获窗口还是按功能频率执行,不会改变捕获沿之间的时序,但捕获后数据搬运时间会变长。所以我们在设计阶段就把“压缩比、链数、测试时间、覆盖率”四个指标放在一起推演,宁可多花两周做权衡,也不在流片后再返工。

4. 实测过程中的问题实录与排查思路

4.1 过渡故障覆盖率为什么卡在70%上不去

项目进行到ATPG收敛阶段,transition覆盖率连续几天卡在70%,怎么加pattern都动不了。我们排查后定位到两个原因。

第一个原因是某个IP内部有一个低频使能信号,在功能模式下由软件配置寄存器控制,但测试模式下这个寄存器没有被扫描替代,导致该IP的OCC使能路径被截断,ATPG认为相关路径不可测。解决办法是把该寄存器纳入扫描链,并让OCC使能信号直接受测试控制器驱动,覆盖随即恢复。第二个原因是跨电源域的信号在测试时钟下存在较长的传输延迟,ATPG工具默认把它当功能路径处理,反而造成大量时序冲突。我们在SDC和ATPG约束里同时把这个路径设成异步,覆盖率立刻回到80%以上。

这类问题很隐蔽,因为报错信息不会直接说“OCC使能被截断”,而是显示一个又一个“unable to generate pattern”的条目。三个人的排查经验是:覆盖率上不去时,第一优先看OCC使能信号和禁测路径名清单,不要一开始就怀疑故障模型设置。

4.2 OCC识别失败:同样一个模块,DFT工具就是找不到时钟

另一个高频问题是工具识别不了OCC。现象是DRC报“no valid OCC clock”,但我们明明已经把OCC模块挂好了。查下来通常有两个原因:一是OCC的输入时钟名带上了功能时钟的分频信息,工具需要用户在dft配置里显式指出时钟树主节点;二是OCC的启动信号在工具视图里被识别成普通数据引脚,没有被定义成test control信号。

解决方式是回到dft_signal定义里,逐个核对OCC的时钟输入、启动输入、输出时钟三类引脚是否都正确声明。这个工作很琐碎,但是最值得提前做的。我们在新建一个IP的DFT约束时,会直接套用一套固定模板,再按IP差异修改,而不是每次从零开始写,避免漏定义导致的低级问题反复出现。

4.3 动态仿真里的X态和“仿真没有沿”

动态仿真阶段有段时间,仿真波形里OCC输出时钟在某些pattern里完全不动作,整个捕获窗口都是平的。我们最开始以为是RTL和网表不一致,后来发现是仿真激励里没把PLL输出建模成自由运行时钟,PLL的初始状态是X,OCC等待X信号根本没有启动。

解决办法是在pattern仿真的激励脚本里,把OCC依赖的PLL输出在初始化阶段显式置为有效值,不能依赖仿真器自动推断。类似的问题还出现在低功耗状态下,某些时钟自动门控单元在仿真初期把功能时钟关掉了,OCC自然拿不到时钟源。后来我们在测试激励模板里固定加一段“时钟初始化序列”,先把所有PLL和时钟门控打开,再执行OCC启动,问题基本清零。

4.4 后端时序和功耗的反复拉锯

后端做时钟树时,OCC路径是最容易引起时序超额的区域。因为OCC的输入是功能时钟,输出又直接驱动大片扫描寄存器,时钟树的负载和分支数量都很大。我们遇到过一次OCC路径的hold违例,原因是OCC输出的时钟树和捕获寄存器之间的偏移过大,修复方式是在OCC后端加了多级平衡buffer,同时调整了扫描寄存器的布局密度,让OCC的输出负载尽量均匀分布。

功耗方面,OCC在测试模式下的功能时钟会以capture频率开关,测试功耗常常比功能模式高一大截。我们测试时发现动态仿真中某域瞬时功耗接近功能模式上限,为了压低它,把测试捕获频率从原来的最高PLL频率降到了0.7倍PLL频率,虽然对缺陷检测的灵敏度有一点影响,但避免了ATE上的供电风险。这是典型的协同优化取舍:测试质量和功耗约束之间没有绝对最优,只有项目约束下的平衡。

5. 工具链选型、工程落地与个人体会

5.1 我们实际使用的工具链组合

项目里DFT插入和ATPG用的是不同的工具组合,原因是它们在OCC处理方式上各有特点。前端DFT插桩和压缩用Synopsys的DFT Compiler,ATPG用TetraMAX,后端时序分析用PrimeTime。这套组合在标准scan和transition测试上非常成熟,OCC的库单元模型支持也比较完整。

另一条值得研究的路线是Siemens的Tessent系列,它在OSC信号级时钟控制和高压缩比scan压缩上做得比传统流程灵活,尤其适合多时钟域和层次化实现的项目。我们评估过Tessent,但最终因为团队对Synopsys的flow更熟,切换成本高,没有换。选型建议是:团队原有skill set最重要,工具本身功能差异在大多数项目里都能通过约束补齐,熟练度才是真正的瓶颈。

5.2 约束文件一致性是这个项目最大的工程难点

协同优化光靠工具跑流程不够,还要有一套能贯穿DFT、STA、ATPG三端的约束体系。我们在项目里维护了一份统一的测试时钟树配置文档,里面记录每个OCC实例的时钟源、使能信号、输出时钟名、测试模式定义。任何一个环节改了OCC相关的约束,文件同步更新,并且有专门的脚本做三个工具之间的一致性检查。

这份文档在项目中期发挥了很大作用。有一次后端工程师为了优化时序调整了OCC输入路径上的一个buf尺寸,如果只改SDC不通知ATPG,ATPG里不会感知这个变化,覆盖率报告看着没问题,但流片后测试时序可能出现细微偏差。有了统一配置和自动检查,这类问题的风险被提前拦截。

5.3 团队协作建议:把DFT当“一等公民”

项目里最聪明的一个决定,是把DFT工程师安排到了综合环境建设的初期评审里,而不是等综合脚本跑完再加入。这样前端designer在选时钟方案时会主动考虑测试可行性,后端在解决时序问题时也会把DFT模式的时序作为一个独立signoff项目,而不是总当成“附加项”处理。

跨团队开会时,我会跟大家强调一个概念:DFT不再只是加几条链,而是从时钟规划开始就要考虑OCC的物理实现和ATPG的时序边界。谁提方案谁负责把约束同步给下游,不让任何信息停留在口头层面。这在多人协作的SOC项目里效果非常明显。

5.4 最后再分享一个小技巧

项目尾声调试ATE pattern时,花了很多时间对比TetraMAX仿真波形和机台波形。后来发现在TetraMAX里开启pattern compression并写入仿真时间戳信息,能直接在ATE上快速定位第一次fail的pattern序号,不用整条向量切成几万段逐段查。这个参数在项目初期容易被忽略,但对量产调试效率帮助巨大。做SOC DFT流片验证的朋友,建议在流程初期就把这个选项打开,能省下后面几天熬夜时间。

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

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

立即咨询