众所周知,PPA(功耗、性能、面积)这三个要素的合理平衡,是一款芯片能否成功的重要因素,Power Performance Area中,performance的衡量可以有很多因素,其中就包括频率性能,也就是时序需求,STA静态时序分析就是检查所设计的电路是否能满足时序需求的方法,设计工程师会在综合之后根据设计的sdc进行一次初步的STA检查,但是在综合阶段,许多关于时钟网络的假设其实是不可用的,只有当完成布局规划,做完时钟树综合,才能得到一个相对准确的时序分析结果,因此DE(数字电路)工程师是第一遍尝试STA分析的芯片设计人员。
常规的芯片设计团队往往很少考虑时序问题,因为对于他们而言,他们的目标更多的聚焦于如何实现功能需求,物理设计团队负责满足时序要求,但是他们不清楚设计的内部结构,因此他们需要依靠于DE来实现时序约束。约束领域充满了细微的差别:不同的约束方式,虽然可能对于逻辑功能来说区别不大,但是会实打实的影响硬件设计的性能,进而影响芯片的质量,因此正确的理解和书写约束,变得非常重要。
时序约束最终是作用在真实电路上的延时约束,从Verilog这样一个行为级的描述过渡到真实的电路所需要经历的步骤被叫做综合,因此在绪论中,我们也需要搞明白综合是什么和综合是怎么作用在时序约束上的这两大问题。
综合(Synthesis)是指将高级硬件描述语言(如Verilog或VHDL)表示的逻辑设计转换为物理可实现的逻辑门级网表的过程,包括逻辑转化、优化、时序约束处理、功耗优化。在约束条件(时序约束、面积约束)下,使用特定厂商的工艺库(TSMC 7nm/5nm),将RTL代码(Verilog),转变为网表(记录wire/DFF等门级电路信息)的一个步骤。
在综合过程中,时序约束被用于指导和控制逻辑综合,确保最终的电路满足设计时序要求.以下的例子切实的反映了综合结果对于时序的影响,两种逻辑排布在逻辑的层面上是一样的,有着相同的真值表,但是对于第一张图片而言,输入经过两级逻辑就可以抵达输出Y,而对于下面的图片而言,输入需要经过三级逻辑才可以抵达输出Y,具体选择哪种逻辑是根据时序约束决定的,通常情况下,大家会认为第一种会比第二种排列好,因为delay少。
但这个说法实际不绝对,因为delay的长短可以分别使建立时间和保持时间的压力变小,不过修保持时间的方法简单,修建立时间的方法复杂困难,
修改建立时间的方法相对较为复杂,可以降频,优化电路路径、调整寄存器的位置
修改保持时间的方法相对较简单,可以通过增加延时元件或添加插入缓冲区等方式实现,
因此更倾向于使用第一种逻辑排布,优先保证建立时间
增加buffer修改保持时间如下:
综合出来的电路中,第二种逻辑排布的output1,output3和output4分别插入了buffer,增强了驱动,因此他们这几个端口的后续门电路的开启和关闭会比output2快(电子在端口的积累速度快),在这种层面上影响了静态时序分析的结果。
建立时间是在时钟信号有效沿到达之前,输入信号需要保持稳定的时间(采样时钟的上升沿 到达 数据起始位置的时间),如不满足建立时间的要求,就可能产生亚稳态,这种现象被称作建立时间违例。
在考虑建立时间违例的极限情况,我们需要保证数据到达的时间,至少比时钟边沿到达的时间,早一个setup time,而前一个寄存器的采样,又比后一个寄存器的采样,早一个周期,因此我们可以列出式子如下
tclk-q + tlogic+tsetup<=tskew+T
tsetup <= T - tlogic - tclk-q + tskew
因此,解决建立时钟违例的方法,就是使等式的右边尽可能的大一些。
方法在于,比如增加tskew,clock通路上插入buffer,减少寄存器之间的组合逻辑,降低时钟频率以增加T,更换DFF器件以降低tclk-q等。
建立时间的检查可以确保移动最慢的数据也能及时到达并满足建立的标准,因此,它又被称为最大分析(max analysis)。由于建立检查考虑了最晚到达的数据,所以也被称为晚期分析(late analysis)在建立时间的检查中,最大分析通常用于确定最大可能的延迟和最小建立时间来评估时序约束是否满足。
保持时间是在时钟信号有效沿到达之后,输入信号需要保持稳定的时间(采样时钟的上升沿 到达 数据结束位置的时间)
在考虑保持时间违例的极限情况,我们需要保证数据改变的时间比时钟沿到来的时间,至少晚一个holdtime。数据改变所需的时间,对于前一个寄存器而言,是指第二个时钟边沿到来时的数据移动的时间,对于第二个寄存器而言,也是指第二个时钟边沿到来的时间,因此我们可以列出式子如下:
tclk-q + tlogic>=tskew+thold
thold <= tclk-q+tlogic-tskew
其中tclk-q是数据从前一个寄存器的clk到q的时间,tlogic是寄存器间的组合逻辑,tskew是前后寄存器时钟边沿到达的时间差,移项,为了解决违例,我们的目标是使右边的值尽可能大
我们可以增加tclk-q的值,换一些更慢的DFF,也可以增加tlogic的时间,这就是我们在本专栏绪论中所说的未必一定要减少组合逻辑delay的原因,当然,减少skew也可以解决holdtime violation的问题。
但是,修hold time violation比修setup time violation更简单,因为只需要在组合逻辑路径上插入buffer,我们就可以很迅速的解决hold time violation问题。
保持时间的检查可以确保即使是移动最快的数据也不应该干扰其他数据,同时期望数据保持稳定。因此,数据路径计算最小延迟,被称为最小分析(min analysis)由于保持检查考虑了最早到达的数据,所以也称其为早期分析(early analysis)
STA分析能够进行的基础,是任何的同步电路,时序路径都可以进行拆分,拆分成几类,统一进行建立时间、保持时间的检查,根据约束,来判断是否有违例发生。
每一条需要分析的路径,都有其自身起点和终点,因为我们在讨论建立时间保持时间的过程中,判断主要发生在:时钟沿到来的时间和数据到来的时间,因此不难区分出STA可能的起点和终点
即5条红线
裕度是指:满足电路最低建立时间、保持时间以外的额外的冗余量,因此:我们通常情况下希望,首先,电路是不能有违例的,其次,冗余量越大越好。
建立slack = 数据建立要求 - 最后一个到达的信号
保持slack = 最早到达的信号 - 数据稳定的要求
上面的电路图为一个典型的同步电路,包含组合逻辑和时序逻辑,是一个经典的时序分析案例
上面的电路图为一个典型的同步电路,包含组合逻辑和时序逻辑,是一个经典的时序分析案例,我们可以找到全部的5条时序路径。对该电路进行分析,我们可以得到如下的时序报告,接下来就让我们看看这个报告中包括什么内容。
在这份timing report中,Start Point为:UFF1的clk端;而Endpoint为:UFF2的clk端
除了起始点与中止点外,我们还能得到路径时钟域的归属,为CLKP,需要注意的是:起点的时钟和终点的时钟有可能不相同,但无论哪种情况,路径组合(Path Group)总是被归属于终点寄存器的时钟
建立时间的检查可以确保移动最慢的数据也能及时到达并满足建立的标准,因此,它又被称为最大分析(max analysis)。由于建立检查考虑了最晚到达的数据,所以也被称为晚期分析(late analysis)
保持时间的检查可以确保即使是移动最快的数据也不应该干扰其他数据,同时期望数据保持稳定。因此,数据路径计算最小延迟,被称为最小分析(min analysis)由于保持检查考虑了最早到达的数据,所以也称其为早期分析(early analysis)
本Timing Report中,Path Type为max,说明了这个是一个建立时间检查相关的时序报告,假如Path Type为min的话,就是一个保持时间检查相关的寄存器
表头有三项内容,分别是Point,Incr和Path。
Point代表着时序分析的点是哪一个,比如其中的”UFF1/CK(DFF)“就是第一个寄存器的clock端。
Incr为incremental delay,代表着一个分立的delay值,比如说经过组合逻辑的门电路,和寄存器的D到Q,都会产生各自的incr值。
Path为Path delay,是Incr delay的累加和。
在Path端,我们可以发现一列数字,0.00、0.17f、0.26r,其中的f就是下降沿检查,r是上升沿检查
整个表格笼统上可以分为上下两部分,上半部分为data到达的时间,下半部分为data需要的时间,是否发生违例(建立时间违例与保持时间违例),用下面的时间减去上面的时间可以得到slack值,假如slack是正值,时序违例没有发生,假如slack是负值,说明发生了时序违例,需要按照第二节的方法去修改建立时间或者保持时间
首先,我们需要强调的是,我们静态时序分析简明教程四的前提,是同步设计电路,STA的静态时序分析,对异步电路,是无效的。
其次,在我们对时钟进行约束的条件下,我们需要掌握时钟的三个特性,他们分别是
create_clock -period period_value
[source_objects]
[-name clock_name]
[-waveform edge_list]
[-add]
[-comment comment_string]
-period 选项用于定义时钟周期,通常情况下,时钟信号的单位默认是ns,但是我们也可以通过set_units设置ps等时钟单位。
create_clock -period 10 代表设置了一个时钟周期为10ns的时钟信号,即100Mhz的时钟频率
当我们确定了时钟周期后,我们也需要将时钟信号对应于某一个源对象(比如说是一个clk的端口,或者是触发器的引脚P、网络N),这一步操作就像是将一个STA中的时钟信号映射到电路层面的某一个对象加以驱动,我们可以使用如下的语句加以标识
#代表作为时钟源端口
create_clock -period 10 [get_ports A]
#代表作为时钟源的网络
create_clock -period 10 [get_nets N]
#代表作为时钟源的引脚,若触发器的名称为FF的话
create_clock -period 10 [get_pins FF/P]
当我们将端口做映射后,一个紧接着出现的问题就是这个时钟的命名,假如我们不单独指定名称,工具会将一个默认的名称赋值给该时钟,在STA的时序分析中,时钟的名称是很重要的信息,因为一旦时钟信号被定义和命名的话,其他所有依赖这个时钟的SDC命令,只需要提到该时钟即可。我们通过 -name 的尾缀来命名时钟,比如
#创建一个10ns的时钟,映射到端口A,时钟命名为PCLK
create_clock -period 10 [get_ports A] -name PCLK
这里我们可以简略一点,因为对于数字电路而言,占空比不是1:1的电路结构,种类很少,但假如我们想要指定占空比的话,我们可以使用 -waveform 来进行
create_clock -period 10 -waveform { 2.5 7.5 } [get_ports clk_sys]
创建一个10 ns时钟,占空比为50%,相移90度,适用于端口clk_sys
当我们设计一个模块的时候,很多时候它的工作频率并不固定,比如一个UART模块,我们可能会将它用在200MHz的APB总线上,也可能会将它用在400M/1GHz的APB总线上,假如这个设计需要在时钟源指定多个时钟,从而满足多IO速度协议的需求,我们可能就需要在SDC中,对于进行约束,我们可以以“-add”的形式增加尾缀,使STA的过程中可以考虑到所有的时钟。假如我们不增加"-add"的话,后一个时钟信号可能就会覆盖掉前一个时钟信号
#同时对CLK端口做100MHz和50MHz的时钟约束
create_clock -name C1 -period 10 [get_ports CLK]
create_clock -name C2 -period 20 [get_ports CLK] -add
除了使用tcl语言的注释外,SDC也给工程师们提供了注释的选项,使用 -comment的尾缀,我们可以将时钟信号的文档信息,以备注的形式加以添加,比如:
#设定一个时钟信号,周期为10ns,信号名称为PCLK,映射到clk端口,备注为“Clock for UART input”
create_clock -period 10 -name PCLK [get_ports clk] -comment "Clock for UART input"
最终的一个概念是虚拟时钟,顾名思义,虚拟时钟没有办法映射到真实的端口网络或引脚,但是他们的出现可以帮助设计者使用更为灵活的时钟特性(比如时钟偏移等)去进行检查,命令如下:
#建立一个周期为10ns,名称为vclk,不映射到具体端口的时钟(虚拟时钟)
create_clock -period 10 -name vclk
在常规的时钟约束以外,另一个我们经常讨论的问题,则是时钟的分频和倍频问题,即“生成时钟”问题,它的BNF(巴斯科范式)如下,而生成时钟的母命令为“create_generated_clock”
create_generated_clock [source_objects]
-source clock_source_pin
[-master_clock master_clock_name]
[-edges edge_list]
[-divide_by factor]
[-multiple_by factor]
[-invert]
[-edge_shift shift_list]
[duty_cycle percent]
[-combinational]
[-add]
[-comment comment_string]