【DFT】【Scan & ATPG】OCC Architecture
On-Chip-Clock Controller
OCC 的作用、原理和基本设计方法。
OCC Introduction
OCC 的全称是 On-Chip-Clock Controller ,主要作用是在结构性测试的 At-Speed Delay 测试进行管理时钟。
下图所示是 Scan Test 的基本过程,
- 在 atspd 测试中,需要精准产生两个 at-speed clock cycles 来完成 Launch 和 Capture 的过程。PLL 产生的时钟是一直运行(Free-Running)的,但测试的时候并不是一直需高速时钟,并且要在不同时钟之间进行切换;
- ATE 不能 atspd 测试所需要提供高速时钟。
所以,需要一个模块来对测试过程中的时钟进行控制,OCC 就是来完成这项任务。

关于 Scan Test 的过程的一些补充:
- Shift:ATE 提供 Test Clock,shift in 数据的同时,对比 shift out 的数据对比
- Dummy Cycles:① SE 驱动所有的寄存器,负载非常大,SE 的 transiton 时间很长,
② shift 的过程,Toggle 比较高,可能导致芯片的电压降低。所以在 AC 测试中,shift 完成之后要等一段时间,让芯片电压恢复。 - Force PI & Memory PO对于 Full Scan 的设计,所有的 IO PAD 都被当做 Scan in 、Scan out(Wrapper Cores),这个时候是不需要这个过程的。不过 ATPG Pattern 默认会有这个两个 cycles。
Scan Test Brief Introduction
B 站视频讲解部分。(待补充)
OCC Design
插入 OCC 之后,Design 中的时钟结构如下图所示,所有 regs 的时钟都来自 OCC 的输出端口。

如何设计一个 OCC 呢? 先来考虑如下几点:
- 在正常工作模式下,regs 需要一直使用 func clk,所有 occ 应该有一个 Test Mode 端口,当 Test Mode = 0 (即正常工作模式),OCC 的 clk out 端口上的时钟和 func clk 完全相同;
- 在测试模式下,Shift 阶段使用慢速时钟,AC Capture 阶段使用快速时钟。clk 切换的时间是在 scan_en 由高拉低之后,所有可以利用 scan_en 来控制 clk 的切换过程;
- scan_en 拉低之后,并不是立刻就要用到 fast clock,两者之间有一定的延时,这一点可以用移位寄存器来实现;
有了这样一个基本思路之后,就可以来设计 OCC 电路。
Example 1
一个基于 N bits 移位寄存器的 OCC 的基本结构如下图所示:

- 当 Test Mode = 0 时,芯片工作在 Func Mode,MUX C 直接选中 Func Clock。此时,OCC 处于 Bypass Mode,在 Func 模式下,OCC 时透明的;
- 当 Test Mode = 1 时,芯片工作在 DFT 测试模式下:① 当 Shift Enable = 1 的时候,MUX B 选中 Scan Clock,OCC 输出低速时钟,芯片完成 Shift 过程。与此同时,0 被保存到移位寄存器中;② Shift 过程完成之后,Shift Enable = 0,芯片进入 Capture Mode。此时,移位寄存器 Q0 - Qn 开始被 Shift 1;③ Shift Enable = 0 的时候,MUX B 选中的是 Func Clock,此时,OCC 的还不能直接输出 Func Clock,所以 MUX B 的输入端口需要一个 ICG;④ 移位寄存器最后三级的输出值,经过一段组合逻辑之后,连接到 ICG 的 E 端口,移位寄存器的长度就是等待时间;⑤ 当 At-Speed Mode = 0 的时候(进行 DC 测试),MUX A 选中 0,只有当 Qn-1 = 1,Qn = 0 的时候(整个 Shift 过程只会出现 1 次),MUX 输出 1,ICG 打开,OCC 输出一个 Capture Clock Pules;⑥ 当 At-Speed Mode = 1 的时候(对应 AC 测试),MUX A 选中 1,当 Qn-2 = 1,Qn = 0 的时候,ICG 打开。因为一直在 Shift 1,所以 Qn-2 会一直保持为1,直到 Qn = 1 的时候,ICG 才会关闭,所有可以产生两个 Capture Clock Pulese。
Example 2
在示例 1 的 OCC 已经能够完成时钟切换的功能,但是它存在一定的风险:
- Capture Clock Cycles 和 scan_en 之间的时间间隔取决于移位寄存器的级数,设计完成之后就不能再发生变化, Capture Clock Cycles 不能动态调整;
- 实际的芯片中,scan_en 的负载很大,从 1 切换为 0 需要一定的时间,如果这个时间大于 Capture Clock Cycles 和 scan_en 之间的时间间隔,那么就无法进行 Scan Test 了;
- scan_en 是直接连接到移位寄存器的,而移位寄存器一直处于工作状态,scan en 从 1 切换到 0 的过程中可能会引入不定态;
所以需要对其进行优化,优化之后的 OCC 如下图所示,整体结构和示例 1 中的类似,最大的不同是 scan_en 上多了一级由 slow clock 驱动的 sen_retiming 寄存器。

