工具:Synopsys DFT Compiler (DC Topographical) O-2018.06-SP1
设计:digital_top(显示驱动芯片数字顶层,约 22k 扫描单元,DFTMAX 压缩)
关键词:insert_dft、set_dft_signal、hookup pin、define_test_mode、Autofix、TestData
DFT 插入完成后检查网表,发现扫描链并没有按约束复用指定的端口,DC 反而自作主张新加了几个顶层端口:
data_source、handler_1:DC 自建的扫描时钟端口,扫描链的 MasterClock 全挂在它们上面,而我们指定的扫描时钟 P2D_SCAN_CLOCK 被晾在一边;
test_mode:DC 自建的模式控制端口,而我们指定的 TestMode 信号(内部 u_AND_scan_mode/Z,即 ATPG_EN)和压缩使能 P2D_SCAN_COMPRESS_EN 没有被用作模式编码;
设计里特意留的两个 hookup buffer(u_buf_vloading_0/1,分别挂在 P2D_SCAN_CLOCK 和 P2D_SCAN_COMPRESS_EN 上、输出故意悬空留给 DC 接)输出依然是空的。
一句话:DC 新加了 pin,没有复用我们指定的 scan clock、compression enable 等信号。
检查网表时发现压缩解压器的例化是:
日志对应行:Architecting Load Decompressor (version 5.8),Number of inputs/chains/internal modes = 4/48/4。
48 条内部链对 4 个扫描输入(12:1),DFTMAX 生成了带 4 个 internal modes 的可重构解压器,需要 log2(4)=2 条 select,于是从 ScanDataIn 端口池里拿了两个当 sel。这是 DFTMAX 自适应扫描的标准架构行为,不是连接错误——SPF 里 sel 以 sccompin 伪链形式声明,TetraMAX 可以正常处理。如果想 4 口全做数据,需要降低链/输入比或增加端口。
data_source、handler_1、test_mode 在 pre-DFT 网表中完全不存在,是 insert_dft 阶段新建的。同时发现两个 hookup buffer 在 pre-DFT 网表里就输出悬空(BUFM1TM u_buf_vloading_0 ( .A(P2D_SCAN_CLOCK) ); 没有 .Z)。
这是本次排查最重要的认知。set_dft_signal 的视图语义:
existing_dft 视图:告诉 DRC"设计里已经有这个信号",只用于协议和规则检查,永远不会产生任何物理连接;
spec 视图:告诉 insert_dft"请按这个建",只有它才可能产生连接;
即使 spec 视图声明了,也只有当 DC 插入的逻辑确实需要消费这个信号时才会接线。TestControl/TestMode 这类声明性信号,如果没有结构引用它们(比如 define_test_mode 的编码),声明完了就只是报告里的一行字。
对照初版脚本:ScanClock 的 spec 视图因笔误缺失 → DC 找不到指定扫描时钟 → 自建端口;TestControl 挂在悬空 pin 上且没有任何结构消费 → DC 自建 TCM 和 test_mode 端口(端口名来自 test_mode_port_naming_style "test_mode%s")。
改脚本—跑 make dftins(约 9 分钟)—看报错—查 man page—再改,共七轮:
| 轮次 | 改动 | 结果/新报错 |
|---|---|---|
| 1 | 加 define_test_mode(P2D_SCAN_COMPRESS_EN 编码)+ -test_mode 关联 chain_count/scan_path/压缩配置 | TESTXG-3:ScanClock 用 hookup pin 必须同时指定一个 port;UIT-1800:encoding 引用的端口必须先声明为 TestMode |
| 2 | P2D_SCAN_COMPRESS_EN 改 TestMode;ScanClock 用 port+hookup 组合 | 规格全部被 Accepted,但 DC 自建了无编码的 Internal_scan 当压缩模式基链 → TCM 报 Conflicting pin values,DRC 出现 S1 链阻断(FATAL),my_base1 的链是空的 |
| 3 | 压缩配置加 -base_mode my_base1 | 基链模式正确关联(日志:Architecting scan compression mode scan_compression1 with base mode my_base1),S1 消除、DRC 通过;但 data_source/handler_1 仍在 |
| 4 | 去掉 TestMode 的 -active_state;ScanClock 改纯 -port 形式 | 自建时钟端口仍在;buffer 仍悬空(man page:hookup pin 找不到 proper global driver 就不 stitch) |
| 5 | spec 视图加 TestData 声明 | UIT-663:同一端口不能在 spec 视图同时有两种信号类型 |
| 6 | ScanClock 只留 existing_dft(带 timing),TestData 只放 spec(官方示例写法);P2D_SCAN_COMPRESS_EN TestMode 只留 spec | ✅ data_source/handler_1/test_mode* 全部消失,4 条基链 + 48 条压缩链的 MasterClock 全部变为 P2D_SCAN_CLOCK |
| 7 | 删掉 dft_prepare 里手插的两个 vloading buffer(DC 直连端口即可) | ✅ 重跑确认:零新增端口,TCM 译码输入直连 P2D_SCAN_COMPRESS_EN,DRC 通过 |
链长从原先的 7555/7555/7554/143(严重失衡)变成 5702/5702/5702/5701——时钟统一后时钟域割裂也顺带消除了。
spec vs existing_dft:existing_dft 只读不产生连接;spec 才指导 insert_dft 建设。写约束时先想清楚"我在描述现状,还是在下建设指令"。
hookup pin 不是许愿池(man set_dft_signal):"The hookup pin specified should be either on a black box or should have a proper global driver. If a proper global driver is not found, insert_dft will not stitch to the specified hookup pin." 悬空 buffer 输出就不是 proper global driver 场景能覆盖的;而且 DC 默认会"跳到端口核心侧、跳过 buffer"去连接,所以专门插 buffer 当 hookup 点经常是多此一举。
encoding 端口必须是 TestMode port(UIT-1800),且官方示例里只在 spec 视图、不带 active_state 声明。
define_test_mode 之后的命令归属陷阱(man define_test_mode):一旦定义了自定义模式,set_scan_configuration set_dft_signal set_scan_compression_configuration 不带 -test_mode 就只作用于最后定义的那个模式,要用 -test_mode all 或显式指定。
压缩模式必须绑定基链模式:set_scan_compression_configuration -test_mode <压缩模式> -base_mode <基链模式>,否则 DC 自建一个无编码的 Internal_scan 当基链,引发 TCM 编码冲突甚至 S1 链阻断。
Autofix 的时钟源要预声明 TestData(man set_autofix_configuration):"If no test data signal is specified, Autofix creates a new ScanClock or Reset port depending on the fixing type." 自建时钟端口的真凶就是它。标准写法:同一端口 existing_dft 视图声明 ScanClock(带 timing)+ spec 视图声明 TestData。
同一端口多角色要拆视图(UIT-663):同一视图内一个端口只能有一种信号类型;ScanClock(existing_dft) + TestData(spec) 是官方推荐拆法。
DFTMAX 自适应解压器会占用扫描输入口当 sel:链/输入比高时自动生成带 internal modes 的可重构解压器,sel 从 ScanDataIn 池里取——看到 din 数量比预期少不要慌,先算一下比例。
my_base1 在 TCM 模式向量生成时报 Conflicting pin values in top level vectors:协议/向量层告警,网表结构不受影响(TCM 译码硬件已验证正确),待后续结合 TetraMAX 协议再生时一并处理;
TEST-337(DC 试探性征用复位端口 A2D_RST_PORB 被拒):架构探测的良性告警;
TESTXG-53:internal pins flow 下写出的协议"不准确不可用",给 ATPG 用前需在非 internal pins flow 下重新生成。
这次排障最大的体会是:DC 的 DFT 约束体系里,"声明"和"连接"之间隔着好几层语义——视图(spec/existing_dft)、信号类型(ScanClock/TestData/TestMode/TestControl)、模式归属(-test_mode/-base_mode)、以及 Autofix 的独立取数逻辑。每违反一条,DC 不会报错拒绝,而是"聪明地"自建端口、自建模式、自建时钟,结果网表看起来能跑,实际上处处不是你要的。排查这类问题最有效的方法就是:netlist 对比(pre-DFT vs post-DFT)→ 报告交叉验证(dft_signal/dft_path/autofix_config)→ 逐条啃 man page 的精确语义——Synopsys 的文档写得很清楚,只是你得被逼到那份上才去读它。