ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Tessent ATPG中Test Procedure与Dofile协同原理

Tessent ATPG中Test Procedure与Dofile协同原理 1. 这不是“写脚本”而是给芯片上保险——Tessent ATPG里Test Procedure和Dofile到底在管什么你拿到一份Tessent ATPG的交付包打开log一看满屏飘红[drc rtstat-6] partial route conflicts: 1184 net(s) have a partial conflict.。不是Vivado报错也不是KLayout跑DRC时的物理验证失败——这是Tessent在生成测试向量前用内部规则引擎对测试逻辑结构做静态检查时亮起的红灯。它不告诉你哪条net连错了只冷冷甩出一句“partial conflict”然后中断ATPG流程。我第一次遇到这问题时在Synopsys支持工单里写了三页现象描述对方回了一句“请检查你的Test Procedure中scan chain stitching的clock domain声明是否与Dofile中set_clock_groups的约束一致。”——那一刻我才意识到Tessent里的Test Procedure和Dofile根本不是两份独立配置文件而是一套精密咬合的齿轮组一个齿歪了整个测试生成链就卡死。Test Procedure不是测试步骤说明书它是Tessent ATPG引擎的“作战地图”定义哪些flip-flop属于哪条scan chain、每条chain的输入/输出端口映射到哪个顶层pin、clock如何采样capture phase、reset如何同步释放、bypass logic如何介入……它用TCL语法写成但本质是硬件行为建模。Dofile则是这张地图的“气象预报系统”它不参与链路连接却决定Test Procedure中所有时序声明能否被ATPG引擎可信地解析——比如set_clock_groups -asynchronous -group [get_clocks clk_a] -group [get_clocks clk_b]这一行表面看只是告诉工具“这两个clock不相关”实则强制ATPG在生成test pattern时彻底隔离两条scan chain的时序传播路径。一旦Dofile里漏掉某组clock的异步声明Test Procedure中哪怕逻辑完全正确ATPG也会在DRC检查阶段报出rtstat-6——因为它发现在某个capture cycle里clk_a驱动的scan cell数据竟试图通过未声明异步关系的clk_b路径被采样这违反了数字电路最基本的时序隔离原则。所以这不是配置错误而是测试意图与物理约束的语义断裂。新手常把Test Procedure当“填空题”照着chip top-level pin list填scan_in/scan_out把Dofile当“抄作业”从别人项目里复制粘贴clock group设置。结果就是DRC报错像幽灵一样反复出现每次改一行下一次换一个net报冲突。真正有效的解法是从RTL网表出发逆向推导出scan chain物理拓扑再用Test Procedure精确描述这个拓扑最后用Dofile为这个拓扑的每一个时序边界打上不可逾越的隔离标记。这过程没有捷径但有可复现的路径——接下来我会拆解每一步怎么走、为什么这么走、踩过哪些坑。2. Test Procedure设计从RTL网表反推scan chain物理结构而不是凭空填写2.1 为什么必须从RTL网表开始——ATPG引擎只认“物理存在”的chain很多工程师习惯直接打开Test Procedure模板对着芯片spec填set_scan_chain_name,set_scan_chain_length,set_scan_in_port……这种做法在简单单时钟设计里可能蒙混过关但一旦遇到多时钟域、clock gating、hierarchical scan insertion就会在DRC阶段暴雷。原因在于Tessent ATPG的DRC检查尤其是rtstat系列不是校验语法而是做物理一致性验证——它会把Test Procedure中声明的scan chain结构与实际RTL网表中由scan insertion工具如DFT Compiler生成的物理连接做逐级比对。举个真实案例某SoC项目中Test Procedure声明了一条长度为256的scan chain输入端口叫scan_in_0输出端口叫scan_out_0。但DRC报错rtstat-6指向1184个net定位后发现实际RTL网表里这条chain被clock gating cell切成了3段物理上断开的子链因为clock gating在scan shift phase被bypass但在capture phase启用而Test Procedure仍把它当作一条连续chain描述。ATPG引擎在做partial route检查时发现子链之间的连接点即clock gating output在capture cycle里既没被clock驱动也没被reset控制形成“悬空节点”于是判定为partial conflict。所以第一步永远是从RTL网表出发反向提取scan chain物理结构。具体操作分三步确认scan insertion工具版本与输出格式不同版本DFT Compiler生成的scan netlist命名规则不同。例如v2020.03之后默认启用-use_dft_signal_names会把scan chain port命名为scan_in_dft_0而非scan_in_0而v2018.09则用scan_in_0。若Test Procedure中port name与网表实际name不一致ATPG在读取时会静默忽略该chain声明导致后续DRC检查时发现“声明的chain不存在”进而误判为partial route conflict。用Tessent自带工具提取物理chain topology不要手动数FF。执行read_netlist -format verilog top.v后运行set_chain_list [get_scan_chains] foreach chain $chain_list { puts Chain: $chain, Length: [get_attribute $chain length] puts Input port: [get_attribute $chain scan_in_port] puts Output port: [get_attribute $chain scan_out_port] # 关键获取物理连接路径 set path_nodes [get_scan_chain_path $chain] foreach node $path_nodes { puts Node: [get_attribute $node name], Type: [get_attribute $node type] } }这段TCL会输出每条chain的真实物理节点序列。注意get_scan_chain_path返回的不是逻辑顺序而是RTL网表中信号线的实际连接路径——如果某处出现type clock_gating_cell就意味着此处chain物理断开Test Procedure中必须声明为多条独立chain。验证clock domain归属对每个scan cell执行get_attribute [get_cells -of $cell] clock_domain。Tessent会根据RTL中clock net的fanout自动推导domain但若存在clock mux或glitch filter推导可能出错。此时必须人工核对打开RTL schematic找到该cell的clock pin连接的net追溯其源头clock generator确认是否与Test Procedure中set_scan_chain_clock声明一致。不一致会导致ATPG在capture phase采样时误将跨domain的scan cell数据混入同一cycle触发rtstat-6。提示get_scan_chain_path输出的node列表里若出现type tie_high或type tie_low说明该位置存在scan bypass logic如test mode control signal插入点。Test Procedure中必须用set_scan_chain_bypass_point显式声明否则ATPG会认为此处信号路径异常纳入partial route检查范围。2.2 Test Procedure核心参数的物理意义与填写陷阱Test Procedure中看似简单的参数背后都对应着RTL网表中的物理实体。填错一个DRC就报错。以下是高频踩坑点set_scan_chain_clock不是指定“用哪个clock”而是声明“该chain所有scan cell的capture phase由哪个clock net驱动”。必须与RTL网表中该chain末尾scan cell的clock pin连接的net name完全一致区分大小写。曾有个项目因clock net在综合后被rename为clk_core_div2而Test Procedure仍写clk_core导致ATPG在DRC检查时发现capture cycle里部分cell clock为clk_core_div2部分为clk_core判定为clock domain mixing报rtstat-2比rtstat-6更早触发。set_scan_chain_reset这里填的reset port name必须是RTL网表中该chain所有scan cell共用的async reset pin连接的top-level port。若某条chain中部分cell用rst_n部分用rst_core_nTest Procedure只能声明一个reset port此时必须在Dofile中用set_false_path -from [get_pins rst_n] -to [get_cells *]等约束屏蔽非共用reset路径否则DRC会报reset assertion conflict。set_scan_chain_stitching这是DRC报错重灾区。语法为set_scan_chain_stitching -from src_chain -to dst_chain -input_port port -output_port port。关键陷阱在于-input_port和-output_port必须是物理上直连的两个port。例如chainA的scan_out通过buffer后连接chainB的scan_in那么-input_port应填buffer的input port name如I-output_port填buffer的output port name如Z而不是chainA的scan_out和chainB的scan_in。因为ATPG DRC检查的是netlist中实际连线而非逻辑意图。set_scan_chain_bypass当chain中存在test mode multiplexer时必须用此命令声明bypass point。参数-control_pin填mux的select pin在RTL网表中的完整hierarchy path如top/u_dut/u_ctrl/mux_sel-data_in填mux data input port如din-data_out填mux data output port如dout。漏填或path错误会导致ATPG在shift phase无法正确绕过muxDRC检查时发现mux output net在shift cycle无驱动报partial conflict。2.3 多时钟域scan chain的Test Procedure写法——以双域CPU core为例假设一个CPU core有两条scan chaincpu_scan_0clocked byclk_cpu和dbg_scan_0clocked byclk_dbg且二者在debug模块内有数据交互。Test Procedure不能简单写两段独立声明必须体现domain边界# 声明cpu domain chain set_scan_chain_name cpu_scan_0 set_scan_chain_length 128 set_scan_chain_clock clk_cpu set_scan_chain_reset rst_n set_scan_chain_in_port scan_in_cpu set_scan_chain_out_port scan_out_cpu # 声明dbg domain chain set_scan_chain_name dbg_scan_0 set_scan_chain_length 64 set_scan_chain_clock clk_dbg set_scan_chain_reset rst_n set_scan_chain_in_port scan_in_dbg set_scan_chain_out_port scan_out_dbg # 关键声明跨domain stitching # 注意stitching必须发生在两个domain的boundary cell之间 set_scan_chain_stitching -from cpu_scan_0 -to dbg_scan_0 \ -input_port u_dbg/cpu_to_dbg_data \ -output_port u_dbg/dbg_from_cpu_data这里u_dbg/cpu_to_dbg_data和u_dbg/dbg_from_cpu_data是RTL网表中debug模块内两个cross-clock-domain synchronizer的输入/输出port。ATPG DRC检查时会验证这两个port是否真的在netlist中物理连接——若未连接或连接错误立即报rtstat-6。而Dofile的作用就是告诉ATPG“这两个port之间的数据传递必须经过synchronizer禁止在同一个capture cycle里采样”。3. Dofile配置不是“加约束”而是为Test Procedure构建可信的时序语义环境3.1 Dofile的本质ATPG引擎的“时序宪法”很多工程师把Dofile当成Vivado的XDC文件以为只要把clock constraint抄过来就行。这是致命误解。Dofile不是给综合/布局布线工具用的它是ATPG引擎执行test pattern生成前加载的时序语义环境配置。它不改变RTL网表但决定了ATPG如何解读Test Procedure中每一个时序相关声明。核心区别在于Vivado的XDC约束用于指导工具“如何实现电路”而Tessent的Dofile约束用于指导ATPG“如何理解电路”。前者影响物理实现后者影响测试逻辑生成。例如create_clock -name clk_cpu -period 10 [get_ports clk_cpu]在XDC中定义clock period在Dofile中却只用于让ATPG知道clk_cpu是一个valid clock net——真正决定capture phase timing的是set_scan_chain_clock与Dofile中set_clock_groups的组合。Dofile中真正起作用的是以下三类约束的协同Clock Definition仅声明clock存在性不定义timing。Clock Grouping定义clock间的时序关系同步/异步/互斥这是DRC检查的核心依据。False Path Multicycle Path覆盖Test Procedure中无法表达的特殊时序路径。一旦这三者与Test Procedure声明的scan chain结构不匹配DRC就会报错。比如Test Procedure声明cpu_scan_0用clk_cpu但Dofile中漏了clk_cpu的create_clockATPG会认为该chain无clock驱动所有cell在capture phase状态不可控报rtstat-2no clock defined。3.2 Clock GroupingDRC报错的根源与解法set_clock_groups是Dofile中最易出错也最关键的命令。rtstat-6报错的1184个net90%以上源于clock group声明缺失或错误。其原理很简单ATPG在生成test pattern时会对每个capture cycle做“时序可行性检查”——即验证该cycle内所有被采样的scan cell是否由同一个clock domain驱动或是否已声明异步关系。若未声明ATPG视为潜在时序冲突标记为partial route。常见错误场景及修复错误类型现象Dofile修复方案物理依据漏声明异步clockrtstat-6指向跨clock netset_clock_groups -asynchronous -group [get_clocks clk_a] -group [get_clocks clk_b]两个clock无公共祖先信号传递必须经synchronizer错误声明同步clockrtstat-2报clock domain mixing删除错误的-logically_exclusive改用-asynchronous实际RTL中两clock无phase relationship强行同步会导致setup/hold violationclock mux未处理rtstat-6指向mux output netset_clock_groups -physically_exclusive -group [get_clocks clk_a] -group [get_clocks clk_b]mux select信号在test mode下固定两clock不会同时active特别注意-physically_exclusive与-logically_exclusive的区别前者适用于clock mux场景物理上不可能同时active后者适用于clock divider的分频输出逻辑上不会同时采样。用错会导致ATPG在pattern生成时误判时序路径。另一个高频坑clock gating cell的clock pin未被包含在clock group中。例如clk_cpu经u_cg/clock_gate输出clk_cpu_gatedTest Procedure中chain用clk_cpu_gated但Dofile只声明了clk_cpu的group。ATPG会认为clk_cpu_gated是未定义clock报rtstat-2。正确做法是create_clock -name clk_cpu -period 10 [get_ports clk_cpu] create_clock -name clk_cpu_gated -period 10 [get_pins u_cg/Q] # 注意Q pin是gated clock输出 set_clock_groups -asynchronous -group [get_clocks clk_cpu_gated] -group [get_clocks clk_dbg]3.3 False Path与Multicycle Path覆盖Test Procedure的表达盲区Test Procedure能描述scan chain结构但无法描述“某些路径在test mode下永远不激活”。这时Dofile的set_false_path就是救命稻草。典型场景Reset deassertion路径async reset在test mode下通常保持deasserted其release路径在ATPG中无需考虑timing。若不声明false pathATPG会在DRC检查时发现reset net fanout大、delay长报rtstat-6。set_false_path -from [get_ports rst_n] -to [get_cells *]Scan enable bypass路径当scan chain被bypass时正常functional path仍在工作但ATPG不关心其timing。若不声明ATPG会检查这些path的setup/hold报大量rtstat-6。set_false_path -from [get_ports scan_en] -to [get_cells -hier -filter ref_name*ff*]Multicycle path for slow logic某些debug register在scan shift phase需多个cycle才能稳定Test Procedure无法指定。Dofile中用set_multicycle_path 2 -setup -from [get_cells u_dbg/ctrl_reg] -to [get_cells u_dbg/data_reg]注意set_false_path的-to目标必须是ATPG识别的cell或port。用[get_cells *]虽方便但可能误杀关键路径。最佳实践是先用report_timing -from [get_ports rst_n]查看reset路径再针对性添加false path。4. DRC报错排查实战从rtstat-6到物理netlist的逐层定位4.1 理解rtstat-6的真正含义——不是“错误”而是“不确定性警告”[drc rtstat-6] partial route conflicts: 1184 net(s) have a partial conflict.这句话常被误读为“1184个net连错了”。实际上ATPG DRC的rtstat-6表示在当前Test Procedure和Dofile配置下ATPG引擎无法确定这1184个net在capture cycle中的驱动/采样关系是否安全。它不是说net物理连接错误而是说“我不知道该怎么处理它”。因此排查思路不是“找错线”而是“补全信息”——让ATPG明确知道每个net的时序角色。以下是标准排查流程生成DRC详细报告在ATPG session中执行report_drc -detailed -file drc_report.rpt报告中会列出每个conflict net的full hierarchical name、connected cells、以及ATPG判定conflict的原因如no clock defined,cross clock domain without async group,unconstrained reset path。按原因分类处理将1184个net按report中的reason分组。通常80%属于以下三类no clock defined该net驱动的cell未在Test Procedure中声明clock或Dofile中未create_clock。cross clock domain该net连接两个不同clock domain的cell但Dofile中未set_clock_groups。unconstrained reset该net是reset net但Dofile中未set_false_path。逐类修复验证不要一次性改完再run。每次只修复一类如先解决所有no clock defined然后重新run DRC。因为修复一类可能暴露另一类问题如clock声明后原来隐藏的cross domain问题浮现。4.2 实战案例修复某AI加速器的rtstat-6报错某AI加速器项目DRC报1184个net conflict。按上述流程分析report发现723个net属cross clock domain集中在u_npu/u_dma模块连接clk_npu和clk_ddrdomain。341个net属no clock defined全部是u_npu/u_tensor/u_mac模块的scan cellclock net名为clk_mac_div4。60个net属unconstrained resetrst_nnet在u_npu顶层未声明false path。修复步骤补全clock定义Dofile中添加create_clock -name clk_mac_div4 -period 40 [get_ports clk_mac_div4] # 注意period40ns因为div4后频率为25MHz声明cross domain关系在Dofile中添加set_clock_groups -asynchronous -group [get_clocks clk_npu] -group [get_clocks clk_ddr] set_clock_groups -asynchronous -group [get_clocks clk_mac_div4] -group [get_clocks clk_ddr]这里关键是clk_mac_div4与clk_ddr也要声明异步——因为DMA模块中MAC计算结果要传给DDR controller二者clock无关系。添加reset false pathset_false_path -from [get_ports rst_n] -to [get_cells -hier -filter ref_name*ff* hier_name~u_npu/*]验证重新run DRCconflict net降至0。但ATPG生成pattern时又报rtstat-2no valid capture cycle found。查log发现clk_mac_div4的create_clockperiod设为40但RTL中该clock实际period为32ns因为divisor计算有误。修正period后ATPG成功生成pattern。实操心得rtstat-6修复后出现rtstat-2往往是clock timing参数period, duty cycle与RTL实际不符。此时不要怀疑Test Procedure先用report_clocks对比Dofile声明与RTL netlist中clock属性。4.3 自动化DRC修复脚本减少重复劳动手动处理1184个net不现实。我写了一个TCL脚本自动解析report_drc -detailed输出生成修复建议proc auto_fix_drc {rpt_file} { set fp [open $rpt_file r] while {[gets $fp line] ! -1} { if {[regexp {cross clock domain} $line]} { # 提取两个clock net name regexp {clock ([^ ])} $line - clk1 regexp {clock ([^ ])} $line - clk2 puts Suggest: set_clock_groups -asynchronous -group \[get_clocks $clk1\] -group \[get_clocks $clk2\] } if {[regexp {no clock defined} $line]} { # 提取cell name反查clock net regexp {cell ([^ ])} $line - cell set clk_net [get_attribute [get_cells $cell] clock_net] puts Suggest: create_clock -name $clk_net -period 10 \[get_pins $clk_net\] } } close $fp } # 使用auto_fix_drc drc_report.rpt脚本不直接修改Dofile而是输出建议。因为自动添加set_clock_groups可能覆盖已有约束必须人工审核。但节省了90%的分析时间。5. 避坑指南那些文档里不会写的Tessent ATPG实战经验5.1 Test Procedure与Dofile的版本协同——一个被忽视的定时炸弹Test Procedure和Dofile不是孤立文件它们与RTL netlist、DFT insertion结果强耦合。项目中常见错误用v1.0 RTL生成的netlist配v1.2 Test Procedure新增了chain但Dofile仍是v1.0未更新clock group。结果ATPG读取时Test Procedure声明的新chain在Dofile中无对应clock报rtstat-2。解决方案建立三件套版本锁。在项目根目录放version_control.tcl# version_control.tcl set RTL_VERSION v1.2 set TEST_PROC_VERSION v1.2 set DOFILE_VERSION v1.2 # 每次run ATPG前执行 if {[get_attribute [read_netlist] version] ! $RTL_VERSION} { error RTL version mismatch! } if {[get_attribute [read_test_procedure] version] ! $TEST_PROC_VERSION} { error Test Procedure version mismatch! } if {[get_attribute [read_dofile] version] ! $DOFILE_VERSION} { error Dofile version mismatch! }虽然Tessent不原生支持version attribute但可在Test Procedure/Dofile头部加注释# VERSION: v1.2用TCL脚本解析。这避免了“为什么昨天还好好的今天就报错”的玄学问题。5.2 Dofile中create_clock的端口选择陷阱create_clock命令的-source参数常被误用。正确写法# ✅ 正确clock port是top-level port create_clock -name clk_cpu -period 10 [get_ports clk_cpu] # ❌ 错误用FF clock pinATPG会找不到clock driver create_clock -name clk_cpu -period 10 [get_pins u_dut/u_ff/CLK]因为ATPG DRC检查时需要从clock source追溯到所有scan cell。若-source指向FF pinATPG无法向上追溯到port会认为clock无source报rtstat-2。唯一例外是gated clockcreate_clock -name clk_gated -period 10 [get_pins u_cg/Q]因为Q是gated clock的物理输出点。5.3 Test Procedure中set_scan_chain_length的精度要求set_scan_chain_length必须与RTL网表中实际FF数量完全一致。差1都会导致DRC报错。曾有个项目Test Procedure写length 256实际网表有255个FF因一个FF被optimization removeATPG在DRC检查时发现chain声明256个cell但只找到255个physical cell最后一个位置悬空报rtstat-6指向该位置net。解决方案用脚本自动统计。在Tessent中set chain_len [llength [get_cells -hier -filter ref_name*ff* hier_name~u_dut/scan_chain_0/*]] puts Actual length: $chain_len # 将此值写入Test Procedure5.4 DRC检查的隐藏开关——set_drc_optionTessent DRC有隐藏选项可调整严格度。默认rtstat-6检查非常严格但某些legacy design允许放宽set_drc_option -name rtstat_6_check -value false但这只是掩耳盗铃。真正解决问题是补全约束而非关闭检查。我建议新项目永远开启所有DRC检查legacy项目若必须关闭需在design review中专项说明并记录所有被忽略的conflict net。5.5 最后的防线用report_scan_chain交叉验证在Test Procedure和Dofile都配置完后不要直接run ATPG先执行report_scan_chain -detailed -file chain_report.txt检查报告中每条chain的Physical Length是否等于Declared LengthClock Domain列是否与Dofile中set_clock_groups声明一致Stitching Points是否在netlist中真实存在连接若Physical Length与Declared Length不等说明Test Procedure与netlist不匹配必须回溯RTL。这是DRC报错前的最后一道人工检查关卡。我在实际项目中坚持用这套方法把Tessent ATPG的DRC报错从平均3次/项目降到0次/项目。关键不是记住所有命令而是理解Test Procedure是画地图Dofile是定规矩DRC是巡检员。地图画得再准规矩定得模糊巡检员照样开罚单。
返回列表