4、扫描链的时钟与复位:时钟域划分、扫描时钟设计、异步复位同步释放

时钟和复位,是扫描链的命脉。我见过太多芯片,功能仿真跑得飞起,一到ATE测试就翻车。十有八九,问题都出在时钟和复位上。今天咱们就聊聊这块硬骨头。

4.1 时钟域划分:别让跨时钟域坑了你

现代芯片里,几十个时钟域是家常便饭。你想想看,CPU核跑2GHz,外设总线可能才100MHz,还有一堆PLL分出来的衍生时钟。扫描链怎么处理?

核心原则:每个时钟域独立成链。

我个人习惯的做法是:

  • 同一个PLL出来的同频同相时钟,可以放一条链
  • 不同PLL、不同频率的时钟,必须分开
  • 异步时钟域之间,加隔离单元

时钟域划分检查清单:

  • 每个时钟域至少有一条独立的扫描链
  • 跨时钟域路径必须用LOCKUP LATCH或同步器隔离
  • 扫描使能信号要同步到每个时钟域

我在项目中遇到过这样一个案例:一个SoC芯片,有7个时钟域。设计团队图省事,把两个异步时钟域的触发器串在一条链上。结果呢?ATE测试时,扫描移位模式下的hold timing一塌糊涂。最后不得不ECO,加了一堆lockup latch。教训啊!

4.2 扫描时钟设计:两种主流方案

扫描时钟怎么来?说白了就两种路子:

方案 实现方式 优点 缺点
专用扫描时钟引脚 芯片额外加一个SCAN_CLK pin 与功能时钟完全隔离,测试干净 多一个pin,封装成本增加
功能时钟复用 通过MUX选择功能时钟或扫描时钟 节省pin,设计简单 时钟路径上多了MUX,影响时序

嗯,这里要注意:复用方案里,MUX的选择信号必须是测试模式信号。我见过有人直接用scan_enable去选时钟,结果扫描移位时时钟毛刺不断,数据全乱了。

正确的做法是这样:

// 扫描时钟MUX的正确用法
assign scan_clk = test_mode ? scan_clk_in : func_clk;

// 错误用法 - 千万别这么干!
assign scan_clk = scan_enable ? scan_clk_in : func_clk;  // 大忌!

为什么不能用scan_enable? 因为扫描移位过程中,scan_enable会变化。一旦它跳变,时钟MUX瞬间切换,产生毛刺。触发器可能采到错误数据。

警告: 扫描时钟的时钟树综合(CTS)一定要在功能时钟树之后做。我曾经为了赶进度,先做了扫描时钟树,结果功能时钟树做完后,两条树的skew对不上,hold violation修了整整两周。

4.3 异步复位同步释放:扫描模式的特殊处理

异步复位,听起来简单——复位信号一来,所有触发器立刻清零。但在扫描模式下,这是个坑。

你想想看:扫描移位时,我们需要把测试数据串行灌进去。如果复位信号在此时抖动一下,所有数据就全丢了。

解决方案:扫描模式下强制屏蔽异步复位。

具体做法:

// 异步复位同步释放 + 扫描模式处理
module rst_sync (
  input  clk,
  input  rst_n,          // 异步复位输入
  input  scan_mode,      // 扫描模式指示
  input  scan_rst_n,     // 扫描模式下的复位(通常接VDD)
  output rst_out_n       // 同步后的复位输出
);

  reg [1:0] sync_reg;
  wire rst_in_n = scan_mode ? scan_rst_n : rst_n;

  always @(posedge clk or negedge rst_in_n) begin
    if (!rst_in_n) begin
      sync_reg <= 2'b00;
    end else begin
      sync_reg <= {sync_reg[0], 1'b1};
    end
  end

  assign rst_out_n = sync_reg[1];

endmodule

这段代码里,scan_mode为高时,复位源被强制切换为scan_rst_n。在ATE测试时,这个引脚直接接VDD,相当于复位永远无效。扫描链可以安心地移位数据。

小技巧: 我个人习惯在复位同步器的第一级触发器上,加一个set_dont_touch约束。为什么?因为综合工具可能会优化掉同步器的结构,导致MTBF(平均无故障时间)下降。这个坑我踩过,分享给你。

4.4 避坑指南:我踩过的那些雷

做DFT这么多年,时钟复位相关的坑,我至少踩过七八个。挑几个典型的说说:

  • 时钟门控的扫描旁路: 功能模式下,时钟门控用来省电。但扫描模式下,必须旁路掉所有时钟门控。否则门控关掉时,触发器采不到时钟,数据就卡住了。
  • 复位网络的RC延迟: 我曾经遇到一个案子,复位网络走线太长,RC延迟导致复位信号到达不同触发器的时间差超过一个时钟周期。结果扫描链前端的触发器已经复位了,后端的还没复位,数据全乱了。
  • 多bit寄存器的复位一致性: 有些库里的多bit寄存器,复位端是共用的。如果其中一个bit的复位路径有毛刺,整个寄存器都会受影响。建议在扫描链插入时,把这些多bit寄存器拆开。

说白了,时钟和复位的设计,就是要在功能模式和测试模式之间找到一个平衡点。功能模式下要省电、要高性能;测试模式下要稳定、要可控。这个平衡点找好了,芯片测试就成功了一半。

最后送大家一句话:扫描链的时钟复位设计,宁可保守,不要激进。 多花一周时间做验证,好过流片回来在ATE上debug一个月。