跳到主要内容DFT 中的 OCC 架构:Scan 与 ATPG 时钟控制详解 | 极客日志编程语言
DFT 中的 OCC 架构:Scan 与 ATPG 时钟控制详解
OCC 用于结构性测试的 At-Speed Delay 测试管理时钟。在 Shift 阶段使用慢速时钟,Capture 阶段切换至高速时钟。设计需考虑 Test Mode、Scan Enable 信号同步及亚稳态消除。插入规则要求内部时钟必须经过 OCC,且不能级联。针对分频器及层级设计,需特殊处理以避免时钟脉冲丢失或不可测。
并发大师5 浏览 On-Chip Clock Controller (OCC) 架构解析
OCC 简介与作用
OCC(On-Chip-Clock Controller)的主要作用是在结构性测试的 At-Speed Delay 测试中管理时钟。在 Scan Test 的基本过程中,我们需要精准产生两个 at-speed clock cycles 来完成 Launch 和 Capture 的过程。
PLL 产生的时钟通常是 Free-Running 的,但测试时并不需要一直运行高速时钟,且需要在不同时钟之间进行切换。此外,ATE 设备通常无法直接提供测试所需的高速时钟信号。因此,需要一个模块来对测试过程中的时钟进行控制,OCC 正是为此而生。
关于 Scan Test 过程的一些补充说明:
- Shift:ATE 提供 Test Clock,shift in 数据的同时对比 shift out 的数据。
- Dummy Cycles:SE 驱动所有寄存器负载较大,transition 时间长;shift 过程 Toggle 较高可能导致芯片电压降低。因此在 AC 测试中,shift 完成后需等待一段时间让芯片电压恢复。
- Force PI & Memory PO:对于 Full Scan 设计,所有 IO PAD 被当作 Scan in/out(Wrapper Cores),此时不需要此过程,但 ATPG Pattern 默认会有这两个 cycles。
OCC 设计与原理
插入 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,两者之间有一定的延时,这一点可以用移位寄存器来实现。
基础结构示例
一个基于 N bits 移位寄存器的 OCC 基本结构如下:

工作逻辑分析:
- 当 Test Mode = 0 时,芯片工作在 Func Mode,MUX C 直接选中 Func Clock。此时 OCC 处于 Bypass Mode,在 Func 模式下是透明的。
- 当 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 Pules。
优化方案
上述示例虽然能完成时钟切换功能,但存在风险:Capture Clock Cycles 和 scan_en 之间的时间间隔取决于移位寄存器的级数,设计完成后不能动态调整;实际芯片中 scan_en 的负载很大,从 1 切换为 0 需要一定时间,若该时间大于间隔则无法进行 Scan Test;scan_en 直接连接到移位寄存器可能引入不定态。
优化后的 OCC 在 scan_en 上增加了一级由 slow clock 驱动的 sen_retiming 寄存器:
分析该 OCC 之前,首先要明确:slow clock 是由 ATE 提供的,可以在外部进行控制;Func clock 是由芯片内部的 PLL 产生,是 free-running 的。
- 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 打开,提供 Launch Clock Cycles。
- 当黄色的两级寄存器中的值为 01 时,capture_en 使能,ICG 打开,提供 Capture Clock Cycles。
如此以来,虽然 slow clock cycles 和 Launch/Capture Clock Cycles 之间的时间是固定的,但是 scan en 和 slow clock cycles 之前的时间间隔可以通过 ATE 动态调整,进而使得 Launch/Capture Clock Cycles 的到来时间也可以实现动态调整。
Synopsys OCC 实现
使用 Synopsys 工具实现 Scan 的时候,OCC 插入前后的电路结构会有所不同。OCC 的基本结构包含 test_se = scan_en,ate_clk = slow_clock。
不同工作模式
- 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 counter 的输出共同决定了 pll_en 是否有效。
- 因此,capture cycles 出现的时间是动态可调的。
主要组件
Synopsys 的 OCC 可以分为如下三大部分:
- Clock Chain / Clock Pulse Generator:Clock 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 时序
基于 Synopsys OCC,Fast Capture Mode 下对应的时序图如下:
- 3 Sync Cycles 对应于消除亚稳态的 3 级 Scan Enable Sync Cell。
- 第四个 Cycles 的时候,计数器的值是 0,不能产生 Clock Pulse。
- Count = 1, Count = 2 和 Count = 3 时对应的情况,需要满足 Clock Chain 中的值是 011,这个值可以通过 ATPG Pattern 来实现。
OCC 插入规则
OCC 可以直接在 RTL 阶段(前端设计过程中)插入,也可以在 DFT Flow 中插入。OCC 的插入并不是随意的,需要满足如下基本原则:
- External Clock 可以不插 OCC(从 PAD 灌入的 Clock 可以从外部控制,因此不需要 OCC),Internal Clock 必须要插 OCC。
- OCC 需要放到 Clock Source 和待测寄存器之间。
- OCC 的输入时钟必须是 free-running 的。
- OCC 不能级联。
结合具体的实例,来看看如何在不同的 Design 中插入 OCC。(在这些示例中,假设所有的 FF 都是 core scan cells,暂时不考虑 wrapper cells。)
示例 1:Free-Running Clock
OCC 的输入时钟必须是 free-running 的,当 design 中 scan cells 的 clock 存在分频的时候,OCC 需要插入到 divider 的后面。
原因是驱动 divider 的 clock 已经被 OCC 执行过 chopping 的动作,不再是 free-running 的 clock,这样就无法得到预期的 clock。例如,transition 测试需要两个 clock pulse,在 fast-capture mode 下,divider 可以得到两个 clock pulse,但经过 divider 后,就只剩下一个 clock pulse 了,显然不能给后面的 FF2 所需要的 clock。
示例 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 都没有级联,且所有 FF 的时钟都是经过 OCC 控制的。
示例 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 报错。
示例 4:Hierarchy Design with Wrapper Cores and Divider
如下图所示,core_C 做了 wrapper chains,并且还有 divider,此时该如何插入 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,也有相应的处理方式,本文不做讨论。)
示例 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 如下图所示:
总结
基于上述几个示例,对 OCC 的插入位置做一个简单总结:
相关免费在线工具
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
- JSON美化和格式化
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online