ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Tessent MBIST SDC约束实战:从时钟架构到STA收敛的避坑指南

2026/10/7 1:09:26 拓冰建站 浏览量
Tessent MBIST SDC约束实战:从时钟架构到STA收敛的避坑指南 1. 从一次流片前的时序惊魂说起如果你正在做DFTDesign for Test相关的后端或验证工作看到“Tessent MBIST SDC”这几个词大概率是遇到了下面这个场景芯片功能逻辑的时序已经收敛得差不多了结果一跑MBISTMemory Built-In Self-Test存储器内建自测试的时序满屏的setup/hold violation或者更隐蔽的——功能模式下没问题一切到MBIST测试模式时钟路径就崩了。我见过不止一个项目在tapeout前两周才发现MBIST的SDC约束根本没写对最后靠加班加点重新约束、重新跑STA才勉强赶上进度。这篇文章就是围绕Tessent MBIST SDC这个主题把MBIST测试模式下的SDC约束到底该怎么写、为什么这么写、哪些地方最容易踩坑从头到尾讲清楚。适合正在用Tessent工具做MBIST插入的DFT工程师、负责测试模式时序收敛的后端工程师以及需要理解MBIST时钟架构的验证人员。不管你是刚接触MBIST约束的新手还是已经写过几轮SDC但总觉得哪里不对的老手下面这些内容应该都能帮你省下不少debug时间。核心关键词先摆出来Tessent是业界主流的DFT工具套件MBIST是存储器自测试的行业标准方法SDCSynopsys Design Constraints则是时序约束的通用语言。三者交汇的地方就是MBIST测试模式下的时序约束——一个看起来简单、实际上暗坑无数的领域。2. MBIST测试模式的时钟架构与约束逻辑2.1 为什么MBIST需要独立的SDC约束功能模式下的SDC约束描述的是芯片在正常工作时的时序关系时钟频率、输入输出延迟、时钟域交叉、多周期路径等等。但MBIST测试模式完全是另一套游戏规则。测试模式下芯片的时钟往往来自ATE自动测试设备直接灌入的慢速时钟PLL可能被旁路功能时钟可能被mux掉取而代之的是测试时钟。更关键的是MBIST控制器会生成自己的时钟和地址信号去访问memory这些路径在功能模式下根本不存在。所以功能SDC直接套用到MBIST模式必然出问题。要么是约束过紧——把本来不需要满足功能频率的测试路径约束到了功能频率导致大量假violation要么是约束过松——该检查的测试路径没检查到硅片上跑MBIST的时候直接fail。这两种情况我都遇到过前者浪费大量时间在假问题上后者更危险可能直接导致芯片报废。Tessent工具在插入MBIST逻辑的时候会生成一套测试模式下的时钟架构。这套架构的核心是MBIST控制器时钟、memory时钟、扫描链时钟以及它们之间的切换逻辑。SDC约束要做的就是准确描述这套架构下的时序关系。2.2 MBIST时钟域的三个层次理解MBIST的SDC约束首先要理解它的时钟域层次。我把它分为三层第一层是测试时钟源。这是从芯片外部ATE直接灌入的时钟通常频率很低比如10MHz到50MHz。这个时钟在SDC里要定义为create_clock周期根据实际测试频率来设。注意这个时钟的端口通常是功能复用的所以要用set_case_analysis或者模式选择信号来区分。第二层是MBIST控制器时钟。Tessent插入的MBIST控制器通常有自己的时钟域这个时钟可能直接来自测试时钟源也可能经过一个分频器。如果是分频器产生的SDC里要用create_generated_clock来描述并且要正确设置分频比。第三层是memory接口时钟。这是MBIST控制器输出到memory的时钟通常和控制器时钟同源但可能经过时钟门控或者mux。这一层的约束最容易出问题因为memory的时序要求setup/hold在测试模式下和功能模式下可能不同。这三层时钟域之间的关系决定了SDC约束的基本框架。我通常的做法是先画出MBIST模式的时钟架构图标注每个时钟的来源、频率、分频关系然后再写约束。这一步看起来费时间但能避免后面大量的返工。2.3 模式选择与case analysis的设置MBIST测试模式和功能模式的切换通常通过一个或多个模式选择信号来控制。在SDC里必须用set_case_analysis把这些信号固定到测试模式的值否则STA工具会同时分析两种模式导致约束冲突。具体操作上假设有一个test_mode信号高电平表示MBIST模式那么SDC里要写set_case_analysis 1 [get_ports test_mode]如果还有更细的模式选择比如mbist_en、scan_en等也要一并设置。这里有个坑set_case_analysis的顺序和优先级。如果多个模式信号之间有依赖关系比如test_mode为1时mbist_en才有效那么要确保case analysis的设置顺序正确或者用-set_case_analysis的优先级选项。另外有些设计会用锁存器或者寄存器来存储模式选择信号这种情况下不能直接对端口做case analysis而要对寄存器的输出做。我遇到过一种情况模式选择信号经过了一个同步器SDC里对端口做了case analysis但同步器后面的信号没有被正确传播导致STA分析的是错误模式。解决办法是用set_case_analysis配合set_disable_timing或者直接在同步器输出上做case analysis。注意set_case_analysis会影响整个时序分析包括功能路径和测试路径。如果设计中有部分逻辑在MBIST模式下仍然需要保持功能行为要特别小心避免误约束。3. Tessent MBIST SDC的核心约束逐条拆解3.1 时钟定义create_clock与create_generated_clockMBIST模式下的时钟定义是SDC约束的起点。Tessent工具在插入MBIST逻辑时会生成一个时钟定义文件通常叫mbist_clock.sdc或者类似名字里面包含了基本的时钟定义。但这个文件往往需要根据实际设计进行修改和补充。对于测试时钟源典型的定义是create_clock -name test_clk -period 100 [get_ports test_clk]周期100ns对应10MHz这是ATE常用的测试频率。如果测试时钟经过PLL或者分频器要用create_generated_clockcreate_generated_clock -name mbist_clk -source [get_ports test_clk] \ -divide_by 2 [get_pins u_div/clk_out]这里的关键是**-source要指向正确的源时钟**-divide_by要跟实际分频比一致。我见过有人把-source指向了功能时钟结果生成的时钟波形完全不对STA结果自然也是错的。对于memory接口时钟如果经过了时钟门控要用create_generated_clock配合-combinational或者-edge_shift来描述。时钟门控在MBIST模式下通常是常开的所以可以用set_case_analysis把门控使能信号固定为有效值然后直接传播时钟。3.2 时钟分组与异步关系MBIST模式下通常有多个时钟域测试时钟域、MBIST控制器时钟域、memory时钟域可能还有扫描链时钟域。这些时钟域之间如果是异步的要用set_clock_groups声明set_clock_groups -asynchronous \ -group {test_clk} \ -group {mbist_clk} \ -group {scan_clk}这一步非常重要因为如果不声明异步关系STA工具会默认检查跨时钟域的时序路径产生大量无意义的violation。但要注意不是所有跨时钟域路径都是异步的。比如MBIST控制器到memory的路径虽然时钟名字不同但可能是同源的这种情况下不能设为异步而要检查实际的时序关系。我通常的做法是先列出所有时钟域然后逐一确认它们之间的相位关系。同源的、有确定相位关系的不设异步真正异步的才设clock groups。这个判断过程需要结合时钟架构图来做不能拍脑袋。3.3 输入输出延迟与驱动强度MBIST模式下ATE直接驱动芯片的测试端口所以输入延迟和输出延迟的设置跟功能模式不同。典型的设置是set_input_delay -clock test_clk -max 5 [get_ports mbist_data_in*] set_input_delay -clock test_clk -min 2 [get_ports mbist_data_in*] set_output_delay -clock test_clk -max 5 [get_ports mbist_data_out*] set_output_delay -clock test_clk -min 2 [get_ports mbist_data_out*]这些值要根据ATE的实际时序参数来定。如果不知道具体值可以先设一个保守的估计比如周期的20%到30%然后在后续分析中调整。驱动强度方面ATE的驱动能力通常比芯片内部的驱动器弱所以要用set_driving_cell或者set_input_transition来模拟set_driving_cell -lib_cell BUFFD4 -pin Z [get_ports mbist_data_in*]或者更简单的方式set_input_transition 1.0 [get_ports mbist_data_in*]这里有个经验输入转换时间不要设得太乐观。我见过有人设0.1ns结果STA过了硅片上却因为信号边沿太慢导致setup violation。保守一点设0.5ns到1.0ns比较稳妥。3.4 多周期路径与false pathMBIST模式下很多路径不需要在一个时钟周期内完成。比如MBIST控制器的配置寄存器写入可能只需要在测试开始前完成一次不需要每个周期都检查。这种情况下要用set_multicycle_pathset_multicycle_path -setup 10 -from [get_pins u_mbist/config_reg*] \ -to [get_pins u_mbist/ctrl_reg*] set_multicycle_path -hold 9 -from [get_pins u_mbist/config_reg*] \ -to [get_pins u_mbist/ctrl_reg*]注意setup和hold的配合setup设Nhold通常设N-1。如果只设setup不设holdhold检查会默认在同一个周期可能导致hold violation。false path的使用要更谨慎。只有确认某条路径在MBIST模式下完全不需要检查时才设false path。比如一些功能模式下的调试逻辑在MBIST模式下被完全旁路可以设false path。但如果不确定宁可先不设等STA报出来再分析。提示set_multicycle_path和set_false_path都是强约束会覆盖默认的时序检查。使用前最好先用report_timing确认路径的实际需求避免过度约束或约束不足。3.5 时钟不确定性uncertainty与latencyMBIST模式下的时钟不确定性主要来自ATE的时钟抖动和芯片内部的时钟树偏差。典型的设置是set_clock_uncertainty -setup 0.5 [get_clocks test_clk] set_clock_uncertainty -hold 0.3 [get_clocks test_clk]这些值要根据ATE的规格和时钟树综合的结果来定。如果时钟树还没综合可以先设一个估计值比如周期的5%到10%。时钟latency方面MBIST模式下通常不需要设source latency因为时钟从ATE直接灌入没有片上的时钟生成电路。但如果有PLL或者分频器要设generated clock的latency。4. 实操流程从Tessent输出到STA收敛4.1 Tessent MBIST插入后的文件清单Tessent工具在完成MBIST插入后会生成一系列文件。跟SDC相关的主要有mbist_clock.sdc基本的时钟定义包括测试时钟和生成的时钟。mbist_mode.sdc模式选择信号的case analysis设置。mbist_path.sdcMBIST相关路径的约束包括multicycle和false path。mbist_interface.sdcmemory接口的时序约束。这些文件通常需要合并到顶层的SDC中。合并的顺序很重要先读功能SDC再读MBIST SDC确保MBIST的约束覆盖功能约束。如果顺序反了功能约束可能会覆盖MBIST约束导致测试模式下的时序检查不正确。我通常的做法是创建一个顶层的MBIST模式SDC文件用include的方式把Tessent生成的文件和手写的补充约束整合在一起# mbist_mode_top.sdc set_case_analysis 1 [get_ports test_mode] source ./mbist_clock.sdc source ./mbist_mode.sdc source ./mbist_path.sdc source ./mbist_interface.sdc # 手写补充约束 set_clock_groups -asynchronous -group {test_clk} -group {scan_clk} set_input_delay -clock test_clk -max 5 [get_ports mbist_data_in*]4.2 约束检查与调试步骤写完SDC后不要急着跑完整的STA。先做几步检查第一步检查时钟定义。用report_clocks确认所有时钟都被正确定义频率、波形、分频关系都对。第二步检查case analysis。用report_case_analysis确认模式选择信号被正确固定没有冲突或遗漏。第三步检查时钟分组。用report_clock_groups确认异步关系设置正确没有把同源时钟误设为异步。第四步跑一次快速的时序分析。用check_timing和report_timing_requirements检查约束的完整性看看有没有未约束的路径或者冲突的约束。第五步分析violation。如果有时序violation先用report_timing -path_type full_clock_expanded看详细的路径信息确认是真实的violation还是约束问题。这个流程我跑过很多次最花时间的通常是第五步。因为MBIST的violation往往不是单纯的时序问题而是约束本身有问题。比如时钟定义错了、case analysis没设对、异步关系没声明都会导致假violation。4.3 一个真实的调试案例去年做一个28nm的项目MBIST模式下的STA一直报setup violation路径是从MBIST控制器到memory的数据线。功能模式下这条路径没问题MBIST模式下却差了0.3ns。我先检查了时钟定义发现MBIST控制器的时钟和memory的时钟虽然名字不同但实际上是同源的都来自测试时钟经过一个分频器。但SDC里把它们设成了异步时钟组导致STA没有检查它们之间的时序关系而是用了一个默认的时序检查结果就报了violation。解决办法是把这两个时钟从异步组里拿出来用create_generated_clock重新定义它们的关系确保STA知道它们是同源的。改完之后violation消失了因为实际的时序关系是满足的。这个案例的教训是不要想当然地设异步时钟组。每设一个异步关系都要确认这两个时钟真的是异步的。同源的时钟即使频率不同也要用generated clock来描述它们的关系。4.4 与功能SDC的共存策略MBIST SDC和功能SDC的共存是另一个容易出问题的地方。因为两种模式的约束可能冲突比如同一个端口在功能模式下有input delay在MBIST模式下也有input delay但值不同。处理策略有两种策略一分文件、分模式。功能SDC和MBIST SDC分别放在不同的文件里用不同的模式选择信号来区分。跑STA时根据分析的模式读对应的SDC。这种策略的优点是清晰缺点是如果两种模式有共享的约束需要重复写。策略二单文件、条件约束。在一个SDC文件里用if-else或者条件语句来区分模式。比如if {$mode mbist} { set_input_delay -clock test_clk -max 5 [get_ports data_in*] } else { set_input_delay -clock func_clk -max 2 [get_ports data_in*] }这种策略的优点是约束集中缺点是文件复杂容易出错。我个人的偏好是策略一因为DFT模式和功能模式的时序分析通常是分开跑的分文件更清晰也更容易维护。但不管用哪种策略都要确保两种模式的约束不会互相干扰。5. 常见问题与排查技巧实录5.1 MBIST SDC常见问题速查表问题现象可能原因排查方法解决方案大量setup violation集中在memory接口时钟定义错误或异步关系误设report_clocks确认时钟关系修正create_generated_clock或clock_groupshold violation在测试模式下出现时钟不确定性设置过小report_clock_uncertainty增大hold uncertainty某些路径没有被检查false path或multicycle设置过度report_timing_requirements移除不必要的false path模式切换后约束冲突case analysis设置错误report_case_analysis修正case analysis顺序或值输入输出延迟不匹配ATE时序参数估计错误对比ATE规格和SDC设置根据实测调整delay值时钟门控路径报violation门控使能信号未固定report_case_analysis用set_case_analysis固定门控使能5.2 独家避坑技巧技巧一先跑功能模式再跑MBIST模式。不要一上来就跑MBIST的STA。先用功能SDC跑一遍确认功能时序没问题然后再切换到MBIST模式。这样可以排除功能约束的干扰更容易定位MBIST特有的问题。技巧二用report_clock_networks检查时钟传播。这个命令可以显示时钟从源到终点的完整传播路径包括经过的mux、分频器、门控。如果时钟传播路径和预期不符说明时钟定义有问题。技巧三对MBIST控制器的配置寄存器设multicycle。MBIST控制器的配置寄存器通常在测试开始前写入一次不需要每个周期都检查。设一个较大的multicycle比如100可以避免不必要的violation。技巧四memory接口的时序约束要参考memory的datasheet。不同memory的setup/hold要求不同不能一概而论。Tessent生成的约束通常是保守的但最好根据实际memory的规格调整。技巧五保留一份约束的版本记录。MBIST SDC经常需要反复调整每次调整都可能影响其他路径。保留版本记录方便回溯和对比。5.3 与Tessent工具的配合要点Tessent工具在生成MBIST逻辑时会同时生成一些约束模板。但这些模板往往需要根据实际设计修改。我通常的做法是先用Tessent生成的模板跑一遍STA看看有哪些violation。分析violation的原因判断是约束问题还是真实的时序问题。如果是约束问题修改SDC如果是真实的时序问题反馈给前端或后端调整设计。重复这个过程直到STA收敛。Tessent还提供了一些命令来辅助约束生成比如report_mbist_clock和report_mbist_path。这些命令可以输出MBIST相关的时钟和路径信息帮助确认约束的正确性。注意Tessent生成的约束模板可能不包含所有需要的约束特别是时钟分组和输入输出延迟。这些需要手动补充。5.4 跨时钟域路径的处理MBIST模式下跨时钟域路径的处理是个难点。因为MBIST控制器和memory可能在不同的时钟域但它们之间的数据交换又需要检查时序。处理原则是同源的跨时钟域路径要检查异步的跨时钟域路径要设false path或clock groups。判断同源还是异步要看时钟的源头。如果两个时钟都来自同一个测试时钟只是经过了不同的分频器那么它们是同源的有确定的相位关系需要检查时序。如果两个时钟来自完全独立的源比如一个来自ATE一个来自片上的PLL那么它们是异步的不需要检查时序。对于同源的跨时钟域路径要用create_generated_clock正确定义时钟关系然后用set_clock_groups -logically_exclusive或者-physically_exclusive来声明它们不能同时有效如果确实如此。6. 从约束到硅片MBIST SDC的验证与签核6.1 形式验证与动态仿真SDC写完后不能只靠STA来验证。形式验证和动态仿真是必要的补充。形式验证方面可以用CDCClock Domain Crossing检查工具来验证时钟域交叉的正确性。这些工具可以检查是否有未同步的跨时钟域路径以及同步器的正确性。动态仿真方面可以跑MBIST的测试向量在仿真中检查时序。虽然仿真的时序精度不如STA但可以发现一些STA覆盖不到的问题比如复位序列、模式切换的时序等。我通常的做法是STA收敛后跑一遍MBIST的仿真确认功能正确。如果仿真中发现时序问题再回头检查SDC。6.2 硅片测试的反馈MBIST SDC的最终验证是硅片测试。如果硅片上MBIST测试通过说明约束基本正确。如果失败需要分析是约束问题还是设计问题。硅片测试失败时首先要确认测试条件是否和SDC中的假设一致。比如ATE的实际时钟频率、输入延迟、输出延迟是否和SDC中设置的一样。如果不一样要调整SDC重新分析。其次要确认MBIST的测试算法和SDC中的约束是否匹配。不同的MBIST算法如March C-、March SS等对时序的要求可能不同。如果算法变了约束也要相应调整。6.3 签核清单在tapeout前MBIST SDC的签核清单包括所有时钟都被正确定义包括测试时钟、生成时钟、门控时钟。所有模式选择信号都被正确设置case analysis。所有异步时钟域都被正确声明clock groups。所有输入输出延迟都根据ATE规格设置。所有multicycle和false path都有明确的理由和文档记录。STA在MBIST模式下收敛没有未解释的violation。形式验证和动态仿真通过。约束文件有版本记录和变更日志。这个清单看起来简单但每一条都需要仔细确认。我见过太多项目因为漏了其中一条导致硅片上出问题。6.4 个人经验体会做了这么多年DFT和时序约束我最大的体会是MBIST SDC不是写完就完事的它是一个需要反复迭代和验证的过程。从Tessent生成模板到手动补充约束到STA收敛到仿真验证到硅片测试每一步都可能发现问题每一步都需要回头调整。另一个体会是不要怕麻烦该画的图要画该记的文档要记。MBIST的时钟架构往往比较复杂光靠脑子记容易出错。画一张清晰的时钟架构图标注每个时钟的来源、频率、分频关系写约束的时候对照着看能避免很多低级错误。最后分享一个小技巧如果STA报的violation太多不知道从哪下手可以先按时钟域分组看看violation集中在哪个时钟域。通常问题最大的那个时钟域就是约束最可能出错的地方。从那里开始排查效率会高很多。MBIST SDC这个领域说难不难说简单也不简单。关键是要理解MBIST的时钟架构理解SDC的约束语义然后耐心地一步步调试。希望这篇文章能帮你少走一些弯路顺利搞定MBIST的时序收敛。