该 OCC 对应的时序图如下所示:

在分析该 OCC 之前,首先要明确:
slow clock 是由 ATE 提供的,可以在外部进行控制;Func clock 是由芯片内部的 PLL 产生,是 free-running 的。
然后来具体分析 OCC 的工作过程:
- scan_en = 1 的时候,所有的寄存器都会别 shift 1;
- shift 结束之后,slow clock 关闭,此时 CDC 和 sen_sync 这些寄存器中的值是不会更新的,等 scan_en 足够稳定之后,给一个 slow clock cycles(ATE控制),scan en 的 0 就会被 shift 到其他寄存器中;
- 当黄色的两级寄存器中的值为 11 时,launch_en 使能,ICG 打开,提供 Lauch Clock Cycles;
- 当黄色的两级寄存器中的值为 01 时,capture_en 使能,ICG 可以,提供 Capture Clokc Cycles。
如此以来, 虽然 slow clock cycles 和 Lauch Clock Cycles、Capture Clokc Cycles 之间的时间是固定的,但是 scan en 和 slow clock cycles 之前的时间间隔可以通过 ATE 动态调整,进而使得 Lauch Clock Cycles、Capture Clokc Cycles 的到来时间也可以可是实现动态调整。
视频课程里面还有进一步的讲解,后续有时间再看一下;
Synopsys OCC
使用 Synopsys 工具实现 Scan 的时候,OCC 插入前后的电路结构如下图所示:

OCC 的基本结构如下图所示,其中 test_se = scan_en,ate_clk = slow_clock
(这里给出的只是一个概念性的逻辑结构,并非真正的功能实现。)

Different Operation Mode
不同工作模式下的时钟通路如下所示:
Func Mode:

Shift Mode:

Slow Capture Mode:

Fast Capture Mode:

- test_se = 1 的时候,Clock Chain 被 shift 1;test_se = 0 的时候,等 test_en 足够稳定之后,给 1 了 ate_clk cycles 就可以向 Clock chain 中 shift 一个 0;
- Clock Chain 中的值和 PLL cycles coounter 的输出共同决定了 pll_en 是否有效;
- 所有,capture cycles 出现的时间时动态可调的;
OCC Main Components
Synopsys 的 OCC 可以分为如下三大部分:

- Clock Chain/Clock Pulse GeneratorClock chain 是 Scan Chain 的一部分,其中的值可以通过 ATPG Pattern 进行控制;Shift Mode 下向 Clock Chain 中 shift 值,Capture Mode 下,Clock Chain 中的值保持不变。Clock Pulse Generator 对 Clock Chain进行 “翻译”, 决定输出几个 clock enable 信号,或者关停 clock
- Clock Gating Cell利用 pulse generator 的输出来 gating 相对应的 clock,可以去除毛刺和亚稳态(metastable);只要是组合逻辑,就有可能产生亚稳态。CGC 中的 LAT 时负沿触发,AND2 是正沿触发,半个 clock cycles 的等待足以让信号稳定;
- Scan Enable Sync Cell避免由 shift 到 fast capture 的切换过程中,clock 产生亚稳态
Fast Capture Mode Timing Diagram
基于 Synosys OCC,Fast Capture Mode 下对应的时序图如下所示:

- 3 Sync Cycles 对应于消除亚稳态的 3 级 Scan Enable Sync Cell;
- 第四个 Cylcles 的时候,计数器的值是 0,不能产生 Clock Pulse;
- Count = 1,Count = 2 和 Count = 3 时对应的情况,需要满足 Clock Chain 中的值是 011,这个值可以通过 ATPG Pattern 来实现。
OCC Insertion Rules
OCC 可以直接在 RTL 阶段(前端设计过程中)插入,也可以在 DFT Flow 中插入。 OCC 的插入并不是随意的,需要满足如下基本原则:
- External Clock 可以不插OCC(从PAD灌入的Clock可以从外部控制,因此不需要OCC),Internal Clcok 必须要插 OCC;
- OCC 需要放到 Clock Source 和 待测寄存器之间;
- OCC 的输入时钟必须是 free-running 的;
- OCC 不能级联;
结合具体的实例,来看看如何在不同的 Design 中插入 OCC。(在这些示例中,假设所有的 FF 都是 core scan cells,暂时不考虑 wrapper cells。)
Example 1:free-runing clock
OCC 的输入时钟必须是 free-running 的,当 design 中 scan cells 的 clock 存在分频的时候,OCC 需要插入到 divider 的后面。

错误的插入方法为:

原因是驱动 divider 的 clock 已经被 OCC 执行过 chopping 的动作,不再是 free-runing 的 clock,这样就无法得到预期的 clock。
例如, transition 测试需要两个 clock pulse ,在 fast-capture mode 下,divider 可以得到两个 clock pulse,但经过 divider 后,就只剩下一个 clock pulse了,显然不能给后面的 FF2 所需要的 clock 。
Example 2:Hierarchy Design with Wrapper Cores
如下图所示,top 层的 design_A 还包含一层 core_A,并且 core_A 做了 wrapper chains,即 core A 能够单独测试,
因此,在 core_A 的 internal mode下,为了能测试 core_A 的内部逻辑,core_A 内部需要插 OCC,在其 external mode 下(只考虑做一层wrapper,此时对于顶层是 internal mode),还需要测试顶层的逻辑,因此顶层也需要一个OCC。

