时钟树综合需要知道每个触发器的物理位置,以便于计算到达每个触发器的最佳路径和插入适当的缓冲器。布局阶段完成后,所有单元都有了确定的坐标,这为时钟树综合提供了所需的信息。此外布局阶段不仅确定了单元的位置,还确定了大部分连线的布线。
时钟树综合需要考虑现有的连线情况,以确保时钟网络的引入不会与现有的信号线冲突。在完成时钟树综合以后,下一步将会完成进一步的布线。本篇文章我们将重点放在时钟树综合上。
在之前的阶段中,我们都认为时钟是理想的,现在既然所有的时序单元都已经放好了,我们按理说要给这些时序单元提供真正的时钟信号,才能让我们的分析变得更加准确。
一个非常简单的办法,直接用一个时钟作为Source,连接到所有的时序单元的Clock接口。可以吗?
显然不可以,这种办法没有考虑Timing、Power、Area等等一系列的问题。最显而易见的就是没有考虑时序,假设两个时序单元模块物理距离比较远,那么时钟到达的时间显然也不一样。目前的电路都是高速电路,一个时钟周期可能1ns都不到,从同一源头出发,这个时间信号可能才走到芯片的一半呢!
既然问题没有这么简单,那么我们就逐一考虑这一系列的问题,将这些问题解决了,大概也就清楚了时钟树综合到底是在做什么。
1、Implications of Clocking
回顾一下静态时序分析的基本概念,我们的时钟约束有两大约束,分别称为Max Delay约束和Min Delay约束。其本质都是评估数据信号到达触发器D端和时钟信号到达触发器Clock端的时间关系。
之前我们的分析相对简单,考虑理想的时钟信号。大家有没有想过时钟信号不是那么理想的情况?比如时钟信号到达两个寄存器的时刻不一样。这就会引入额外的参数,这个概念我们称之为Clock Skew。同样对时序造成影响的还有Clock Jitter。
Clock Skew是一个空间概念,反映的是不同寄存器之间的时钟到达关系。Clock Jitter则是相对于同一个寄存器而言,由于时钟信号的扰动之类的影响,其不同的时钟周期持续时间不一样的现象。此外时钟的上升和下降,显然不是一下子就从0到1或者从1到0,其必然需要一个时间,我们一般叫做trise,tfall。
对于Clock Skew,有一个很简单的思路,既然到达的时刻不一样,想办法让它们一样不就行了?比如到达一个寄存器比较快,我在它中间搞一点延迟,那么到达时间不就慢下来了?这种方法我们称为Insertion Delay。
下图反映了Skew和Jitter是怎么导致的。基本上由以下几个因素导致:
Clock Generation
时钟信号最初由时钟源生成,如果时钟源本身存在不稳定因素,比如晶体振荡器的老化、温度变化影响等,都可能导致时钟信号的不稳定;
Distribution Network
Number of Buffers:在时钟分布网络中,为了驱动更多的负载,会插入多个缓冲器。缓冲器的数量和类型会影响时钟信号的稳定性和传递时间;
Device Variation:即使是同一批次的器件,它们的工作特性也可能存在微小的差异,这些差异可能会导致时钟信号通过不同器件时产生不同的延迟;
Wire length and Variation:芯片内部的连线长度不同,电气特性也不尽相同,这会导致时钟信号到达各个触发器的时间不同;
Coupling:信号线之间的耦合效应也可能导致时钟信号的传播受到影响,比如相邻信号线之间的电磁干扰;
Load:不同的触发器或逻辑单元对时钟信号的负载不同,这会影响时钟信号的传递速度;
Environment Variation
Temperature:温度变化会影响器件的电气特性,包括信号传播速度和电源电压等,进而影响时钟信号的稳定性;
Power Supply:电源的波动或者噪声也会影响时钟信号的稳定性,尤其是在电压供应不稳定的情况下;
我们知道了Skew和Jitter的由来,我们再来看看它是怎么影响我们的时序分析的,通过下图我们可以非常清晰的看到Skew和Jitter对时序的影响。这里相信大家看过静态时序分析那篇文章以后,对静态时序分析有基本的理解,所以大家这里直接看图就行,我就不多做解释了。
我们再来看一下时钟对功耗的影响。对时钟网络自身而言,其作为源头,是需要一直活跃的。因此其活跃因子为1。因此我们需要考虑一下电容对功耗的影响。时钟电容主要由以下几方面组成:
时钟生成:时钟信号的产生通常涉及到锁相环、时钟分频器等电路,这些电路在产生时钟信号的过程中会消耗一定的功率;
时钟元件:时钟网络中包含的缓冲器、多路选择器、时钟门控等元件,在驱动时钟信号时会消耗功率;
时钟连线:时钟信号需要通过连线传递到芯片上的各个部分,连线的电容会对时钟信号产生负载,从而影响功耗;
时钟负载:时钟信号需要驱动所有的时序元件(如触发器),这些元件的负载也会消耗时钟网络的功率;
综上所述,时钟占据了整个芯片Power的很大一部分,考虑功耗的时候需要重点考虑这一部分。
我们再来看一下时钟网络对信号完整性的需求和影响。考虑信号完整性,意味着时钟信号在传输过程中需要保持其原始形状和质量,不受噪声和失真的影响。时钟网络上的噪声可能会导致以下问题:
首先考虑时钟网络上的噪声会产生什么负面影响。最坏的情况下,噪声会导致额外的时钟边缘,造成后级模块的误判断,以为新的时钟周期又来了。显然这样会造成严重错误。即使噪声没有引起额外的边沿,较低的耦合效应仍然可能减缓或加速时钟信号的传播,导致时钟偏斜。不规则的时钟边沿可能会阻碍触发器的正常操作,因为触发器需要精确的时钟边沿来同步其操作。
然后考虑一下时钟边沿上升下降缓慢会带来什么影响。时钟信号的过渡时间过长可能会导致触发器无法在正确的时间窗口内识别时钟边沿,影响其设置和保持时间。此时对噪声的容忍性会进一步下降。还会导致触发器的性能下降,比如更差的建立时间保持时间。
那是不是上升下降越快越好呢?就像理想情况一样,直接就从1到0或者从0到1。其实也不是,虽然快速的时钟过渡通常被认为是理想的,但如果过快,可能会导致功率消耗增加、设计过度复杂化,以及对其他信号的干扰增大。
此外如果时钟网络中的driver不平衡,会导致时钟偏斜的增加,从而影响电路的同步性能。
一个比较好的建议,将trise和tfall设置为时钟周期的百分之10到百分之20。
我们再来看一下时钟网络对面积的影响。时钟网络包括时钟生成器、时钟元件和时钟连线,所有这些都会占用芯片面积。
时钟生成器:例如锁相环(PLL),可能会非常大,因为它需要包含振荡器、相位检测器、电荷泵、滤波器等多个子组件。
时钟缓冲器:时钟缓冲器分布在芯片的各个部分,以便驱动时钟信号到达每个时钟元素。这些缓冲器的总和会占用相当大的面积。
时钟连线:时钟连线会消耗大量的布线资源。在芯片设计中,布线资源是非常宝贵的,因为它们决定了信号如何在芯片上传播。
此外我们需要考虑布线资源的重要性,为了实现快速和干净的时钟信号过渡,需要低的电阻-电容(RC)时间常数。这意味着时钟网络需要高质量的布线资源。为了减少电阻,通常会选择high、wide的金属层来布线时钟信号,因为这些金属层通常更宽,电阻更低。
时钟网络需要连接到芯片上的每个时钟元素,这意味着时钟连线需要遍布整个芯片。此外为了从高层次的金属层连接到低层次的金属层,需要使用叠孔,这也会占用额外的面积,并可能增加延迟。
2、Clock Distribution
所以我们怎么构建时钟树呢?
我们看一下需要做到什么。首先考虑只有一个时钟源头,有多个Sinks。我们需要将他们连接起来。同时让Clock Skew,Delay,整体的Wire length,噪声和耦合效应都尽可能的小。
我们的挑战是什么?
同步数百万(数十亿)个独立元素:在现代集成电路中,可能包含数百万甚至数十亿个需要同步的元素,如触发器、寄存器等。
在10 ps的时间尺度上同步:这些元素需要在极短的时间内同步,大约在10皮秒(ps)的量级上。这是一个非常短暂的时间窗口,要求时钟信号必须非常精确和稳定。
跨越2-4 cm的距离:时钟信号需要在芯片上传播很长的距离,通常在2到4厘米之间。这样的距离在芯片内部是一个相对较大的范围。
同步距离与元素尺寸的比例约为10^5:这意味着时钟信号需要在一个非常大的范围内同步非常小的元素,这是一个巨大的挑战。
参考:光在1 cm内传播需要10 ps:光在10皮秒传播不到1cm。这是一个理论上的极限,实际上的电子信号传播速度远低于光速。
总结来说,时钟路由的挑战在于如何在极短的时间内,将时钟信号精确地同步到芯片上每一个角落的元素,同时还要克服信号在传播过程中的延迟和衰减。这要求设计师采用先进的时钟树综合技术,优化时钟网络的布局和布线,以确保时钟信号的稳定性和同步性。
我们看一下目前的技术趋势。我们都知道时钟频率目前变得越来越高,随着时钟频率的提高,对始终偏斜以及信号过渡的要求也越来越高。此外随着CMOS工艺的缩小,PLL的性能得到改善,有助于减少时钟抖动,但与此同时其它噪声源可能会增加,比如电源噪声和温度梯度。
铜互连的使用降低了电阻-电容(RC)时间常数,有助于改善信号过渡和潜在的时钟偏斜。低介电常数(low k)材料可以减少时钟功耗,改善延迟、偏斜和过渡率。
随着设计的深入流水线化,使用了更多的寄存器,这增加了时钟网络的电容负载。更大的芯片尺寸需要更长的连线来覆盖整个晶圆,增加了时钟网络的复杂性和功耗。随着功能的增加和器件的增多,更多的元素需要时钟信号,这进一步增加了时钟网络的负担。动态逻辑设计中,通常会有更多的元素需要时钟信号,这也会增加时钟网络的复杂性。
根据不同的设计需求和目标,时钟综合可以采用不同的方法,主要包括以下几种:
时钟树(Clock Tree):这是传统的时钟分布方法,它从单一的时钟源开始,通过一系列的缓冲器(buffers)和驱动器(drivers)将时钟信号分支传递到芯片上的各个触发器。时钟树的设计旨在平衡每个触发器看到的时钟路径长度,以减少时钟偏斜。
时钟网格(Clock Mesh/Grid):时钟网格是一种全局时钟分布网络,它由水平和垂直的时钟线组成,这些线在整个芯片上形成一个网格状结构。时钟网格的设计可以提高时钟信号的均匀性,减少时钟偏斜,并且有助于应对随着芯片尺寸增大而增加的时钟分布挑战。
时钟脊柱(Clock Spines):时钟脊柱是一种介于时钟树和时钟网格之间的时钟分布方法。它通常包括一些主要的垂直或水平时钟线,这些线充当主时钟路径,然后通过分支将时钟信号传递到芯片上的各个部分。时钟脊柱的设计旨在提供一种平衡的方法,既能够减少时钟偏斜,又能够简化时钟网络的复杂性。
每种方法都有其优势和局限性,设计师需要根据具体的电路设计、性能要求和工艺技术来选择合适的时钟综合方法。随着集成电路尺寸的增大和性能要求的提高,时钟综合变得越来越具有挑战性,需要更加先进的工具和算法来支持。
我们来看一下时钟树。时钟树是集成电路中用于分布时钟信号的一种结构。在设计中,一个简单但非实用的方法是为每个时钟终点(sink)单独布线,并平衡RC延迟。然而,这种方法会导致功耗过大,且每个网线的较大RC值可能会引起信号完整性问题。
为了避免这些问题,实际中会使用缓冲器树(buffered tree)结构。这种方法的特点和优势包括:
短网线意味着更低的RC值:通过使用缓冲器树,每个时钟网线的长度可以缩短,从而降低RC(电阻-电容)值。短的网线可以减少信号延迟和功耗。
缓冲器恢复信号:在时钟信号传播路径上插入缓冲器可以帮助恢复信号强度,提高信号的过渡速率(slew rates),确保时钟边沿的清晰和可识别。
降低总插入延迟:由于RC值较低,整个时钟树的插入延迟(insertion delay)也会降低,这有助于减少时钟偏斜。
减少总的开关电容:缓冲器树可以减少时钟网络上总的开关电容,因为每个缓冲器只需驱动较少的负载。这有助于降低时钟网络的动态功耗。
总之,时钟树的设计目标是在功耗、信号完整性和时钟偏斜之间找到平衡。通过使用缓冲器树,设计师可以有效地管理这些设计约束,实现高效且可靠的时钟分布。
让我们来构建一个实际的时钟树,可以看到下图这个形状,非常像H。所以我们称之为H-Tree。它具有以下特点:
一个大的中心驱动器:H-Tree从一个大的中心驱动器开始,向四个方向(或者更多的方向,取决于设计的复杂性)分支。
递归的H形状结构:H-Tree使用递归的H形状结构来匹配连线长度,确保时钟信号到达各个触发器的时间大致相同。
在分支点减半连线宽度:在H-Tree的分支点,连线的宽度会减半,这样做可以减少信号反射,提高信号质量。
然而,这种完美平衡的H-Tree在实际应用中很难实现,因此更现实的方法是使用锥形H-Tree(Tapered H-Tree),其试图实现平衡,但更加灵活,以适应实际设计中触发器不均匀分布的情况。
标准的时钟树综合(CTS)方法会考虑到触发器的实际分布,尝试构建一个平衡的时钟树。在CTS过程中,工具会根据触发器的位置和时钟网络的需求来自动放置缓冲器,并调整连线的长度和宽度,以实现最佳的时钟分布。
我们来看两个工业界的芯片的时钟网络,其使用了H-Tree。
我们再来看一下时钟网格,其相对于时钟树有什么区别呢?首先我们看一下时钟网格长什么样子,可以看到其前面仍然是时钟树,但真的驱动的时候,将flip flop放到一个个的格子中,然后直接通过连线进行驱动。它有以下几个优点:
时钟偏斜由网格密度决定:时钟网格通过均匀分布的网格线来提供时钟信号,因此时钟偏斜主要取决于网格的密度,而不是特定负载的位置。
时钟信号无处不在:由于时钟网格覆盖整个芯片,因此时钟信号几乎可以在芯片的任何地方获得。
对工艺变化的容忍度高:时钟网格的结构使得它对制造过程中的变化不那么敏感,因此可以提供更加稳定的时钟分布。
通常能够实现极低的时钟偏斜:由于时钟网格的设计方式,它通常能够实现非常低的时钟偏斜值。
然而,时钟网格也有一些缺点:
大量的布线和功耗:时钟网格需要大量的布线,这会导致功耗的增加。
连线电容大:由于时钟网格的布线范围广泛,因此连线的电容也会很大。
需要强大的驱动器:为了驱动这样的网格,需要强大的驱动器,这意味着驱动器的预驱动电容也会很大。
布线面积大:时钟网格占用了大量的芯片面积,这可能会影响其他电路元素的布局。
为了最小化这些缺点,可以使网格间距变得更粗,但这样做会导致时钟偏斜变差,从而失去了时钟网格的主要优势。设计时不应过度设计,而是应该让时钟偏斜尽可能大,只要它仍然在可容忍的范围内。
此外时钟网格对于片上系统来说似乎并不可行,这是因为SoC的复杂性和对功耗、面积的限制。因此,设计师需要根据具体的应用和设计约束来选择合适的时钟分布方法。
我们看几个工业界的例子,可以看到时钟网格的Driver Size很大。其Skew相比于时钟周期而言非常的小。
时钟脊柱(Clock Spines)是一种用于时钟分布的替代方法,它旨在减少时钟网格所导致的功耗和布线资源的消耗。时钟脊柱的设计理念是构建一个中心脊柱,然后从脊柱向外辐射时钟信号,以实现时钟的局部分布。
以下是时钟脊柱的一些关键特点:
构建H Tree到每个脊柱:与时钟网格不同,时钟脊柱设计中会构建一个中心脊柱,然后从脊柱向外辐射时钟信号。这种设计类似于H Tree结构。
从脊柱辐射本地时钟分布:时钟脊柱的设计允许从脊柱向各个方向辐射时钟信号,以实现对本地区域的时钟分布。
减少功耗和布线资源:与时钟网格相比,时钟脊柱的设计减少了布线资源的需求,因为它不要求在每个方向上都布设时钟线。这有助于降低功耗。
Pentium 4是早期采用时钟脊柱设计的一个例子。它表明时钟脊柱在实际应用中是可行的,并且能够满足当时的设计需求。
当然时钟的设计非常复杂,上面也是简单介绍一下。这里我们简单总结一下这三种时钟网络的区别:
此外还有专用的Skew管理机制。
我们来看一下时钟并发优化。不要忘记CTS的主要目标,我们的核心目标是要满足时序要求和DRV约束。时钟偏斜的减少只是作为时钟综合与后端设计(post-CTS)和前端设计(pre-CTS)之间时序相关性的一个指标。实际上,我们更应该关注的是满足时序和驱动约束。
CCOpt提出了一种新的时钟综合方法,它不再将时钟偏斜作为唯一目标,而是同时考虑时序和驱动约束,以及功耗和面积的优化。在构建时钟网络时,CCOpt方法会考虑时序和驱动约束,而不是仅仅关注时钟偏斜。这有助于在满足性能要求的同时,减少功耗和面积的浪费。
其首先构建一个时钟树,然后检查时序并修复任何违反时序要求的地方。这种方法之所以有效,是因为大多数时序路径都是局部的,它们可能来自同一个时钟分支,因此不需要太多的时钟偏斜平衡。
以下是这种方法的一些优点:
局部的时序路径:大多数时序路径都是局部的,这意味着它们通常来自同一个时钟分支。因此,这些路径不需要太多的时钟偏斜平衡来开始;
减少时钟偏斜平衡:由于时序路径的局部性,可以减少时钟偏斜平衡的需求。这有助于降低插入延迟,因为时钟信号到达触发器的时间更短;
降低功耗和面积:由于减少了时钟偏斜平衡的需求,因此可以减少时钟缓冲器的数量,从而降低功耗和面积的消耗;
电流分布的优化:减少时钟偏斜平衡有助于优化电流分布,减少IR Drop的影响;
有用的时钟偏斜:尽管减少了时钟偏斜平衡,但仍会保留一定程度的时钟偏斜,这对于时序路径上的局部时序要求是有益的。比如可以在建立时间紧张的寄存器,你让时钟晚一点到来,这属于合理利用Skew;
总的来说,CCOpt方法通过首先构建一个基本的时钟树,然后根据时序要求进行调整,可以在满足时序要求的同时,减少功耗和面积的消耗。这种方法强调时序路径的局部性,并在此基础上进行时钟网络的设计和优化。
3、Clock Tree Synthesis in EDA
我们来看一下实际EDA工具是如何进行时钟树综合的。这里我们将以Cadence的Innovus为例进行说明。
首先我们再明确一下,我们在时钟树综合之前已经有了什么,基于这些东西我们需要做什么,实现什么。
我们需要满足DRV约束,比如最大扇出,最大电容,最大长度等等。还要尽可能减少Skew,减少Insertion Delay。
我们来看一下时钟树由哪些部分组成?
起始点:时钟树的起始点是时钟端口或时钟生成器的输出引脚,这是时钟信号的源头,所有的时钟信号都是从这里开始传播的;
叶子节点/终点:时钟树的叶节点或终点是指时钟信号最终到达的地方,通常是寄存器、存储器等同步元件的时钟引脚,理论上时钟信号必须在这些点上同时到达,以保持数据的同步性;
缓冲器/反相器:缓冲器和反相器是时钟树中的重要组成部分,它们用于驱动时钟信号,确保时钟信号的转换能够满足设计要求。通过插入缓冲器或反相器,可以调整时钟路径的延迟,以减少时钟偏斜;(比如通过两个反相器,让信号0和1变得更分明,变得变强)
特殊逻辑:包括多路复用器、集成的时钟门控、时钟分频器等。这些逻辑单元可以用来控制时钟信号的分布,例如,通过时钟门控来关闭不需要的时钟信号,以降低功耗;
我们需要一种“语言”来定义这些(以及其他)组件,接下来我们会讨论CCOpt方法中对这些的命名规定。
我们再来回顾一下什么是Source和Sink。
Clock Source:
Clock Source是指时钟信号发散出来的引脚,是时钟树的起点;
Clock Source可以是:(这三个直接看下图就可以理解,很清楚)
设计的主要输入端口,例如一个外部时钟信号输入到芯片;
一个IP核的输出引脚,比如一个锁相环(PLL)的输出,PLL通常用于生成稳定且频率可调的时钟信号;
一个门控电路的输出引脚,例如时钟复用器或时钟门控的输出。这些电路用于控制时钟信号的路由和开关;
Clock Sink:
Clock Sinks是指所有接收时钟信号的引脚,是时钟树的终点。
Clock Sinks可以是:
寄存器(触发器FF或锁存器latch)的时钟输入引脚;
IP核的时钟输入引脚,比如SRAM,这种我们也成为Macro单元;
主要输出端口,比如时钟信号需要从当前模块驱动到外部;
我们再来看一下Skew Group这个概念。我们有很多很多的Sink,我们将一部分Sink划分为一个Skew Group,用于分析和控制Skew。默认情况下,时钟树所有的Sinks属于同一Skew Group。
然而,这些Sink也可以被划分为几个时钟偏斜组,这样可以更精细地控制时钟偏斜。(有点像之前的Timing Group的概念)
此外不同时钟的接收端可以属于同一个时钟偏斜组(例如,时钟和生成的时钟),这意味着它们在时钟树上可能共享相同的路径或缓冲器,甚至一个接收端可以同时属于多个时钟偏斜组。
我们再来看几个关于Pins的概念。
Stop Pins
时钟树的叶子节点,时钟网络将缓冲到停止引脚,但不会接着往下传递了;
所有时钟接收端都是隐式的停止引脚,因此,按理说这些引脚需要进行时钟偏斜平衡/分析(隐式代表不要额外去声明,与之对应的我们可以定义显式的停止引脚,比如一个反相器,我们不希望时钟顺着它接着往下传递了,就可以显式的声明出来);
要在CCOpt中定义额外的引脚作为停止引脚,使用下图中的命令;
Ignore Pins
本身是时钟网络上的引脚,但它们在任何时钟偏斜组中都不会被视为时钟接收端,因此也就不需要进行时钟偏斜平衡/分析;
时钟网络将缓冲到忽略引脚,但不会接着往下传递了;
Exclude Pins
与Ignore Pins相似,但时钟网络不会缓冲到Exclude Pins;
Through Pins
Through Pins是指那些本来会被视为Stop pins的引脚,但我们希望时钟信号能够通过它们传播(用于缓冲和将引脚添加到时钟偏斜组中);
在Innovus的新版本中,没有明确的命令来定义穿越引脚。只需将其称为Ignore Pins;
简单来说在时钟树综合的过程中,Through Pins允许时钟信号在不被视作最终接收端的情况下通过某些节点。这样做可以保持时钟网络的连续性,同时允许在这些节点上进行缓冲和其他操作,以优化时钟网络的性能。在Innovus的新版本中,不再需要显式地定义穿越引脚,而是通过将它们标记为忽略引脚来实现相同的功能;
我们再来看一个概念,Insertion Delay Pin,也可以叫做float pin。这个Pin角对应Macro比如SRAM的时钟输入引脚。
这个引脚到其内部的时钟引脚还有一段逻辑。就比如下图,其还需要X,这个时候如果我们要保证时钟平衡的话。我们就应该让时钟信号到这个Macro的时钟引脚早一点,从T变成T-X。其写法如下所示。
让我们来总结一下上述的Pin角类型。Stop Pin非常好理解,就是终点,时钟到这里就停下来了,不会接着传了。Exclude Pin是完完全全可以忽视的Pin,什么规则都不用满足。而Ignore Pin尽管叫这个名字,但还是要进行DRV fixing的。
来看一下Clock Net的Routing问题。由于Clock nets对于信号完整性影响非常大,前面也已经介绍过了。所以对待其相比对待别的Net,有额外的工作要做。
我们在时钟树综合的时候要对其进行Pre-route,来快速检查一遍。此外还需要:
优先选择布线轨道:
为了减少电阻和电容,我们通常优先选择更高、更厚的金属层来布线时钟网络。高层的金属通常具有较低的电阻,而且与衬底的电容较小,这有助于提高时钟网络的性能。
屏蔽时钟网络:
屏蔽是一种常用的技术,用于减少时钟网络对其他网络的干扰。通过在时钟网络周围添加保护层或使用专门的屏蔽轨迹,可以减少电磁干扰(EMI)。
考虑在时钟缓冲器旁边添加去耦电容(DeCaps):
去耦电容可以用来过滤时钟缓冲器输出端的噪声,提高时钟信号的稳定性。这些电容通常放置在时钟缓冲器的附近,以减少电源噪声对时钟信号的影响。
我们怎么在Innovus中布线时钟nets呢?首先,既然这些nets很特殊,就不能用默认规则,要使用非默认规则即Non-Default Rules(NDRs)。比如double-width/double-spacing。
同时还需要指定Routing类型,定义首选的布线层和屏蔽技术。
在Innovus中,我们将时钟网络分为三种类型:
顶部(Top)时钟网络,即时钟树的初始分支,通常非常宽和高;
主干(Trunks)时钟网络,即时钟树的主要分支,也比较宽和高;
叶子(Leaf)时钟网络,即时钟树的底层,更接近逻辑单元。
综上,我们将定义NDRs和布线规则,然后将它们应用到时钟网络上。
我们来看一个具体的例子:
首先,定义NDR规则,比如Double width和Double Spacing,定义方式如下图所示。这个规则的名字叫做CTS_2W2S
。我们定义的规则允许我们指定时钟网络布线的特殊要求,例如更大的线宽、间距或特定的布线层。
然后我们创建用于时钟树综合的routing type ,type名字叫做cts_trunk
。在Innovus中,布线类型允许我们定义首选的布线层和屏蔽。这意味着在设计时钟网络时,我们可以指定时钟信号应该优先在哪些金属层上布线,以及是否需要采取屏蔽措施来保护时钟信号免受干扰。此外routing type是基于我们上述定义的NDR的,也就是说routing type可以理解为在NDR上的进一步规则定义。
最后我们上述定义的属性作用在trunk类型的网络上。这样,Innovus就会根据定义的NDR和布线类型来布线时钟网络,确保时钟信号的质量和完整性。
在运行时钟树综合之前,对设计中的每个时钟树进行分析是非常重要的。分析的目的是为了确定以下几个关键方面:
确定时钟树的根节点,即时钟信号的发散点,通常是一个时钟生成器或时钟源的输出引脚。
确定时钟信号应该到达的所有时钟汇(如寄存器、触发器等)以及可能需要特殊处理的时钟树例外情况。
检查时钟树中是否已经包含了某些预存的单元,例如用于时钟门控的逻辑单元。
确定时钟树是否收敛,即是否存在自身收敛的时钟路径(一个时钟树的多个分支最终汇合)或与其他时钟树重叠的时钟路径。
分析时钟树之间是否存在时序关系,例如跨时钟偏斜要求。
确定DRV约束,包括最大扇出、最大转换时间和最大电容等。
选择合适的库单元来构建时钟树,这些单元应该满足设计的要求,并且与工艺相兼容。
确定布线约束,包括布线规则和金属层的选择。这些约束将指导CTS工具如何布线时钟网络,以确保信号质量和满足设计约束。
通过这些分析,设计者可以确保时钟树综合的结果能够满足设计的时序和性能要求,同时还可以避免潜在的问题,如时钟偏斜过大、时钟抖动过多等。这有助于提高整个数字系统的可靠性和稳定性。
我们看一下Clock Tree优化前后的对比。包括但不限于使用Gate relocation、Buffer relocation、Buffer Sizing等技术。
我们再看看时钟树综合以后,对时序的影响。可以看到之前认为时钟是理想的,现在引入了positive skew和negative skew。为了解决这一点,我们按理说就得对input delay和output delay,把这个因素给考虑进来。
想象一下入口和出口有两个Virtual寄存器,其Clock Skew存在不平衡。我们可以通过设置Input Delay和Output Delay,做到时钟平衡。
我们看一下如何减少时钟分布问题,下面的很多方法其实用的不太多,大家可以自己看看。
4、Clock Generation
前面讲了这么多,我们来看看时钟是怎么生成的。最简单的方法就是用环形振荡器,如下图右上角所示。但这种方法虽然简单,但不是很稳定,很容易受到PVT的影响。
因此我们通常是在芯片外部使用专用的晶振电路产生时钟,但这个片外时钟只有一个,并且时钟频率很受限,如果要实现高频和分频呢?我们就需要使用片上的专用时钟生成器,通常是PLL。
基于上述的方案的电路大概长这样,可以看到我们实现了时钟的倍频和分频。
PLL长什么样呢?其大概长下面这个样子。锁相环基本的组成部件:检相器 (PD)、环路滤波器 (LF) 和压控振荡器 (VCO)。作为一个负反馈系统,在反馈回路中VCO的输出被分频器分频到低频后,通过检相器和参考时钟比较产生相位差信号,接着该相差信号在前向通路上,被电荷泵和环路滤波器处理后产生电压控制信号,从而反过来控制VCO的输出。锁相环锁相环,关键是把相位给锁住。
我们简单看一下PD长啥样。其输入自然而然有两个时钟信号,我们假设一个是Ref,一个是F_IN。如果REF先来,那不就是慢了吗,我们要把时钟往前挪动。类似的如果F_REF先来,那就要把时钟往后挪动。
电荷泵和积分器长下面这样,我们已经有了UP和DOWN信号。如果F_IN和F_REF一样,那么就不需要充放电,V_C保持不变,输出频率也不变,否则就需要改变输出频率。
这个电压就会用来控制Delay Line。我们看下图,如果电压不变,是不是Delay也就不变?如果电压改变了,Delay-line的Delay也改变了,进而影响到频率。
我们把上面这个东西集成一下,就是VCO了。也就是压控振荡器。
5、Clock Domain Crossing
跨时钟域可以说是面试必问的一个问题了。为什么要考虑跨时钟域问题呢?其本质是建立时间和保持时间的要求决定的。如下图所示,DA到DB的时候,由于CLKA和CLKB是异步时钟,其无法保证建立时间的要求,所以就会出现亚稳态。
我们看一下跨时钟域主要的问题有哪些:
亚稳态:
亚稳态是指一个触发器(flip-flop)的输出在稳定的高电平或低电平状态之间的一种不稳定状态。当异步信号在触发器的建立时间(setup time)和保持时间(hold time)窗口内发生变化时,就可能会出现亚稳态。亚稳态可能导致的问题包括:
在扇出处产生高的传播延迟。
在芯片内产生高电流流动,可能会导致芯片损坏。
在扇出的不同部分出现信号的不同值
数据丢失:
数据丢失可能发生在源端产生新数据时,而目的端尚未捕获前一个数据。在异步系统中,由于时钟不同步,这种数据丢失的情况更为常见。
数据不一致
数据不一致性是指数据被延迟捕获,导致多个相关信号处于不同的状态。这种情况可能会在多时钟域系统中出现,当一个域中的数据更新速度与其他域不同步时,就会导致数据的不一致性。
通过同步器可以解决亚稳态问题,通常采用双DFF同步,其让亚稳态出现的频率变得非常低。值得注意的是其只是消除亚稳态,并不能保证是0还是1。
同步器就足够了吗?并不是,同步器只解决了亚稳态,没有解决数据丢失问题和数据不一致问题。
以数据不一致为例,我们想象一下有多个bit,都采用同步的方式,其到达的时间有前有后,比如01变成10,采样得到的可能是11(低比特还没有采到变化以后的值)。
为了消除数据丢失,我们可以采取以下措施:
慢时钟到快时钟:如果数据从慢时钟域传输到快时钟域,由于快时钟域的时钟周期较短,可以在多个周期内采样慢时钟域的数据,从而不会丢失数据。
快时钟到慢时钟:如果数据从快时钟域传输到慢时钟域,快时钟域的数据需要在源端保持多个周期,以确保慢时钟域有足够的时间采样到数据。
为了确保数据一致性,我们需要考虑更多的因素:
握手协议:通过握手协议,源时钟域和目的时钟域可以相互确认数据已经准备好并被接收,从而确保数据的连贯性和一致性。
异步FIFO接口:异步FIFO可以在不同的时钟域之间提供一种缓冲机制,确保数据按照顺序传输,避免数据丢失和一致性问题。
即使不用异步FIFO,也可以单独使用格雷码,其可以减少在跨时钟域传输时出现的数据不一致。但针对的是顺序变化的数据才有意义,比如顺序访存地址。以上述的01变成10为例,格雷码就将其转换成了01变成11。这样你要么采到01要么采到11,只会采到旧的值或者新的值,而不会采到错误的值。还可以使用Mux实现跨时钟,具体的可以搜相关资料了解一下。
系列文章入口——
【芯片验证】sva_assertion: 15道助力飞升的断言练习 |
【芯片验证】可能是RTL定向验证的巅峰之作 |
【芯片验证】RTL仿真中X态行为的传播 —— 从xprop说起 |
【芯片验证】年轻人的第一个systemVerilog验证环境全工程与解析 |
【芯片设计】verilog中有符号数和无符号数的本质探究 |
【芯片设计】论RTL中always语法的消失术 |
【芯片设计】代码即注释,注释即代码 |
【芯片设计】700行代码的risc处理器你确实不能要求太多了 |
入职芯片开发部门后,每天摸鱼之外的时间我们要做些什么呢 |
如何计算系统的outstanding 和 burst length? |
芯片搬砖日常·逼死强迫症的关键词不对齐事件 |
熟人社会里,一群没有社会价值的局外人 |