4. Scan插入流程
Scan插入不是综合完成后的“补丁动作”,而是一条从RTL阶段就开始规划、贯穿综合与DFT插入、最终落到扫描链连接与签核的完整工程链路。很多项目在后期才发现扫描链无法收敛、测试端口不够、时钟域混乱,根源往往在于RTL阶段没有为可测性设计预留结构。本节围绕RTL规划、综合脚本、DFT Compiler/DFTMAX流程以及扫描链配置与连接四个环节,梳理一条可落地的Scan插入主线。
一、核心原理:Scan插入到底在做什么
Scan插入的本质,是把设计中原本难以直接控制的时序单元,改造成“可控且可观测”的扫描触发器。具体做法是将普通触发器替换为扫描触发器(Scan Flip-Flop),并把同一扫描链上的触发器首尾串联:前一级的Q输出接到后一级的Scan In,形成一条移位寄存器链。测试时通过Scan Enable切换工作模式,在Shift阶段把测试向量逐位移入,在Capture阶段让组合逻辑响应,再在Shift阶段把结果移出比对。
因此,Scan插入要解决三个核心问题:替换(普通FF换成扫描FF)、分组(按时钟域、电源域、物理区域划分扫描链)、连接(确定链的入口、出口、顺序与端口)。这三件事分别对应RTL规划、综合脚本约束和DFT工具流程。
二、RTL阶段规划:把可测性前置
RTL阶段是Scan插入成本最低的窗口。此时设计结构尚未固化,修改端口、时钟和复位策略的代价最小。规划重点包括:
- 时钟域与复位域梳理:每个时钟域通常需要独立的扫描链,避免跨域移位导致时序违例。异步复位在Shift阶段必须被屏蔽,否则会破坏移位数据。
- 测试端口预留:提前确定scan_in、scan_out、scan_enable、scan_clk的引脚数量与位置。若芯片引脚紧张,需规划压缩扫描(Compression)或复用功能引脚。
- 扫描链数量估算:根据触发器总数、目标链长和测试时间预算,估算链数。链越长,移位周期越多,测试时间越长;链越短,端口和布线压力越大。
- 黑盒与IP处理:对模拟IP、存储器等非扫描单元,需在RTL中标记为黑盒或添加旁路逻辑,避免扫描链断裂。
三、综合脚本:为Scan插入准备网表
综合阶段的目标是生成一个“可被DFT工具识别和修改”的网表。关键是在综合脚本中加入扫描相关配置,让综合器在映射时直接使用扫描触发器,而不是先映射普通FF再替换。
# 示例:Design Compiler 综合脚本中的DFT相关设置
set_scan_configuration -chain_count 8 \
-clock_mixing no_mix \
-style multiplexed_flip_flop
set_scan_signal test_scan_enable -port scan_enable
set_scan_signal test_scan_in -port scan_in
set_scan_signal test_scan_out -port scan_out
# 指定扫描时钟
set_scan_path chain_clk1 -view existing_dft \
-scan_data_in scan_in -scan_data_out scan_out
# 综合时启用扫描映射
compile_ultra -scan
# 输出带扫描信息的网表
write -format verilog -hierarchy -output netlist_scan_ready.v
write_scan_def -output scan_ready.def
综合脚本中常见的误区是只写了set_scan_configuration却忘记compile -scan,导致网表中仍是普通触发器,DFT工具需要额外做替换,增加流程复杂度和风险。另一个误区是时钟混合(clock mixing)设置不当,把不同时钟域的FF串在同一条链上,后期移位阶段出现大量时序违例。
四、DFT Compiler/DFTMAX流程与扫描链配置
DFT Compiler(或DFTMAX)负责在综合后网表上完成扫描链的插入、连接和验证。典型流程如下:
- 读入设计:读取综合输出的网表、时序库和扫描就绪的DEF文件。
- 设置DFT配置:指定扫描链数量、链长平衡策略、时钟域分组、压缩模式等。
- 插入扫描链:工具自动替换剩余普通FF,按配置分组并串联。
- 连接与修复:绑定scan_in/scan_out端口,修复链断裂、未连接FF和时序违例。
- 输出与验证:生成插入后的网表、SPF测试协议和扫描链报告。
# DFT Compiler 典型命令序列
read_verilog netlist_scan_ready.v
current_design top
link
set_scan_configuration -chain_count 8 \
-max_length 500 \
-clock_mixing no_mix
set_scan_path chain_clk1 -view existing_dft \
-scan_data_in scan_in -scan_data_out scan_out
insert_dft
connect_scan_chains -auto_create_chains
check_scan_chain -verbose
write -format verilog -output netlist_with_scan.v
write_test_protocol -output top.spf
report_scan_path -view existing_dft -chain all
扫描链配置的核心参数包括链数、最大链长、时钟混合策略和压缩模式。链数越多,测试时间越短,但端口和布线资源消耗越大;最大链长限制用于控制单链移位周期;时钟混合策略决定是否允许跨时钟域串联。压缩模式(如DFTMAX Compression)通过少量端口实现多链并行,适合引脚受限的高密度设计。
| 配置项 | 作用 | 典型取值/建议 |
|---|---|---|
| chain_count | 扫描链数量 | 按FF总数与目标链长估算,常见8~32条 |
| max_length | 单链最大长度 | 控制移位周期,常见200~1000 |
| clock_mixing | 是否允许跨时钟域 | no_mix,按域独立成链 |
| scan_enable | 移位/捕获模式切换 | 全局SE或分域SE |
| compression | 压缩扫描 | 引脚紧张时启用,压缩比10x~100x |
五、案例与复盘:一次扫描链断裂的排查
某项目在DFT插入后执行check_scan_chain,报告显示链3存在“unconnected scan cell”。排查发现,该链经过一个被标记为黑盒的模拟IP,IP内部没有扫描旁路,导致链在此处断开。修复方法是在RTL中为该IP添加扫描旁路逻辑,或在DFT脚本中用set_scan_element false排除该模块并重新规划链路径。
另一个常见问题是扫描链顺序与物理布局不匹配,导致布线拥塞和时序违例。复盘经验是:在DFT插入前,结合布局规划信息对FF进行分组,尽量让同一条链上的FF在物理上相邻;插入后使用report_scan_path检查链长平衡,必要时用balance_scan_chains重新分配。
总结来看,Scan插入流程的关键在于“前置规划、脚本约束、工具执行、连接验证”四个环节的闭环。RTL阶段把可测性结构规划清楚,综合脚本把扫描配置写对,DFT Compiler/DFTMAX按配置完成插入与连接,最后通过扫描链报告和时序分析确认签核质量。只有每个环节都落实,扫描链才能真正成为可测试、可收敛、可签核的工程结构。