此时,两个 OCC 的工作情况如下:

虽然有两个OCC,但是无论何时,都是只有一个在工作,这就保证了在任何一个通路上,OCC都没有级联,且所有FF的时钟都是经过OCC控的。
Example 3:Hierarchy Design with No-Wrapper Cores
如下图所示,design_B 与 design_A 类似,区别是内部的 core_B 没有做 wrapper chains。
所以,core_B 不需要单独测试,它和 top 一起进行测试,core_B 的内部不需要插入 OCC。测试的时候无论是顶层的 FF1 还是 core_B 内部的FF2,其时钟都由顶层的 OCC 来控制,

顶层的 OCC1 是必须要有的,需要它来控制 FF1 的时钟。如果 core_B 内部插了 OCC,因为没有做 wrapper,也就无法与顶层隔离开,这样一来, FF2 前面将会有两个 OCC,这就导致 OCC 级联,是不符合 rule 的,在 OCC insertion 这一步有 DRC 报错。
Example 4:Hierarchy Design with Wrapper Cores and Divider
如下图所示,core_C 做了 wrapper chains,并且还有 devider,此时该如何插入 OCC 呢?

首先要明确,要实现 Scan 测试,所有的 FF 的时钟都必须由 OCC 进行控制。
一般情况下,在 block-level 中,会在每个 clock port 的后面(即上图中的 A 点)直接插入一个 OCC,这样就可以确保 block 内部所有的 FF 的 clock 都是由 OCC 控制的。
但是 core_C 中是存在 divider 的,结合示例 1 和 示例 2 ,core_C 中 OCC 的插入方法如下:

这里有一个小细节,FF2 和 FF4 的 clock 找不到一个公共点来进行 OCC 的插入,此时可以和前端沟通,让他们插入一个定位作用的Buffer。
Wrapper Cell Driven by Divider
在 Wrapper Core 中,Scan Cell 分为 Regular Cell 和 Wrapper Cell,Regular Cell 是在 Internal Mode 时候工作,而 Wrapper Cell 是在External Mode 时候工作。
如果示例 4 中的 FF3 是 Regular Cell,它在 Internal Mode工作,此时顶层的 OCC1 不工作,core 内的 OCC3 工作且能拿到一个 free running clock 去驱动 FF3,这样 FF3 可以正常做 Scan 测试。
但是假如 FF3 是 Wrapper Cell,那么它就要在 External Mode 下工作,此时顶层的 OCC1 工作,core 内部的 OCC3 不工作,这时 FF3 拿到的 Capture Clock 就会出现问题。因为顶层的 OCC1 工作后会放下来一个 chopping 过的 clock,再经过 divider,AC Capture 的时候,两个 Clock Pulse 就变成一个,这会使得 FF3 无法测试。
因此,对于 Core 内有 Divider 的模块,假如 Divider 后面驱动了 Wrapper cell,需要特殊处理,最简单的方法就是这部分逻辑不做 Wrapper
Cell。假如工具把 FF3 分析为了 Wrapper Cell,就需要把相对应的 Port Exclude 掉,使得 FF3 变成 Regular Cell 即可。
(如果 Divider 后面确实需要驱动 wrapper cell,也有相应的处理方式,本文不做讨论。)
Example 5:Hierarchy Design with No-Wrapper Cores and Divider
如下图所示的 design_D,它与 design_C 类似,区别是内部的 core_D 不做 wrapper。

对于内部 core 不做 wrapper 的情况,core 内不用插 OCC,但是对于 design_D 来说是行不通的,因为 core 内还有个 Divider。
假如 core_D 内部不插入 OCC 并且不做 wrapper,Core 和顶层一起测试,Core 内的 FF 的测试时钟都由 OCC1 来控制。这对于 FF2 和FF4 来说没什么问题,但是对于 FF3 又会出现 AC Capture Clock 只有一个 Clock Pulse 的情况,导致其无法测试。
因此,不管做不做 Wrapper,Core 内部只要有 Divider,Divider 后面就要插 OCC,否则 Divider 后面的逻辑将不可测。
但是,对于 design_D 的这种情况,如果直接在 B 点插入 OCC,它和 OCC1 之间就是级联关系,这是不符合设计规则的。可是顶层的OCC1 又必不可少,否则 FF1/FF2/FF4 都不可测。解决这个问题的办法和 示例 4 类似,给 Divider 这一路单独做分支。
只是这个分支要从顶层开始做,并且给 core_D 增加个 port(如果这路时钟仅仅只是驱动了 core_D,在顶层没有驱动其他逻辑,也可以不新增 port,把 OCC1 和分支做在 core 内部。)。
最终,完成 OCC 插入的 design 如下图所示:

Brief Summary
基于上述几个示例,对 OCC 的插入位置做一个简单总结:
