4、扫描链时序约束:扫描时钟约束、扫描输入输出延迟、扫描模式时序分析

好,咱们进入第四章。扫描链的时序约束,说实话,这是DFT工程师最常打交道,也最容易出问题的地方。

很多人觉得,扫描模式嘛,不就是把芯片当成一堆寄存器连起来,时序要求没那么严格。嗯,这个想法很危险。我见过不止一个项目,因为扫描链时序没约束好,导致ATE测试时频频报错,最后查出来是setup或者hold violation。那叫一个头疼。

咱们今天就把这块掰开揉碎了讲。核心就三件事:扫描时钟怎么约束、扫描输入输出延迟怎么设、扫描模式下的时序分析怎么做

4.1 扫描时钟约束

扫描时钟,说白了就是测试模式下的时钟。它跟功能时钟是同一个物理时钟源,但约束方式不太一样。

我个人习惯,在扫描模式下,会把时钟约束得稍微宽松一点。为什么?因为测试频率通常比功能频率低。比如功能跑1GHz,扫描可能只跑50MHz。但注意,宽松不代表可以乱来。

关键点在这里:

  • 时钟源要明确:扫描时钟通常来自ATE的时钟通道,或者芯片内部的PLL。你得告诉工具,这个时钟是从哪个端口进来的。
  • 时钟周期要设对:根据ATE的测试频率来设。我建议留10%的余量。比如ATE跑50MHz,你设55MHz的约束。
  • 时钟波形要合理:占空比50%是最常见的。但有些ATE支持非50%占空比,这时候要小心hold time。

重要:扫描时钟的约束,必须跟功能时钟的约束分开。用不同的create_clock命令,加上-waveform参数指定波形。

举个例子,假设你的扫描时钟从SCAN_CLK端口进来,频率50MHz:

create_clock -name scan_clk -period 20.0 -waveform {0 10} [get_ports SCAN_CLK]

这里周期20ns,对应50MHz。波形0到10ns是高电平,10到20ns是低电平。简单明了。

小技巧:如果你用的是内部PLL产生的扫描时钟,记得把PLL的锁定时间考虑进去。我曾经有个项目,PLL锁定需要100us,结果ATE那边等都没等就直接灌向量,前几个cycle全是错的。

4.2 扫描输入输出延迟

扫描输入输出延迟,这个很多人会忽略。你想想看,ATE跟芯片之间是有物理走线的,信号从ATE到芯片引脚,再到内部寄存器,这中间有延迟。

怎么约束?分两部分:

  • 扫描输入延迟:从ATE发出数据,到芯片SI引脚,再到内部第一个扫描寄存器的D端。这个延迟要设成input delay。
  • 扫描输出延迟:从内部最后一个扫描寄存器的Q端,到芯片SO引脚,再到ATE接收端。这个延迟要设成output delay。

我一般这样设:

set_input_delay -clock scan_clk -max 5.0 [get_ports SI*]
set_input_delay -clock scan_clk -min 1.0 [get_ports SI*]
set_output_delay -clock scan_clk -max 6.0 [get_ports SO*]
set_output_delay -clock scan_clk -min 1.5 [get_ports SO*]

这里-max和-min分别对应setup和hold的检查。数值怎么来?看ATE的spec和PCB走线长度。我习惯留0.5ns的裕量。

注意:扫描输入输出延迟的约束,不能跟功能IO的约束混在一起。否则工具会报冲突。我曾经犯过这个错,结果STA跑出来一堆莫名其妙的violation,查了两天才发现是约束重叠了。

4.3 扫描模式时序分析

扫描模式的时序分析,跟功能模式最大的区别在于:扫描链上的路径都是寄存器到寄存器。没有组合逻辑的复杂路径,所以分析起来相对简单。

但简单不代表没坑。我总结了几点:

  1. 检查setup和hold:扫描链上的每个寄存器,都要满足setup和hold。特别是hold,因为扫描时钟的skew可能比较大。
  2. 关注clock skew:扫描模式下,时钟树可能跟功能模式不一样。有些工具会自动切换时钟树结构,你得确认一下。
  3. 注意异步复位:如果扫描链上有异步复位信号,要确保在扫描模式下被正确处理。我建议把异步复位在扫描模式下强制拉无效。

举个例子,假设你有一条扫描链,包含1000个寄存器。每个寄存器的setup要求是0.5ns,hold要求是0.2ns。时钟周期20ns,时钟skew 0.3ns。

那么setup的裕量就是:20 - 0.5 - 0.3 = 19.2ns。看起来很大,对吧?但hold的裕量是:0.2 - 0.3 = -0.1ns。嗯,hold violation了。

核心观点:扫描链的时序瓶颈,往往不在setup,而在hold。因为扫描时钟的skew可能吃掉hold margin。

怎么解决hold violation?我常用的方法:

  • 在扫描链上插入buffer,增加延迟
  • 调整时钟树,减少skew
  • 或者,干脆降低扫描频率

我个人更倾向于第一种。因为插入buffer不影响功能模式,而且成本低。

避坑指南:我曾经在一个项目里,扫描链的hold violation怎么修都修不掉。后来发现,是因为扫描时钟的tree在综合时被优化掉了。工具觉得扫描模式不重要,直接把时钟树给简化了。从那以后,我每次做扫描时序分析,都会先确认时钟树是不是完整的。

最后,说一个实用技巧。扫描模式的时序分析,最好跟功能模式分开跑。用不同的SDC文件,不同的分析视角。我习惯在项目初期就把扫描模式的SDC写好,然后随着设计迭代不断更新。这样到了后期,就不会手忙脚乱。

嗯,扫描链时序约束这块,大概就这些。核心就是:时钟约束要准,IO延迟要合理,时序分析要全面。你只要把这三点抓住了,扫描链的时序问题基本就能搞定。