ARTICLE DETAIL

资讯详情

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

Tessent DFT流程中库文件选型与.lib到.tcelllib转换实战指南

Tessent DFT流程中库文件选型与.lib到.tcelllib转换实战指南 1. 为什么Tessent流程里库文件选型是个绕不开的坎搞DFT的同行大概都有过这种体验拿到一个新工艺节点的标准单元库打开一看厂商给了一堆文件——.lib、.db、.lef、.gds、.cdl还有Tessent专用的.tcelllib和.tsdb。这时候问题就来了到底该用哪个为什么有的流程跑得通有的跑一半报错说找不到cell为什么同样的设计换一个库文件格式ATPG的覆盖率就掉了几个百分点这些问题的根源在于Tessent的DFT流程对库文件有自己的一套逻辑。它不像综合工具那样直接吃.lib就完事也不像后端PR工具那样主要依赖.lef和.gds。Tessent需要的是带有测试信息的库模型——也就是说它不光要知道这个cell的逻辑功能还要知道这个cell在测试模式下的行为比如扫描链怎么串、时钟怎么控、三态门怎么关。这就引出了我们今天要聊的核心从.lib到.tcelllib的转换以及在这个过程中怎么做库文件选型。我见过太多项目在这上面翻车——有的是直接拿.lib硬塞给Tessent结果工具根本不认有的是转换脚本写错了导致scan chain的时序信息丢失还有的是选错了库的版本跟综合用的库对不上最后DFT插完跟网表匹配不了。这篇文章适合谁看如果你正在搭建Tessent DFT流程或者正在为库文件转换头疼又或者你是个刚接触DFT的新人想搞清楚这些文件格式之间的关系那接下来的内容应该能帮你省下不少试错时间。我会从库文件的本质讲起把Tessent的库模型体系拆开然后一步步说清楚转换的实操细节和选型逻辑。1.1 先搞清楚Tessent到底需要什么Tessent在DFT流程中主要干三件事扫描链插入Scan Insertion、测试协议生成Test Protocol Generation、ATPG向量生成。这三件事对库文件的需求是不一样的。扫描链插入阶段Tessent需要知道每个触发器的时钟端口、扫描使能端口、扫描输入输出端口。这些信息在标准的.lib文件里其实有但格式和命名不一定符合Tessent的预期。比如有的库用CK表示时钟有的用CLK有的用CP。Tessent的.tcelllib文件就是用来做这层映射的——它把标准库里的cell定义翻译成Tessent能理解的测试模型。测试协议生成阶段Tessent需要知道时钟树的结构、时钟门控单元的行为、复位/置位信号的极性。这些信息在.lib里往往不够完整因为.lib主要是给综合和时序分析用的它不关心测试模式下时钟怎么切换。所以.tcelllib里会额外定义测试时钟的切换逻辑、时钟门控的bypass路径。ATPG阶段Tessent需要每个cell的故障模型——stuck-at、transition delay、path delay等等。这些故障模型依赖于cell的内部结构。对于标准单元Tessent通常用预定义的故障模型库对于复杂IP比如存储器、PLL就需要专门的.tcelllib来描述其测试行为。所以你看.lib和.tcelllib根本不是一回事。.lib是给综合和时序分析用的.tcelllib是给DFT用的。两者有交集但侧重点完全不同。1.2 库文件格式的家族谱系在深入转换之前有必要把整个库文件家族理清楚。我画个表来对比文件格式主要用途是否包含测试信息Tessent是否直接支持.lib综合、时序分析部分触发器有scan端口定义不直接支持需转换.dbSynopsys综合同.lib不直接支持.lef物理布局无不支持.gds版图无不支持.cdl网表无不支持.tcelllibTessent测试模型完整直接支持.tsdbTessent内部数据库完整直接支持这个表里最关键的一行是.tcelllib。它是Tessent的原生库格式本质上是一个Tcl语法的脚本文件里面用add_cell、add_pin、add_test_model这些命令来描述每个cell的测试行为。.tsdb则是Tessent在读取.tcelllib后生成的二进制数据库读取速度更快但不可编辑。实际项目中我们通常维护.tcelllib源文件让Tessent自动生成.tsdb。2. 从.lib到.tcelllib转换的核心逻辑与实操2.1 转换的本质是什么很多人以为从.lib到.tcelllib就是个格式转换写个脚本解析.lib然后输出.tcelllib就完事了。如果你真这么干大概率会踩坑。因为.lib里的信息不足以完整描述一个cell的测试行为转换过程中需要补充大量DFT专属信息。举个例子。一个普通的D触发器在.lib里的定义大概是这样的cell(DEF_FF) { area: 10; ff(IQ, IQN) { next_state: D; clocked_on: CK; } pin(D) { direction: input; } pin(CK) { direction: input; clock: true; } pin(Q) { direction: output; function: IQ; } }这个定义告诉综合工具这是一个D触发器时钟是CK输出是Q。但Tessent看了会问扫描模式怎么进scan enable是哪个端口scan chain的输入输出怎么接时钟在测试模式下能不能被门控这些问题.lib都没回答。所以.tcelllib里需要补充add_cell DEF_FF -type sequential add_pin D -direction input add_pin CK -direction input -clock add_pin Q -direction output add_test_model DEF_FF -type scan_ff \ -clock CK \ -scan_in SI \ -scan_out Q \ -scan_enable SE注意这里的SI和SE端口在原始.lib里可能根本不存在——它们是DFT插入阶段Tessent自己加上去的。但.tcelllib需要预先定义好这些端口的名字和连接关系否则Tessent不知道该往哪插。2.2 手工转换 vs 脚本转换怎么选实际项目里库文件转换有两条路手工写.tcelllib或者用脚本自动转换。手工写适合什么情况cell数量少比如只有几十个自定义cell、测试行为特殊比如复杂的时钟门控、或者厂商已经提供了参考.tcelllib需要你微调。手工写的优点是精确可控缺点是费时费力而且容易漏掉cell。脚本转换适合什么情况标准单元库有几百上千个cell、格式规整、厂商提供了完整的.lib。脚本转换的优点是快缺点是需要处理各种边界情况——比如.lib里的语法变体、特殊celllatch、clock gate、三态门的测试模型定义。我的建议是混合使用。先用脚本做批量转换生成一个基础.tcelllib然后手工review和修正特殊cell。这样既保证了效率又不会在关键cell上出错。2.3 脚本转换的实操步骤下面我以一个实际项目为例说说脚本转换的完整流程。假设我们有一个标准单元库stdcell.lib需要转换成stdcell.tcelllib。第一步解析.lib文件.lib是Liberty格式语法上是嵌套的括号结构。你可以用Python的liberty-parser库来解析也可以自己写个简单的解析器。我倾向于自己写因为Liberty的语法虽然规整但不同厂商的扩展语法差异很大用现成的库反而容易被限制。import re def parse_liberty(filepath): with open(filepath, r) as f: content f.read() # 去掉注释 content re.sub(r/\*.*?\*/, , content, flagsre.DOTALL) # 提取cell定义 cells {} cell_pattern rcell\s*\(\s*(\w)\s*\)\s*\{ for match in re.finditer(cell_pattern, content): cell_name match.group(1) start match.end() # 找到匹配的右括号 brace_count 1 pos start while brace_count 0 and pos len(content): if content[pos] {: brace_count 1 elif content[pos] }: brace_count - 1 pos 1 cell_body content[start:pos-1] cells[cell_name] cell_body return cells这段代码的核心是括号匹配。Liberty文件里cell定义是嵌套的简单的正则搞不定必须做括号计数。第二步识别cell类型解析出cell后需要判断每个cell是什么类型。标准单元库里的cell大致分几类组合逻辑AND、OR、MUX、INV等时序逻辑DFF、DLAT、SDFF等时钟单元CLKBUF、CLKGATE等特殊单元TIEH、TIEL、FILL等判断依据主要是cell内部有没有ff或latch定义以及pin的名字和功能。def classify_cell(cell_body): if ff( in cell_body or latch( in cell_body: if scan in cell_body.lower() or SI in cell_body: return scan_ff return sequential elif clock_gating in cell_body.lower(): return clock_gate elif three_state in cell_body.lower(): return tristate else: return combinational第三步生成.tcelllib这是最关键的一步。对于不同类型的cell生成的.tcelllib内容完全不同。组合逻辑cell的转换最简单def gen_comb_cell(name, body): pins extract_pins(body) tcl fadd_cell {name} -type combinational\n for pin_name, pin_info in pins.items(): direction pin_info[direction] tcl fadd_pin {pin_name} -direction {direction}\n return tcl时序逻辑cell就复杂了。需要提取时钟端口、扫描端口、输出端口还要定义测试模型def gen_seq_cell(name, body): pins extract_pins(body) clock_pin find_clock_pin(pins) output_pins [p for p, i in pins.items() if i[direction] output] tcl fadd_cell {name} -type sequential\n for pin_name, pin_info in pins.items(): tcl fadd_pin {pin_name} -direction {pin_info[direction]}\n # 定义扫描触发器测试模型 tcl fadd_test_model {name} -type scan_ff \\\n tcl f -clock {clock_pin} \\\n tcl f -scan_in SI \\\n tcl f -scan_out {output_pins[0]} \\\n tcl f -scan_enable SE\n return tcl注意这里的SI和SE是Tessent在插入扫描链时会自动添加的端口。如果你的设计里已经有这些端口比如用了带扫描端的DFF那就要用实际的名字。第四步处理特殊情况实际转换中会遇到各种特殊情况我列几个常见的多时钟DFF有的DFF有多个时钟输入需要定义时钟选择逻辑带复位/置位的DFF需要定义复位/置位在测试模式下的行为时钟门控单元需要定义测试模式下的bypass路径三态门需要定义测试模式下如何disableLatch需要定义测试模式下的透明/锁存行为这些特殊情况如果处理不好ATPG阶段会报大量DRC错误。我的经验是先把所有特殊情况列出来逐个写转换规则然后在.tcelllib里手工验证。2.4 转换后的验证怎么知道.tcelllib是对的生成.tcelllib后不能直接拿去跑DFT。必须先验证。验证分三步第一步语法检查Tessent读.tcelllib时如果语法有错会直接报错。你可以用tessent -shell进入交互模式然后执行read_cell_library stdcell.tcelllib如果没有报错说明语法没问题。第二步cell覆盖检查检查.tcelllib里定义的cell是否覆盖了网表里用到的所有cell。这个可以用Tessent的check_cell_library命令check_cell_library -design my_design如果报出missing cell说明转换时漏了。第三步测试模型验证这是最关键的一步。用一个小设计跑一遍完整的DFT流程——scan insertion、DRC、ATPG——看看有没有问题。如果ATPG覆盖率正常通常95%以上DRC没有大量违规说明.tcelllib的测试模型定义是对的。我踩过的一个坑是转换时把某个clock gate的测试bypass路径定义错了导致ATPG时时钟控不住覆盖率直接掉到70%。后来查了半天才发现是.tcelllib里add_test_model的-clock参数写错了端口名。3. 库文件选型的决策逻辑什么场景用什么库3.1 综合库和DFT库必须一致吗这是个经典问题。理论上综合用的.lib和DFT用的.tcelllib应该来自同一个库版本否则cell的行为可能不一致。但实际项目中经常出现综合库和DFT库版本不同的情况——比如综合用的是厂商最新版的.lib而DFT用的.tcelllib是从旧版转换来的。这种不一致会导致什么问题最典型的是时序信息不匹配。综合时工具认为某个路径的延迟是XDFT插入扫描链后Tessent按.tcelllib里的时序信息算出来是Y。如果X和Y差异大可能导致hold time violation扫描链跑不通。我的建议是尽量保持一致。如果实在做不到至少要做交叉验证——用综合后的网表跑一遍DFT DRC看看有没有时序相关的违规。如果有要么更新.tcelllib要么在DFT阶段加时序约束。3.2 不同工艺节点下的库选型策略不同工艺节点库文件的组织方式差异很大。我按节点来说成熟节点180nm、130nm库文件通常比较简单cell数量少.lib里直接包含scan信息。这种节点下手工写.tcelllib完全可行甚至厂商可能直接提供.tcelllib。主流节点65nm、40nm、28nmcell数量多.lib里scan信息可能不完整需要脚本转换。这个节点下要特别注意low power cell比如带power gating的cell的测试模型定义。先进节点16nm、7nm及以下库文件极其复杂multi-bit flip-flop、complex clock gate、各种低功耗cell。这个节点下基本必须用厂商提供的.tcelllib或转换工具手工写不现实。而且先进节点的DFT规则更严格库文件的任何小错误都可能导致ATPG失败。3.3 存储器、IP核的库文件怎么处理标准单元库的转换相对标准化但存储器SRAM、ROM和IP核PLL、ADC的库文件就麻烦多了。这些IP通常不提供.lib格式的测试模型而是提供Verilog行为模型或专门的DFT手册。对于存储器Tessent需要的是MBIST模型Memory BIST。这个模型描述了存储器的地址线、数据线、控制线以及内建的self-test逻辑。通常厂商会提供.mbist文件或.tcelllib格式的存储器模型。如果没有就需要根据存储器的datasheet手工写。对于PLL这类模拟IPDFT阶段通常只需要知道它在测试模式下怎么bypass。这个信息一般在IP的DFT手册里有需要手工写成.tcelllib。我做过一个项目SRAM厂商只给了Verilog模型没有.tcelllib。我们根据Verilog模型和datasheet手工写了MBIST模型花了大概两周时间。所以如果你在项目初期就知道要用哪些IP最好提前跟厂商确认他们能提供什么格式的DFT模型。4. 实操中容易踩的坑与排查思路4.1 转换脚本的常见错误写转换脚本时最容易出错的地方有几个端口方向判断错误。.lib里pin的direction字段有时候会写错或者用了非标准写法比如direction : input;和direction: input ;。脚本解析时如果没做容错就会漏掉或搞错方向。时钟端口识别错误。有的库用clock: true标记时钟端口有的用clocked_on有的什么都不写但端口名是CK。脚本需要综合多种规则来判断。scan端口处理错误。有的DFF在.lib里已经定义了scan端口SI、SE有的没有。脚本需要判断如果已有scan端口直接用如果没有生成默认的SI/SE。特殊cell遗漏。比如TIEH、TIEL、FILL、DECAP这些cell在DFT流程里通常不需要测试模型但.tcelllib里如果不定义Tessent读网表时会报warning。我的做法是在.tcelllib里给这些cell加一个空的test model明确告诉Tessent忽略它们。4.2 Tessent报错信息的解读Tessent的报错信息有时候很隐晦我列几个常见的和对应的排查方向报错信息可能原因排查方向Cannot find cell XXX in library.tcelllib里没有定义该cell检查转换脚本是否漏了cellCell XXX has no test modelcell定义了但没有test model检查add_test_model是否执行Clock pin XXX not found时钟端口名不匹配检查.lib和.tcelllib里的端口名Scan chain tracing failedscan端口连接错误检查SI/SE端口定义DRC violation: clock gating时钟门控测试模型错误检查clock gate的bypass定义4.3 一个真实的排查案例去年有个项目ATPG覆盖率一直上不去卡在85%左右。DRC报了几百个violation都是关于clock gate的。我一开始以为是.tcelllib里clock gate的测试模型写错了查了半天没发现问题。后来用Tessent的report_test_model命令把clock gate的测试模型dump出来才发现问题.lib里这个clock gate的enable信号是低有效但.tcelllib里我按高有效定义了。结果测试模式下enable信号一直有效时钟被门控住触发器收不到时钟扫描链断了一截。修复方法很简单在.tcelllib里把enable的极性改过来add_test_model CLKGATE -type clock_gate \ -clock CK \ -enable E \ -enable_polarity low \ -test_enable TE改完后覆盖率直接回到96%。这个坑让我记住了一件事极性polarity是库文件转换里最容易忽略的细节。.lib里很多信号都有极性定义转换时必须原样保留。4.4 库文件版本管理DFT库文件不是转换一次就完事了。项目过程中库可能会更新——厂商发了新版本、修了bug、加了新cell。每次更新都需要重新转换和验证。我的做法是把转换脚本和.tcelllib都纳入版本管理Git每次库更新时先diff新旧.lib看看哪些cell变了然后有针对性地更新.tcelllib。不要每次都全量重新转换那样容易引入意外变化。另外.tcelllib里最好加注释标明每个cell的来源和转换日期。这样后面查问题时能快速定位。5. 一些提高效率的实践技巧5.1 建立库文件检查清单每次拿到新库按这个清单过一遍确认.lib版本和工艺节点检查cell数量跟厂商文档对比检查是否有scan信息SI/SE端口检查特殊cellclock gate、latch、tristate的定义跑转换脚本生成.tcelllib语法检查cell覆盖检查小设计跑通DFT流程记录转换过程中的特殊处理这个清单看起来简单但能避免80%的低级错误。5.2 用Tessent的交互模式调试Tessent的shell模式是调试库文件的好工具。你可以逐条执行.tcelllib里的命令看看哪条报错。也可以读入设计后用report_cell命令查看某个cell的测试模型report_cell DEF_FF -test_model这个命令会输出Tessent理解的该cell的测试行为跟你的预期对比就能发现定义错误。5.3 自动化验证脚本如果项目里库文件经常更新建议写个自动化验证脚本。脚本做三件事读入.tcelllib读入一个包含所有cell的测试网表跑DFT DRC检查是否有violation这个脚本可以集成到CI流程里每次库更新自动跑一遍有问题提前发现。6. 写在最后库文件转换这件事说大不大说小不小。做得好DFT流程顺风顺水做得不好后面ATPG阶段各种报错排查起来极其痛苦。我的经验是在库文件上多花一天时间验证后面能省一周的debug时间。另外不要迷信厂商提供的.tcelllib。我遇到过厂商给的.tcelllib里clock gate模型定义错误的情况直接拿来用导致覆盖率上不去。所以不管来源是什么都要自己验证一遍。最后分享一个小技巧如果你不确定某个cell的测试模型该怎么写可以找一个已知正确的.tcelllib比如Tessent自带的示例库看看类似cell是怎么定义的照猫画虎。Tessent的安装目录下通常有$TESSENT_HOME/share/tcelllib之类的示例库很有参考价值。
返回列表