Design Compiler指南——施加设计约束

        Design Compiler是一个约束驱动(constrain-driven)的综合工具,它的结果是与设计者施加的约束条件密切相关的。在本文里,我们主要讨论怎样给电路施加约束条件,这些约束主要包括——时序和面积约束、电路的环境属性、时序和负载在不同模块之间的分配以及时序分析。

一、时序和面积

        上图是RTL模块的综合示意图,可以看出在RTL代码仿真通过以后,就开始将它进行综合,综合时需要对他加入约束和设计属性的信息,DC根据这些约束将RTL模块综合成门级网表,然后分析综合出的网表是否满足约束条件,如果不满足就要修改约束条件,甚至重写RTL代码。值得注意的是,上面提到的仅仅是RTL模块的综合过程,而不是整个芯片的综合,整个芯片是由很多这样的模块组成的,它的综合过程与上图描述的过程有一定的区别,具体我们将在后面进行讨论。 

1、定义面积约束

        因为芯片面积直接关系到芯片的成本,面积越大,成本越高,因此,集成电路的设计总是希望面积尽量小,以减小芯片成本。定义面积约束是通过set_max_area命令来完成的,比如:

dc_shell > current_design PRGRM_CNT_TOP

dc_shell > set_max_area 100

        上面的例子给PRGRM_CNT_TOP的设计施加了一个最大面积100单位的约束。100的具体单位是由Foundry规定的,定义这个单位有三种可能的标准:

  1. 一种是将一个二输入与非门的大小作为单位1;
  2. 第二种是以晶体管的数目规定单位;
  3. 第三种则是根据实际的面积(平方微米等等)。

        至于设计者具体用的是哪种单位,可以通过下面的一个小技巧得到——即先综合一个二输入与非门,用report_area看他的面积是多少,如果是1,则是按照第一种标准定义的;如果是4,则是第二种标准;如果是其他的值,则为第三种标准。

2、同步设计的特点

        同步时序电路是DC综合的前提,因此这里有必要先讨论一下同步时序电路的特点及目标。这里所讨论的同步时序电路的特点是——电路中的信号从一个受时钟控制的寄存器触发,到达另一个受时钟控制的寄存器。而我们要达到的目标是——约束电路中所有的时序路径,这些时序路径可以分为三类:输入到寄存器的路径 、寄存器到寄存器之间的路径以及寄存器到输出的路径。他们分别对应与下图所示的标号为N、X和S的电路。

        假设在上面的电路中,我们要控制触发器FF2到FF3之间的时序,即X电路的延时,那要通过什么方式让DC知道呢?显然一个直观的办法就是定义系统的时钟Clk,如果我们定义好了Clk的周期,那么DC会自动的尽量保证从FF2触发的信号能在一个周期内到达FF3寄存器。假如周期是10ns,FF3触发器的建立时间(setup time)是1ns,那么留给X电路的延时最大只能有10-1=9ns。

3、定义时钟

        在电路综合的过程中,所有时序电路以及组合电路的优化都是以时钟为基准来计算路径延迟的,因此,一般都要在综合的时候指定时钟,作为估计路径延迟的基准。定义时钟的时候我们必须定义它的时钟源(Clock source),时钟源可以是端口也可以是管脚;另外还必须定义时钟的周期。另外有一些可选项,比如占空比(Duty Cycle)、时钟偏差(Clock Skew)和时钟名字(Clock Name)。定义时钟采用一个语句create_clock完成——

dc_shell > create_clock -period 10 [get_ports  Clk]

dc_shell > set_dont_touch_network  [get_ports  Clk]

        第一句定义了一个周期为10ns的时钟①,它的时钟源是一个称为Clk的端口。

        第二句对所有定义的时钟网络设置为don’t_touch,即综合的时候不对Clk信号优化。如果不加这句,DC会根据Clk的负载自动对他产生Buffer,而在实际的电路设计中,时钟树(Clock Tree)的综合有自己特别的方法,它需要考虑到实际布线后的物理信息,所以DC不需要在这里对它进行处理,就算处理了也不会符合要求。

4、约束输入路径

        

        从上图可以看出,我们所要定义的输入延时是指被综合模块外的寄存器触发的信号在到达被综合模块之前经过的延时,在上图中就是外围触发器的clk-q的延时加上M电路的延时。当确定这段延时之后,被综合模块内部的电路延时的范围也可以确定下来了。加入时钟周期是20ns,输入延时是4ns,内部触发器的建立时间为1.0ns,那么就可以推断出要使电路正常工作,N电路的延时最大不能超过20-4-1.0=15.0ns。

        设置输入延时是通过DC的set_input_delay命令完成的—— 

dc_shell > set_input_delay -max 4 -clock Clk  [get_ports A]

        如上面的语句指出了被综合模块的端口A的最大输入延时为4ns。-max选项是指明目前设置的是输入的最大延迟,为了满足时序单元建立时间(setup time)的要求。另外还有一个选项是-min,它是针对保持时间的约束使用的。-clk是指出这个端口受哪个时钟周期的约束。

