恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Tessent标准单元库DFT适配:扫描链映射与DRC排错
首页
资讯中心
/
Tessent标准单元库DFT适配:扫描链映射与DRC排错
Tessent标准单元库DFT适配:扫描链映射与DRC排错
发布时间:2026/9/29 5:03:46
做 DFT 的同行大概都碰过这种场面RTL 交给后端之前一切顺利扫描链一插就炸Tessent 的 DRC 报告刷满屏幕而报错指向的那些单元看上去毫无毛病——它就是库里的一个普通触发器。Tessent_StdcellLib 这类项目的价值恰恰在这里它管的不是什么高深算法而是把代工厂给的标准单元库改造成 Tessent 能正确识别、正确建模、正确做规则检查的那一套 DFT 视图。标准单元库StdcellLib是 DFT 流程里最容易被低估的环节很多人以为read_liberty跑通就完事了结果扫描链映射、EDT 压缩、时序收敛阶段才发现一堆单元没被识别。这篇内容面向做芯片可测性设计的工程师也适合刚接手 DFT 库维护的初学者我会把库准备工作、DFT 建模、常见报错和排查手法完整讲一遍都是能直接抄去用的东西。1. 把 Tessent 和 StdcellLib 的关系捋清楚1.1 标准单元库在 DFT 流程里到底扮演几个角色先说个容易被忽略的事实一颗数字芯片的 DFT 流程里标准单元库不只是逻辑门的集合它在 Tessent 眼里至少有三重身份。第一重是功能与时序身份也就是 Liberty 里描述的布尔函数、建立保持时间、延迟表第二重是物理身份对应 LEF、GDS 里的版图信息这部分 Tessent 用得少但后端扫描链绕线阶段绕不开第三重是 DFT 身份也就是工具靠什么认出这个单元是扫描触发器这个单元是时钟门控这个单元支持扫描旁路。三重身份里前两重通常由代工厂或者后端团队维护得好好的第三重往往就是 Tessent_StdcellLib 这类项目要补的窟窿。为什么第三重最容易出问题因为模拟和综合对库的要求跟 DFT 对库的要求根本不是一套标准。综合工具只要知道逻辑和时序就能把 RTL 映射成门级网表它不关心这个触发器是不是扫描触发器但 Tessent 在做扫描替换的时候必须找到一个和原触发器功能等价、同时带扫描端口的替代单元否则它只能报找不到扫描等价单元。这个信息 Liberty 里可能有也可能没有取决于代工厂的库做得够不够细。我在项目里见过最典型的情况代工厂给的 Liberty 里触发器只标了ff组和时钟、复位的相关属性test_cell那一组完全是空的。这种库丢给综合没问题丢给 Tessent 就会在扫描插入阶段大面积报错。解决办法要么是让代工厂补要么自己在库适配层里补——而后者正是 StdcellLib 项目的核心工作量。1.2 Tessent_StdcellLib 这个项目名背后的真实工作量光看Tessent_StdcellLib这个名字很容易误解成给 Tessent 准备一套标准单元库这么简单。实际拆开看它至少要干四件事库视图的收集与裁剪、DFT 属性的补全、扫描单元的映射关系建立、库版本与工具版本的绑定管理。这四件事没有一件是纯搬砖每一件都涉及对代工厂库文档的仔细阅读和大量试错。收集与裁剪是第一步。代工厂给的库往往是一个大压缩包里面躺着几十种工艺角corner的 Liberty、不同电压域的版本、各种 PVT 组合。DFT 流程真正用到的通常只有签名signoff用的那两三个角其余全丢掉能省掉大量读库时间。我遇到过读一次全库要花二十分钟的情况裁剪到必要角之后缩到三分钟以内迭代效率完全不是一个量级。补全 DFT 属性是第二步也是最费脑子的。有些代工厂的库在test_cell里只标了扫描输入输出忘了标扫描使能的有效电平有些把时钟门控单元ICG的 enable 端口标成了普通输入导致 Tessent 在做时钟树上的测试点插入时判断失误。这些细节不补后面 DRC 阶段会以各种奇奇怪怪的形式报出来。建立映射关系是第三步。工具需要知道A 触发器的扫描版本是 B 触发器这个映射可以靠命名规则自动推导也可以手工配置。命名规则靠谱的时候自动推导能省事但代工厂的命名经常不统一同一个库里可能出现SDFFQ、SDFFRQ、SDFFRSQ多种前缀甚至有的扫描单元压根不带S前缀。版本绑定是第四步是长期维护的痛点。工具升级、库升级、工艺节点切换任何一个变了都可能让之前的适配失效必须有一套能复现、能回溯的管理机制。1.3 什么样的团队需要单独维护这样一个库不是所有项目都需要把 StdcellLib 单独拎出来做。小规模的 SoC如果用的是主流代工厂的成熟库Tessent 直接读 Liberty 就能跑通犯不着专门建一个库适配项目。但下面几种情况基本躲不掉一是用自研单元库或者定制工艺库文档不全二是做多项目并行同一套流程要适配好几个工艺节点三是做 MCU、汽车电子这类对 DFT 覆盖率要求极高的产品扫描链配置复杂需要精细控制每个单元的行为四是团队里 DFT 工程师和库维护工程师是两拨人需要一层隔离。我倾向于这么判断如果每次换库都要花超过一周时间调试 Tessent 报错那就值得把适配工作沉淀成项目如果换库基本一天搞定那就先别急着建项目容易过度工程化。这个判断标准听起来粗糙但实际用下来挺准。2. 库视图清单Tessent 到底会向你要哪些文件2.1 时序与功能视图是基础盘Liberty 文件是 Tessent 读取的核心输入。它里面包含了时序弧、单元功能、引脚定义、工作条件这些信息。DFT 流程对 Liberty 的关注点和综合、STA 不太一样综合盯着延迟和面积STA 盯着路径时序Tessent 主要看单元类型、引脚属性、以及跟测试相关的那些描述。换句话说Liberty 里那些时序表对 DFT 来说大多是噪音真正关键的是单元定义那部分。Verilog 仿真模型是另一个必需的输入。Tessent 在做扫描链仿真验证的时候需要把插入扫描逻辑之后的网表跑一遍这时候得用库的仿真模型。代工厂一般会提供两种 Verilog 模型一种是功能模型行为级描述一种是带specify块的时序模型用于 SDF 反标。DFT 仿真用功能模型就够了用时序模型反而会因为路径延迟导致仿真变慢。这里有个坑提醒一下功能模型和 Liberty 的功能描述必须一致。我见过代工厂的库因为版本更新不同步Liberty 里触发器是上升沿触发Verilog 模型里写成了下降沿结果 Tessent 扫描仿真出来的波形对不上查了两天才发现是库自己的问题。库一致性检查这一步千万别省。2.2 物理视图对 DFT 的影响没想象中那么大LEF 和 GDS 属于物理视图。严格来说Tessent 做扫描链插入、EDT 压缩、边界扫描这些工作的时候不太关心单元的物理尺寸。但它有两个地方会用到一是扫描链的物理感知排序physical-aware scan chain reordering为了减少绕线拥塞工具需要知道单元的大致位置和引脚方向二是和 ATPG 相关的版图感知分析。对 Tessent_StdcellLib 项目来说物理视图的维护优先级可以放低通常直接引用后端团队维护的版本就行不用自己在库项目里再存一份。非要存的话注意 LEF 里的宏定义和 Liberty 里的引脚名必须严格对应大小写都不能错——这个错在校验阶段报出来还算友好在绕线阶段报出来就很折磨人了。2.3 DFT 专属视图是重头戏真正体现 StdcellLib 项目价值的是 DFT 专属视图。这里面最重要的概念是扫描单元定义。Liberty 用test_cell组来描述一个单元的测试行为里面可以定义扫描输入scan in、扫描输出scan out、扫描使能scan enable、测试时钟这些引脚并通过signal_type属性告诉工具每个引脚在测试模式下的角色。常见的signal_type取值包括表示扫描输入的、表示扫描输出的、表示扫描使能的、表示扫描时钟的以及它们的反相版本。工具读到这些标注之后就能自动完成扫描链的连接推断。如果库里的test_cell不全Tessent 会退而求其次用单元名的模式匹配去猜。猜得准不准全看代工厂的命名规范。除了test_cellDFT 视图里还有一些辅助信息值得整理比如时钟门控单元的使能引脚定义、三态单元的输出使能定义、锁存器单元的透明状态描述。这些东西平时不显山露水一旦出问题就是大面积报错。2.4 目录组织与命名约定要提前定死库文件一多目录结构就成了灾难。我的建议是按工艺节点 / 库版本 / 视图类型三级组织比如顶层是工艺代号下面按库版本号分目录再下面是 liberty、verilog、lef、dft 这几个子目录。命名上统一用库名加视图类型加角标的格式避免出现这个文件到底是哪个库哪个角的困惑。这套约定最好在项目启动时就写进 README并且用脚本强制检查。人是有惰性的你指望每个同事都按规矩放文件迟早会乱。3. 动手做把代工厂库改造成 Tessent 可用的 DFT 库3.1 第一步是梳理 Liberty 里跟 DFT 相关的属性拿到一个新库别急着往 Tessent 里塞先用脚本把 Liberty 里所有单元类型扫一遍。关注这么几类单元带ff或ff_bank组的时序单元、带latch组的锁存器、带statetable的状态表单元、以及名字里带 scan 或 test 字样的所有单元。把这四类先列出来形成一张清单。接着检查清单里每个时序单元的test_cell组是否存在。存在的话看里面的引脚标注是否完整不存在的话标记为需要补全。补全的方式有两种一是直接修改 Liberty 文件加入test_cell组二是用工具提供的 Tcl 命令做外部映射。前者一劳永逸但会污染原始库文件后者灵活但要每次跑流程时都加载一遍配置脚本。我个人偏向第一种把补全后的库作为项目产物管理起来源库只读。举一个补全的例子。假设有个触发器叫DFFRQ带异步复位扫描版本叫SDFFRQ两者引脚上扫描输入叫SI、扫描输出叫SO、扫描使能叫SE测试时钟复用功能时钟。那么补全后的test_cell组大致要描述清楚SI 是扫描输入类型SO 是扫描输出类型SE 是扫描使能类型而且要标明 SE 的有效电平是高还是低。这四件事缺一不可缺了工具就得靠猜。注意修改 Liberty 时不要动功能组、时序组、功耗组里的任何内容只在test_cell和引脚属性层面做加法。动了基础部分综合和 STA 的结果就跟校验对不上后果比 DFT 报错严重得多。3.2 扫描单元和扫描链的匹配逻辑库补全之后第二步是让 Tessent 把非扫描单元和扫描单元对应起来。工具的逻辑是扫描插入阶段它遍历网表里每个时序单元尝试找一个功能等价、带扫描端口的替代单元。找得到就替换找不到就报没有扫描等价单元。匹配的可靠性取决于两个东西单元命名规则和扫描单元库的完整性。命名规则方面代工厂通常遵循某种规律比如加 S 前缀、加后缀、或者在名字里插入 scan 字样。你可以用正则表达式把这些规则提炼出来写进 Tessent 的配置里让它自动完成映射。库完整性方面要注意有些工艺库为了省面积某些驱动强度的触发器没有对应扫描版本这种单元的扫描替换就只能靠工具插入多路选择器来实现性能和面积都有代价。实操中我建议做一次全库映射检查把所有非扫描触发器列出来逐个查找扫描版本生成一张映射表。表里查不到对应项的单元要么在 RTL 层面避免使用要么在综合阶段做单元替换。这张表本身也是 StdcellLib 项目的重要产物。3.3 时钟门控、锁存器、异步单元最容易踩坑时钟门控单元ICG是 DFT 里最麻烦的一类。它通常有功能时钟输入、时钟输出、使能端、测试使能端。工具需要知道使能端在扫描测试模式下应该被强制为什么值否则测试模式的时钟会被意外关掉扫描链直接卡死。有些库没有明确标注测试使能引脚Tessent 只能靠猜猜错了就报时钟不可控。锁存器相对好处理一些但也有坑。锁存器的透明特性让它在扫描链里无法直接使用工具需要把它展开成主从结构或者插入测试点。如果库里的锁存器没有标注透明状态工具展开的时候可能会出错。这个错误在 DRC 阶段不一定报跑到 ATPG 阶段才发现覆盖率异常排查成本很高。异步单元指的是带异步置位、异步复位的触发器。扫描测试模式下这些异步端必须被控制在非有效状态否则扫描链里的值会被强制清零或置一。库需要明确告诉工具哪些引脚是异步控制端、有效电平是什么。我见过库把复位引脚的有效电平标反的案例结果扫描链一插入一半的触发器被锁死波形上看得出来但 DRC 不报纯靠肉眼盯出来的。3.4 库编译和一致性验证不能省补全后的库在做正式流程之前建议先做一轮独立的一致性验证。验证内容至少包括Liberty 内部各单元的功能描述和引脚定义自洽、Verilog 功能模型的端口列表和 Liberty 完全对应、扫描单元的替代关系表没有悬空项、所有test_cell标注引用的引脚名字都真实存在。这一步用脚本自动化比较划算。我写过一个简单的一致性检查脚本就是把 Liberty 解析成字典Verilog 模型解析成端口列表两边做差集比对。跑一次几秒钟能拦下大部分低级错误。比等到 Tessent 报一堆看不懂的错再去翻库文件效率高太多了。验证通过之后再把这个库交给 Tessent 做一次空跑也就是拿一个最小规模的测试设计跑通读库、扫描配置、DRC 检查这几步。空跑通过才算库真的可用。4. 常用命令与参数速查可直接抄的片段4.1 上下文设置与读库Tessent Shell 是基于 Tcl 的流程通常从设置上下文开始。做扫描测试相关的库检查一般进入扫描上下文然后再读设计源和库文件。下面这段是我常用的骨架注意命令名和选项在不同版本上可能略有差异以你手上版本的手册为准。# 进入扫描 DFT 上下文 set_context dft -scan # 读取 RTL 或门级网表 read_verilog ./design/rtl/top.v read_verilog ./design/rtl/sub.v # 读入库文件 read_liberty ./lib/tech.lib # 设置当前设计 set_current_design top # 定义扫描相关的 DFT 信号 set_dft_signal -view existing_dft -type ScanClock -port clk -timing {45 55} set_dft_signal -view existing_dft -type ScanEnable -port se -active_state 1 set_dft_signal -view existing_dft -type Reset -port rst_n -active_state 0这里解释一下几个关键参数。set_context dft -scan说的是后面所有操作都在扫描插入的语境下进行工具会加载对应的库解析规则和 DRC 规则集。read_liberty负责把 Liberty 读进来工具会解析里面的单元定义并建立内部模型。set_dft_signal用来告诉工具哪些端口是测试相关的信号-type指定信号类型-active_state指定有效电平-timing给时钟定义波形。-active_state这个参数特别容易写错。扫描使能是高有效就写 1低有效写 0复位同理。写错了工具不会立刻报错但扫描链插入的结果会完全不对。我习惯在写完这几行之后用一次简单的 DRC 检查确认工具认出了这些信号。4.2 扫描插入前的 DRC 检查库能不能用DRC 说了算。Tessent 提供了一组设计规则检查命令能在正式插入扫描逻辑之前先把问题暴露出来。常见做法是先配置扫描规则然后跑检查再根据报告逐条处理。# 配置扫描参数 set_scan_configuration -chain_count 8 \ -clock_mixing no_mix \ -add_lockup true # 跑设计规则检查 check_design_rules # 查看违规详情 analyze_drc_violationsset_scan_configuration里的几个参数值得说明。-chain_count指定扫描链数量这个数字要结合测试引脚数和测试时间预算来定链少了测试时间长链多了引脚不够。-clock_mixing no_mix表示不同时钟域的触发器不混在同一条链里这样做的好处是避免跨时钟域的时序问题代价是链数会增加。-add_lockup true会在链的边界插入锁存器防止时钟偏移导致的保持时间违例。DRC 报告里跟库相关的违规大体分几类找不到扫描等价单元、时钟不可控、异步信号不可控、单元被当成黑盒。每一类的处理方式不同后面会详细讲。4.3 一个最小可跑通的流程脚本把上面几步串起来就是一个最小可跑通的库验证流程。这个脚本的目的不是产出可用的测试逻辑而是验证库本身有没有问题。set_context dft -scan read_verilog ./design/rtl/top.v read_liberty ./lib/tech.lib set_current_design top set_dft_signal -view existing_dft -type ScanClock -port clk -timing {45 55} set_dft_signal -view existing_dft -type ScanEnable -port se -active_state 1 set_dft_signal -view existing_dft -type Reset -port rst_n -active_state 0 set_scan_configuration -chain_count 4 -clock_mixing no_mix check_design_rules # 报告库中扫描单元的识别情况 report_scan_cells ./report/scan_cells.rpt跑完之后重点看两份东西DRC 报告里的错误条目以及扫描单元报告里工具识别出的扫描触发器数量。如果识别数量明显少于网表里的触发器数量说明库的映射没配全。提示库验证阶段不要急着跑完整插入流程。先把 DRC 和识别报告看干净再往下走能省掉大量无意义的迭代时间。我见过有人直接跑插入报了几千条错根本无从下手。5. 常见问题与排查实录5.1 典型报错速查表下面这张表是我这些年攒下来的高频问题清单覆盖了库相关报错的绝大部分场景。表里的可能原因和处理方向都是实打实踩出来的不是从手册上抄的。报错或现象可能原因处理方向找不到扫描等价单元库缺扫描版本或命名规则没配补全扫描单元映射表检查命名正则时钟不可控时钟门控单元的测试使能未标注补全 ICG 的测试引脚定义异步端不可控复位或置位引脚有效电平标错核对 Liberty 中的引脚极性单元被识别为黑盒Liberty 里缺少该单元定义检查库是否裁剪过头补回单元扫描链卡死无波形翻转时钟被门控或复位被激活检查测试模式下的时钟与复位约束同一单元在不同角下行为不一致多角库混用确认流程只用签名角仿真结果与预期不符Verilog 模型与 Liberty 不一致做库一致性比对这张表不是万能钥匙但它能帮你快速缩小排查范围。遇到报错先对号入座别一上来就怀疑工具。5.2 从 DRC 报告倒推库问题的思路DRC 报告是排查库问题的第一手材料但它有个特点报告里说的是设计规则违规真正的原因可能在库里。举几个我实际遇到的例子。有一次报的是某触发器输出端没有可观测路径表面上像是测试点插入的问题查下来发现是那个触发器的扫描输出引脚在 Liberty 里标注成了普通输出工具根本不知道它是扫描输出自然连不上链。改一个属性就解决了。还有一次工具报了上百条时钟信号不可控定位到具体单元之后发现是某个时钟门控单元。打开 Liberty 一看这个 ICG 的测试使能端名字叫TE但库里的test_cell组把它标成了普通输入。工具不知道TE在测试模式下要拉高时钟自然就断在那里。补上标注之后上百条报错一次清零。这类问题的共同特征是报错位置和真实原因相隔一层。看报告的时候要习惯性地问一句工具为什么会这么判断往往就能顺着线索找到库里的定义缺口。5.3 几个特别容易忽略的细节第一个细节是大小写。Liberty 里的引脚名、Verilog 模型里的端口名、网表里实例化的连接名三处必须完全一致包括大小写。我见过因为库文件里把SE写成se导致映射失败的案例找了半天才发现是大小写差异。DFT 工具对大小写通常敏感别指望它帮你做归一化。第二个细节是多驱动强度版本的单元。同一功能不同驱动强度的触发器可能有好几个版本扫描替换时要保证替换前后驱动能力接近否则会影响时序收敛。有些库的扫描版本只提供中等驱动强度用在高驱动场景会引入额外的时序违例。这个在后端阶段才暴露返工成本很高最好在库映射阶段就记录清楚。第三个细节是低功耗单元的隔离。带电源开关的单元、带体偏置的单元在测试模式下的行为往往和功能模式不同。库需要明确描述这些单元在测试模式下的状态否则扫描测试可能会在错误的电源状态下执行。这块内容在很多代工厂的基础库里是缺失的需要单独补。第四个细节是库的版本号追踪。每次代工厂更新库都要重新跑一遍一致性验证和空跑流程。我习惯在库目录里放一个版本记录文件写清楚这一版相比上一版改了什么、谁改的、什么时候改的。听起来像形式主义但真出事的时候这份记录能救命。6. 工具版本、安装环境与库的适配关系6.1 工具版本与库格式的兼容问题Tessent 的库解析逻辑在不同版本之间是有变化的有时候新版本对 Liberty 的语法支持更宽松有时候反而更严格。我遇到过升级工具之后原本能读的库读不进去了原因是新版本对某个属性的取值范围做了收紧。这类问题没有通用解只能靠版本记录和回归测试来防。稳妥的做法是工具版本和库版本做绑定记录下这套库在哪个工具版本上验证过。升级工具之前先在测试设计上跑一次完整回归确认库读取、DRC、扫描插入、ATPG 全流程都正常再上正式项目。别图省事直接升出了问题排查起来极其痛苦因为报错信息往往指向库实际原因在工具。6.2 安装介质与授权要按正规流程走关于tessent安装包这个关键词实际工作中经常有人问去哪找。我的建议很明确安装介质和授权从正规渠道获取走公司的采购流程或者供应商的支持渠道。EDA 工具的价值不只是那个安装包本身更重要的是配套的技术支持、文档和版本更新。绕开正规渠道拿到的东西遇到问题没人帮你版本对不上也没人管短期省事长期埋雷。安装环节本身倒是不复杂主要是环境变量的配置。Tessent 需要设置工具根目录、授权服务地址、以及一些语言相关的环境变量。这些在官方的安装手册里都有说明照着配就行。要注意的是多版本共存的情况如果机器上装了好几个版本的 Tessent环境变量要指向当前项目要用的那一个别让默认路径把流程带到别的版本上去。6.3 环境变量和库路径管理的实践库路径管理这块我建议不要写死在脚本里。把库根目录做成环境变量脚本里引用变量切换库版本时只改变量不改脚本。这样做的好处是同一套流程脚本能适配多个工艺节点回归测试也方便。# 示例库根目录与工具根目录的环境变量约定 export STDCELL_LIB_ROOT/proj/lib/techA/v1.2 export TESSENT_HOME/tools/tessent/2023.4 export PATH$TESSENT_HOME/bin:$PATH配合一个简单的路径检查脚本在流程启动时验证库目录存在、关键文件齐全、版本号符合预期能挡掉不少跑了一半才发现路径错了的尴尬。7. 我在这类项目里攒下的一些实操心得库适配这件事技术难度其实不高难的是耐心和细致。我做过三个工艺节点的库适配每次都有新坑也慢慢摸出了一些共性的东西。第一先做减法再做加法。拿到代工厂的库先把用不到的工艺角、电压域、单元类型全部砍掉只留 DFT 真正需要的那部分。库小了读得快报错也少排查范围更清晰。很多人一上来就想着全都留着省得以后要用结果被冗余信息淹没。第二所有人工补全都用脚本做。手工改 Liberty 文件改一个两个还行改几十个必然出错而且没法追溯。写个脚本把补全规则固化下来库更新的时候重跑一遍就行。脚本本身也是项目资产。第三建一份单元映射台账。把所有非扫描单元到扫描单元的对应关系、驱动强度对比、特殊属性都记录下来。这份台账在项目后期特别有用无论是要做手工 ECO还是要跟后端对齐面积和时序预算都能直接查。第四回归测试用例要小而精。不需要拿整颗芯片做库验证设计一个包含各种典型单元的小测试设计就够了普通触发器、带异步复位的触发器、带扫描的版本、时钟门控、锁存器、三态单元一样来一个。这个设计跑得快覆盖面也够是库迭代的好帮手。第五别忽略文档。库的每个补全动作都值得写一句注释说明为什么补、依据是什么。三个月后回头看你自己都不记得当时为什么改那一行。文档不是给别人看的是给未来的自己看的。最后说一点体会Tessent_StdcellLib 这类项目最难的部分从来不是工具命令而是对库的理解。工具的行为是可以从手册和实验中搞清楚的库里的每一个属性、每一个引脚定义背后都有设计者的意图。把库读薄再读厚这两个来回走完之后DFT 流程里那些看似莫名其妙的报错基本都能一眼看穿。