为什么在 cts 过程中 func clock 和 scan clock 经常长不齐?

在数字后端 CTS 过程中,有时候会碰到这样一种情况:

只开 function scenario 来做cts,可以得到很 balance 的 tree,

但是一旦带上 scan scenario 去做 cts,就容易出现不balance。

 

首先说说为什么会出现这种现象:

假设一个design 中只有两个 function clock: clk1、clk2,如下图所示:

clk1 的 sink 点是 R1~R3

clk2 的 sink 点是 R4~R6

那么在cts时,clk1 和 clk2 就会单独长tree,各自内部长齐,

假设 clk1 的 clock latency 比较短,而 clk2 的clock latency 比较长,

由于所有的reg 都要串起来做成一条 scan chain,所以scan_clk 的sink点就是图中的 R1~R6,

又因为 R1~R3 的 clock latency 比 R4~R6 的clock latency 小很多,

所以在 scan scenario 下必然会有较大的skew。

 

那么这个问题该如何解决?

1) 只开 scan scenario 去做 cts,让所有的sink点都长齐,这种方法显然得不偿失,白白增加了大量的clock buffer,不可取

2) 只开 func  scenario 去做 cts,此时 clk1 和 clk2 两组clock 各自内部单独长齐,比较合理;但是在 scan mode 下,R3 与 R4 之间可能会有较大的 hold violation,这个问题可以参考这篇博文来解决: 如何使用 lockup latch 来修 hold violation 

https://www.cnblogs.com/xiaoxie2014/p/12518376.html

 

除了上面这种方法,还有一种简单的办法:

同时开启 func 和 scan,但是要在上图中的两个 MUX 的 scan 输入端设置 exclude pin,这样在cts 时,scan clock 就不会穿透mux ,不会影响到mux 后的时钟树

这样做的代价是 scan clock 并没有做平,可能会出现hold,不过由于 scan 的周期比较大,setup 余量较大,所以对于 scan hold 还是可以通过垫 buffer 修掉

 

关于func 和 scan clock 的一个案例:

某设计中的时钟结构如下图:

 

其中定义在 port A 上的时钟 clk 是 func clock,定义在 D 点后的 clk_gen 是 clk 的 generated clock,clk 与 clk_gen 在EF点的与门汇合,scan clock 定义在 port C上

1. 在不设置任何exception 的条件下,直接做 cts ,发现工具在 HD 之间加了很多ckbuffer,看名字是为了垫长这段时钟,工具似乎把D 点当作了一个sink pin,而 D 点定义的是一个 generated clock,cts 应该会穿透 generated clock,为什么这里没有穿透?

这里的 clk_gen 的 source 是 clk,所以对于 clk 来说, clk_gen 是 generated clock ,但是对于 scanclk 时, clk_gen 并不是 generated clock,所以在给 scanclk 做 cts 时,工具会把 D 点作为一个 sink pin 来做 balance ,所以 HD 之间的这些 buffer 都是在 scanclk cts 过程中加入的

解决办法:把图中两个mux 的 1 端都设置成 exclude pin,这样 cts 时, scanclk 不会穿透 mux ,就不会出现上面的情况了,但是这样做的代价就是 scanclk 并没有长齐,可能会有时序问题,但是由于 scanclk 一般都比较慢,周期较长,即使时序出了问题也比较好修

2.

 

 

 

|-------------------------------------------|

 

posted @ 2020-03-16 13:15  いつまでも  阅读(4137)  评论(1编辑  收藏  举报