5、约束输出路径

        上图中,信号在被综合模块的触发器U3里触发,被外围的一个触发器接收。对外围电路而言,它有一个T电路延时和外围触发器的建立时间。当确定了他们的延时之后,被综合模块内部的输出路径延时范围也就确定下来了。假如,时钟周期20ns,输出延时5.4ns,U3触发器的clk-q延时为1.0ns,那么输入路径S的最大延时就是20-5.4-1.0=13.6ns。

        设置输入延时是通过DC的set_output_delay命令完成的——

 dc_shell > set_output_delay -max 5.4 -clock Clk  [get_ports B]

        上面的语句指出了被综合模块的输出端口B的最大输出延时为5.4ns。-max选项是指明目前设置的是输入的最大延迟;-clk是指出这个端口受哪个时钟周期的约束。

        至此,模块的面积、时钟、输入输出延时都施加了相应的约束。在施加了这些约束之后,可以使用下面的几个命令检查约束是否施加成功——

  • report_port –verbose 报告在当前设计中所有的输入输出端口属性和施加的约束值
  • report_clock 报告当前设计中定义的时钟及其属性情况
  • reset_design 删除当前设计中所有的属性值和约束(通常用在约束脚本的第一句)
  • list_libs 列出内存中所有可用的库

二、环境属性

        在上一节中,我们主要讨论了怎样电路中加入时序约束,如设置clock周期、设置输入输出延时等,但是仅仅靠这些约束还是不够的。因为还要考虑到被综合模块周围环境的变化,举个例子说,如果当外界的温度变化,或者电路的供电电压发生变化时,延时会相应的改变,所以这些方面也是必须考虑到的。类似的上一节仅仅约束了输入输出的延时,而没有考虑到他们的电平转化时间(transition time),这些是有输入输出的外围电路的驱动能力负载大小决定的。另外,电路内部的互连线的延时也没有估计在内。这一节我们主要讨论怎样给电路施加这些环境属性。

1、设置输出负载

        为了更加准确的估计模块输出的时序,除了知道它的输出延时之外还要知道输出所接电路的负载情况,如果输出负载过大会加大电路的transition time,影响时序特性。另外,由于DC默认输出负载为0,即相当于不接负载的情况,这样综合出来的电路时序显然过于乐观,不能反映实际工作情况。

        设置输出负载是通过DC的set_load命令完成的。该命令有两种用法,一种是直接给端口赋一个具体的值,另外则结合另一个命令load_of指出它的负载相当于工艺库中的哪个单元的负载值。

        例如下图,给OUT1端口设了一个负载为5的值。这里的单位也是由Foundry提供,具体的单位,可以通过report_lib命令查看,一般而言是pf。

        采用第二种方法从下图中可以看出,第一条语句说明OUT1端口接的负载值是my_lib中and2a0单元的A管脚的负载值。第二条语句则多用了TCL语言的表达式的语法,它说的是,OUT1相当于接了三个inv1a0单元的A管脚的负载值。一般后面的这种方法用的多些。

2、设置输入驱动

        与设置输出负载类似,为了更加准确的估计模块输入的时序,我们同样需要知道输入端口所接单元的驱动能力。在默认的情况下,DC认为驱动输入的单元的驱动能力为无穷大,也就是说,transition time为0

        设置输入驱动是通过DC的set_driving_cell命令完成的。set_driving_cell是指定使用库中的某一个单元来驱动输入端口。该命令是在输入端口之前假想一个驱动单元,然后按照该单元的输出电阻来计算transition time,从而计算输入端口到门单元电路的延迟。

 dc_shell > set_driving_cell -lib_cell and2a0 [get_ports IN1]

3、设置工作条件

        工作条件包括三方面的内容——温度、电压以及工艺。在Foundry提供的工艺库里,它的各个单元的延时是在一个“标准”(nominal)条件下得到的,比如说温度25.0度、工艺参数1.0和工作电压1.8V。一旦工作条件发生了改变,电路的时序特性也必将收到影响,以上三方面的因素对电路时序的影响如下所示:

在较为先进的工艺中,会出现温度翻转效应,即低温反而导致delay更大,所以在使用库的时候,要详细阅读库的说明。

        从图中可以看出,单元的延时会随着温度的上升而增加;随着电压的上升而减小;随着工艺尺寸的增大而增大。以上的这些工作条件的变化,Foundry在建库的时候已经考虑到了,因此它在工艺库中提供了几种工作条件的模型(operating condition model)以供设计者选择。这些工作条件一般分为三种:最好情况(best case)、典型情况(typical case)以及最差情况(worst case)。我们为了以后能使电路正常的工作在上面的三种情况下,在综合的时候就必需要将他们考虑进来。一般综合只要考虑到最差和最好两种情况,最差情况用于作基于建立时间(setup time)的时序分析,最好情况用于作基于保持时间(hold time)的时序分析

        在默认情况下,Design Compiler不会自动指定工作条件,我们可以先通过report_lib命令来列出在当前的工艺库里提供了哪几种工作条件——

        然后指定需要用到的工作条件,在做建立时间分析的时候需要用到最差情况的条件:

 dc_shell > set_operating_conditions -max "slow_125_1.62"

        如果我们既要分析建立时间,又要分析保持时间那么就要同时指定最差和最好情况:

