What Is OCV/AOCV/POCV/SOCV/LVF?

芯片在实际生产中,同一片晶圆上的不同区域的芯片,因为各种外部条件和生产条件的变化(variation),比如:工艺(Process),电压(Voltage),温度(Temperature)等,可能会产生不同的误差从而导致同一块晶圆上某些区域上的芯片里的晶体管整体速度变快或变慢,因此有了corner的概念。而与此同时,在同一块芯片上的不同区域,也会因为上述因素而有进一步的差异(variation),因此产生了OCV(On Chip Variation)的概念。

Corner vs. OCV

在设计中引入OCV的目的在于从设计角度考虑芯片在实际生产中可能出现的各种差异(variation),从而适度增加设计余量(margin),减少不必要的设计悲观量(pessimism)。那么在实际中是如何将OCV带入design的呢?

从OCV的概念出现至今,随着工艺的发展,OCV也经历了如下的一系列进化:

OCV的发展

那么它们都是什么意思呢?在设计中又有什么不同呢?在详细解说之前我们先考虑以下一条timing path的setup分析:

在理想情况下,我们假设所有cell和net在实际生产后其delay都和我们设计中通过库和rc寄生参数计算出来的数值完全一样,那么setup应满足如下条件(如此处有疑问请复习一下setup hold的概念):

然而,在实际生产中,由于各种variation可能会出现如下情况:

此时的setup分析变成了下面的样子:

在x, y, z都是正数的时候,只满足理想状况下setup的电路是不一定能够满足上述条件的。这样就会导致实际生产出来的芯片有一定的概率不能满足需要的频率等条件,严重的甚至会导致芯片失效而降低良率。那么对此我们有什么解决办法呢?

OCV (On Chip Variation)

这是针对上述问题提出的第一个方法。它的基本理念是,对launch, capture和data line上的cell或者net加一个固定的derate数值,使得setup和hold等时序约束比理想状况更加悲观从而能够覆盖部分实际生产中所产生的variation。实际设计中的效果如下:

可以看到,对于launch clock,加上一个统一的大于1的derate值,就会在timing report中反映出来,相应的delay也会在原始值的基础上乘以这个derate值。

对于capture clock line,相应地就会加上一个小于1的derate来计算delay。通过这样的方法来让时序约束更加悲观,以此来覆盖生产中和实际应用中的各种variation,提高良率。

AOCV (Advanced On Chip Variation)

AOCV的概念之所以被提出来,是由于OCV存在以下缺点:在实际中的variation,绝少是一个统一的数值,而大概率是服从正态分布的。以一条timing path的data line为例,可能并不是所有的cell都因为variation而变慢或变快,而是大部分variation较小,少量variation较大。如果我们采用OCV的方式,就会引入不必要的悲观量使得设计更难收敛,同时可能增加不必要的面积和功耗。

针对这个问题,AOCV提出:对于一条path上,级数越多其variation分布越接近正态分布,因而这条path整体的variation也越小。在实际设计中,会根据一条line上cell的级数不同而设置不同的dereate值。实现这中设置的方法,是通过一种AOCV table来查表决定。这种table文件的内容格式大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
object_type: lib_cell
delay_type: cell
object_spec: -quiet libName/cellName
rf_type: rise
derate_type: early
depth: 1 2 3 4 5 6 8 10 20 30 40 50 60 80 100
distance: 0 5000000 10000000 20000000 30000000 40000000
table: 0.7232 0.8043 0.8402 0.8616 0.8762 0.8870 0.9021 0.9125 0.9381 0.9495 0.9562 0.9609 0.9643 0.9691 0.9723 \
0.7166 0.7970 0.8326 0.8538 0.8682 0.8789 0.8939 0.9042 0.9296 0.9408 0.9475 0.9521 0.9555 0.9602 0.9635 \
0.7139 0.7939 0.8294 0.8505 0.8649 0.8756 0.8905 0.9007 0.9260 0.9372 0.9439 0.9485 0.9518 0.9566 0.9598 \
0.7101 0.7897 0.8249 0.8459 0.8603 0.8709 0.8857 0.8959 0.9210 0.9322 0.9388 0.9434 0.9467 0.9514 0.9546 \
0.7071 0.7864 0.8215 0.8424 0.8567 0.8672 0.8820 0.8921 0.9172 0.9283 0.9349 0.9394 0.9428 0.9474 0.9506 \
0.7046 0.7836 0.8186 0.8395 0.8537 0.8642 0.8790 0.8890 0.9140 0.9251 0.9317 0.9362 0.9395 0.9442 0.9473

有些AOCV表是depth和distance而对应derate数值的二维查表,有些只是depth对应derate的一维查表,上述例子属于前者。我们可以看出,级数(depth)越深,对应的derate越小。通过这种方式来剔除部分不必要的悲观量,使得设计在尽量覆盖实际情况的前提下更加容易收敛。

接下来我们继续谈谈它们的升级版:POCV和LVF。上次我们说过,实际中由于PVT (Process, Voltage, Temperature) 导致的variation并不是一个或几个固定的值,而是服从类似高斯分布的形态。因此,反映在cell的delay上亦如此:

Normal Derating vs. POCV

POCV (Parametric On Chip Variation)

如上图所示,所谓POCV,也称SOCV(Statistical On Chip Variation),就是将cell的delay模拟成一个数学期望为 [公式] ,标准差为 [公式] 的高斯分布。简单地讲,每个cell的delay都有最高的概率出现在期望值上,有一定的概率出现在大于或者小于期望值一定范围内的区间上。整体上落在期望值 [公式] 区间内的概率为99.7%,即所谓的3 sigma。那么实际中工具是如何算得cell的delay呢?基本公式如下:

如果在.lib中提供了sigma的数值,则可以通过公式(1)算出,如果通过read_aocvm读取的POCV的参数文件(包含参数C),则可以通过公式(2)算出,这种通过给定的参数计算cell的OCV delay的方式就是’Parametric’的含义。

那么这和LVF和上面这些东西有什么关系呢?下面我们详细说说。

LVF (Liberty Variation Format)

从它的名字Liberty Variation Format我们可以看出LVF是一种和liberty库文件(.lib)有关的数据格式。我们知道一般情况下无论是AOCV或者POCV,都会有一个专门的文本文件通过特定的命令读取到工具中。以PrimeTime为例,读取AOCV和POCV的命令如下:

1
read_aocvm $file_name

而除了这种方式之外,我们还有另外一种选择:将POCV的内容集成到类似于liberty文件中,如下图所示:

Slew-Load Based LVF

我们可以看出来,这种形式很像liberty文件中的delay查表。在这里,POCV的coefficient同样是一个基于slew-load的表格。同时,LVF中也可以是基于distance的查表:

Distance Based LVF

需要注意的是,在使用LVF的时候就不能通过read_aocvm读取专用的POCV文本。在PrimeTime中我们也可以通过如下方式report POCV的结果:

Report POCV Analysis