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工具流程。

Scan插入全流程:从RTL规划到扫描链连接 ① RTL阶段规划 • 时钟/复位域梳理 • 测试端口预留 • 扫描链数量估算 ② 综合脚本约束 • set_scan_configuration • 时钟/时序例外 • 扫描FF映射 ③ DFT Compiler/DFTMAX • 读入综合网表 • 插入扫描链 • 生成测试协议 ④ 链配置与连接 • 链顺序 • 端口绑定 • 平衡与修复 扫描链连接示意(单链,Shift方向) scan_in SFF1 SI→Q SFF2 SI→Q SFF3 SI→Q SFF4 SI→Q scan_out scan_enable (SE) scan_clk Shift 方向 →

二、RTL阶段规划:把可测性前置

RTL阶段是Scan插入成本最低的窗口。此时设计结构尚未固化,修改端口、时钟和复位策略的代价最小。规划重点包括:

  • 时钟域与复位域梳理:每个时钟域通常需要独立的扫描链,避免跨域移位导致时序违例。异步复位在Shift阶段必须被屏蔽,否则会破坏移位数据。
  • 测试端口预留:提前确定scan_in、scan_out、scan_enable、scan_clk的引脚数量与位置。若芯片引脚紧张,需规划压缩扫描(Compression)或复用功能引脚。
  • 扫描链数量估算:根据触发器总数、目标链长和测试时间预算,估算链数。链越长,移位周期越多,测试时间越长;链越短,端口和布线压力越大。
  • 黑盒与IP处理:对模拟IP、存储器等非扫描单元,需在RTL中标记为黑盒或添加旁路逻辑,避免扫描链断裂。
RTL阶段建议输出一份《DFT规划表》,记录每个时钟域的FF数量、计划链数、目标链长、测试端口分配,作为后续综合与DFT插入的输入依据。

三、综合脚本:为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)负责在综合后网表上完成扫描链的插入、连接和验证。典型流程如下:

  1. 读入设计:读取综合输出的网表、时序库和扫描就绪的DEF文件。
  2. 设置DFT配置:指定扫描链数量、链长平衡策略、时钟域分组、压缩模式等。
  3. 插入扫描链:工具自动替换剩余普通FF,按配置分组并串联。
  4. 连接与修复:绑定scan_in/scan_out端口,修复链断裂、未连接FF和时序违例。
  5. 输出与验证:生成插入后的网表、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重新分配。

扫描链插入后必须重新做时序分析,尤其是Shift模式的建立/保持时间。很多项目只关注功能模式时序,忽略Shift模式,导致流片后扫描测试失败。

总结来看,Scan插入流程的关键在于“前置规划、脚本约束、工具执行、连接验证”四个环节的闭环。RTL阶段把可测性结构规划清楚,综合脚本把扫描配置写对,DFT Compiler/DFTMAX按配置完成插入与连接,最后通过扫描链报告和时序分析确认签核质量。只有每个环节都落实,扫描链才能真正成为可测试、可收敛、可签核的工程结构。