dc_shell > set_min_library core_slow.db -min_version core_fast.db

dc_shell > set_operating_conditions -max "slow_125_1.62" -min "fast_0_1.98"

        其中core_slow.db和core_fast.db分别是最差和最好条件下的工艺库文件,第一句话先用set_min_library设定作保持时间检查的库,第二句话则分别对应了两种时间检查需要用到的工作条件。

4、设置连线负载模型

        在DC综合的过程中,连线延时是通过设置连线负载模型(wire load model)确定的。连线负载模型基于连线的扇出,估计它的电阻电容等寄生参数,它是也是由Foundry提供的。Foundry根据其他用这个工艺流片的芯片的连线延时进行统计,从而得到这个值。

        下面是一个负载模型的例子

         这个例子可以通过命令report_lib得到,它是ssc_core_slow这个工作条件下的一个名为160KGATES的负载模型。其中时间单位为1ns,电容负载单位为1pf,电阻单位为1kΩ。从图中可以看出单位长度的电阻以及电容值,DC在估算连线延时时,会先算出连线的扇出,然后根据扇出查表,得出长度,再在长度的基础上计算出它的电阻和电容的大小。若扇出值超出表中的值(假设为7),那么DC就要根据扇出和长度的斜率(Slop)推算出此时的连线长度来。

        事实上,在每一种工作条件下都会有很多种负载模型,各种负载模型对应不同大小的模块的连线,如上图的模型近似认为是160K门大小的模块适用的。可以认为,模块越小,它的单位长度的电阻及电容值也越小,负载模型对应的参数也越小。

        设置输入驱动是通过DC的set_wire_load_model命令完成的。

dc_shell > current_design addtwo 

dc_shell > set_wire_load_model -name 160KGATES

        如上面的语句,则设置了addtwo这个模块的连线负载模型为160KGATES。

        另外我们也可以让DC自动根据综合出来的模块的大小选择负载模型,这个选项在默认下是打开的。如下图所示,当综合出的电路的面积小于43478.00时,使用5KGATES的模型,属于43478.00和86956.00之间时,使用10KGATES的模型。

        以上讨论的情况是一个模块内部连线的负载模型的估计。如果连线连接的是不同的模块,那么它的负载模型又将怎么估计呢?这就要用到连线负载模式(set_wire_load_mode)这个命令了。

        连线负载模式一共有3种,围绕(enclosed)、顶层(top)以及分段(segmented)。如上图所示,一根连线连接了B2和B2两个模块,这两个模块都位于TOP下的SUB这个子模块中,

  1. 围绕模式是指连接B1和B2的连线的负载模型用围绕它们的模块的负载模型代替,即用SUB的负载模型;
  2. 顶层模式是指用顶层模块的负载模型代替;
  3. 分段模式顾名思义,分别根据穿过的三段的模型相加得到。

        如果要设置成围绕模式,可以使用如下命令 

dc_shell > set_wire_load_mode enclosed

当然,约束中时序约束还有很多需要详细了解,会在其他文中介绍。。。

  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Design Compiler SDC约束是用于设计综合的一种约束语言,它能够定义设计综合过程中的时序和功能要求。SDC意为Synopsys Design Constraints,通过在设计综合之前定义和添加这些约束,可以确保设计的正确性和性能目标的达成。 SDC约束主要包括时钟频率、时序路径、时序推迟、时钟握手协议等方面的约束。时钟频率是指设计中时钟的振荡频率,需要在SDC中进行显式的指定。时序路径是指信号在设计中的传输路径,通过定义这些路径的时序要求,可以确保设计的时序符合预期。时序推迟是指时序与延迟之间的关系,可以通过SDC约束来指定某些路径的最大延迟或最小延迟。时钟握手协议是指时钟和数据之间的逻辑关系,通过SDC约束可以确保正确的时钟握手协议被遵守。 使用SDC约束的过程一般包括以下几个步骤:首先,根据设计的要求和目标,在设计启动之前确定所需的约束类型。然后,通过定义时钟频率及相关约束,确保设计中时钟的正常运行。接着,通过定义时序路径和相关约束,确保信号在设计中的正确传输和时序要求的达成。最后,根据具体设计的需求,定义时序推迟和时钟握手协议的约束,以确保设计在时序和功能上的要求被满足。 总的来说,Design Compiler SDC约束是一种重要的工具和语言,可以帮助设计工程师在设计综合过程中进行时序和功能要求的定义和控制,从而实现设计的正确性和性能目标。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沧海一升

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值