lwj930609的个人空间 https://blog.eetop.cn/1372046 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

Synthesis学习笔记

热度 4已有 9878 次阅读| 2017-2-25 05:14 |系统分类:硬件设计

Synthesis学习笔记
§1. 综合综述
1.1什么是综合?
- 综合是使用软件的方法来设计硬件,然后将门级电路实现与优化的工作留给综合工具的一种设计方法。它是根据一个系统逻辑功能与性能的要求,在一个包含众多结构、功能、性能均已知的逻辑元件的单元库的支持下,寻找出一个逻辑网络结构的最佳实现方案。即实现在满足设计电路的功能、速度及面积等限制条件下,将行为级描述转化为指定的技术库中单元电路的连接。
1.2 综合的不同层次
随着抽象层次的升高,设计者对于最终硬件(门和触发器)的控制能力越来越小。设计者可以在上述的三个层次用HDL语言描述他的设计,根据HDL语言描述的层次的高低,综合也相应的可以分为逻辑级综合,RTL级综合以及行为级综合。
1.2.1 逻辑级综合
- 在逻辑级综合中,设计被描述成布尔等式的形式,触发器、锁存器这样的基本单元采用元件例化(instantiate)的方式表达出来。
1.2.2 RTL级综合
- 与逻辑级综合不同,在RTL级综合中,电路的数学运算和行为功能分别通过HDL语言特定的运算符和行为结构描述出来。对于时序电路,我们可以明确的描述它在每个时钟边沿的行为。
1.2.3 行为级综合
行为级综合比RTL级综合层次更高,同时它描述电路也越抽象,在RTL级中,电路在每个时钟边沿的行为必须确切的描述出来,而行为级描述却不是这样,这里没有明确规定电路的时钟周期,推断法则也不是用来推断寄存器。电路的行为可以描述成一个时序程序(sequential program),综合工具的任务就是根据指定的设计约束,找出哪些运算可以在哪个时钟周期内完成,需要在多个周期内用到的变量值需要通过寄存器寄存起来。
- RTL级就是指将硬件描述语言抽象为一级级的register,而behavior则只需要描述需要进行的操作,由综合工具根据每一级所需要的延时,自行决定register的多少。
1.2.4 Design Compiler所处的位置
- Design Compiler就是将RTL级描述语言转换为门级电路的过程。比RTL更高的行为级的综合,将由Synopsys的另外一个工具——Behavior. Compiler来完成。
1.3 使用Design Compiler做综合的流程示意图
- 与一般的综合过程相同,使用DC做综合也包含转换、优化和映射三个阶段。转换阶段综合工具将HDL语言描述的电路或未映射的电路用工艺独立的RTL级的逻辑来实现,对于Synopsys的综合工具DC来说,就是使用gtech.db
库中的RTL级单元来组成一个中间的网表。优化与映射是综合工具对已有的中间网表进行分析,去掉其中的冗余单元,并对不满足限制条件(如constraints.tcl)的路径进行优化,然后将优化之后的电路映射到由制造商提供的工艺库上(如core_slow.db)。
1.4 超深亚微米给综合工具带来的挑战
- 当进入超深亚微米设计后,原有的综合工具受到了很大的挑战,其中一个主要表现是:连线的延时迅速上升。通常在0.35um设计时,连线延时已经达到了总延时的50%以上,于是版图发标的延时与综合出来得到延时相差会比较大,单靠一次综合已经不能准确估计电路的延时情况,此时需要经过前端后端工具不断叠代来达到比较真实的结果(见图11)。在0.18um的时候,连线延时已经达到了70%,这时就算增加叠代的次数也不一定能得到满意的结果,因而必须引入新的综合手段,保证优化叠代过程的收敛,这就是物理综合方法(Physical Synthesis Flow)。
2 使用Design Compiler进行综合
- 预综合过程是指在综合过程之前的一些为综合作准备的步骤,包括Design Compiler的启动、设置各种库文件、创建启动脚本文件、读入设计文件、DC中的设计对象、各种模块的划分以及Verilog的编码等等。
2.1 预综合过程
- 综合的过程分为以下4步,预综合过程(Pre-synthesis Processes) ,施加设计约束(Constrainting the Design),设计综合(Synthesizing the Design) ,后综合过程(Post-synthesis Process) 
2.1.1 Design Compiler的启动 
- Design Analyzer在启动时自动在启动目录下面创建两个日志文件:command.log和view_command.log,用于记录用户在使用Design Compiler时所执行的命令以及设置的参数,在运行过程中同时还产生filenames.log的文件,用于记录design compiler访问过的目录,包括库、源文件等,filenames.log文件在退出design compiler时会被自动删除。启动dc_shell时则只产生command.log的日志文件
2.1.2 库文件的设置
- 在Design Compiler的运行过程中需要用到几种库文件,他们是工艺库链接库符号库以及综合库
- 在tcl模式下,我们可以根据下面的命令指定工艺库
  set target_library "xxx.db"
- link_library设置模块或者单元电路的引用"链接库",对于所有DC可能用到的库,我们都需要在link_library中指定,其中也包括要用到的IP。
- 在link_library的设置中必须包含’*’, 表示DC在引用实例化模块或者单元电路时首先搜索已经调进DC memory的模块和单元电路,如果在link library中不包含’*’,DC就不会使用DC memory中已有的模块,因此,会出现无法匹配的模块或单元电路的警告信息(unresolved design reference)。
- 符号库symbol_library是定义了单元电路显示的Schematic的库。用户如果想启动design_analyzer或design_vision来查看、分析电路时需要设置symbol_library。符号库的后缀是.sdb,加入没有设置,DC会用默认的符号库取代。设置符号库的命令是:set symbol_library
- 综合库,在初始化DC的时候,不需要设置标准的DesignWare库standard.sldb用于实现Verilog描述的运算符,对于扩展的DesignWare,需要在synthetic_library中设置,同时需要在link_library中设置相应的库以使得在链接的时候DC可以搜索到相应运算符的实现。综合库中包含提供的算术运算等单元,恰当的使用可以大大降低综合的时间
2.1.3 设置启动文件
 
2.1.4 读入设计文件
- 设置好以上的库文件,下一步就是读入Verilog所写的设计文件。在tcl模式下,有以下命令:
   read_db file.db                 //TCL工作模式读取DB格式
   read_verilog file.v            //TCL工作模式读取verilog格式
   read_vhdl file.vhd            //TCL工作模式读取VHDL格式
- Design Compiler可以读取设计流程中任何一种数据格式,如行为级的描述、RTL级的描述、门级网表等等,不过由于不同的数据格式使得Design Compiler综合的起点不同,即使实现相同的功能,也可能会产生不同的结果。
- 当读取完所要综合的模块之后,需要使用link命令将读到Design Compiler存储区中的模块或实体连接起来,如果在使用link命令之后,出现unresolved design reference的警告信息,需要重新读取该模块,或者在.synopsys_dc.setup文件中添加link_library,告诉DC到库中去找这些模块,同时还要注意search_path中的路径是否指向该模块或单元电路所在的目录。
2.1.5 设计对象
- 下图是一个Verilog描述的设计实例,里面包含了我们所要讨论的几种设计对象。这些对象也是今后DC命令的操作对象。Verilog描述的各个模块可以称之为设计(Design),里面包含时钟(Clock),他的输入输出称为端口(Port),模块中的互连线是线网(Net),内部引用的元件称为引用(Reference),引用的实例称为单元(Cell),引用单元的内部端口是管脚(Pin)。

- 假如要对名叫”CLK”的线网设置一个为5的负载,那应该怎样表示呢?这里,我们需要借助DCTCL的一个特殊的数据类型集合(collection),表示如下:
   set_load 5 [get_nets CLK] 
或者,如果想设置全部的fanout为5,可以将[]的内容改为[all_outputs]
可以在dc_shell-t环境下输入”help get*”列出所有以get打头的DC命令
2.1.6 设计划分
把一个复杂的设计分割成几个相对简单的部分,称为设计划分(Design Partition)。模块(module)就是一个划分的单位。在运用DC作综合的过程中,默认的情况下各个模块的层次关系是保留着的,保留着的层次关系会对DC综合造成一定的影响,比如在优化的过程中,各个子模块的管脚必须保留,这势必影响到子模块边界的优化效果。设计划分应遵守以下几个原则:原则1,不要让一个组合电路穿越过多的模块;原则2,将模块的输出寄存;原则3,根据综合时间长短控制模块大小;原则4,将同步逻辑部分与其他部分分离。

- 上图是一个芯片的顶层设计,可以看到它被分层了三个层次——最外边是芯片的Pad,Pad是综合工具中没有的,也不是工具能生成的,它由Foundry提供,并由设计者根据芯片外围的环境手工选择;中间一层被分成四个部分,其中最里面那个称为Core,也就是DC可以综合的全同步逻辑电路,另外的三个部分DC不能综合,需要其他的办法来解决:ASYNCH是异步时序部分,不属于DC的范畴;CLOCK GEN是时钟产生模块(可能用到PLL),尽管有一部分同步电路,但也不符合综合的条件;JTAG是边界扫描的产生电路,这一部分可以由Synopsys的另外一个工具BSD Compiler自动生成。
2.2 施加设计约束
- Design Compiler是一个约束驱动(constrain-driven)的综合工具,这些约束主要包括——时序和面积约束电路的环境属性时序负载在不同模块之间的分配以及时序分析
2.2.1 时序和面积
- 下图是RTL模块的综合示意图,可以看出在RTL代码仿真通过以后,就开始将它进行综合,综合时需要对他加入约束和设计属性的信息,DC根据这些约束将RTL模块综合成门级网表,然后分析综合出的网表是否满足约束条件,如果不满足就要修改约束条件,甚至重写RTL代码。值得注意的是,上面提到的仅仅是RTL模块的综合过程,而不是整个芯片的综合,整个芯片是由很多这样的模块组成的,它的综合过程与上图描述的过程有一定的区别。

2.2.1.1 定义面积约束
- 因为芯片面积直接关系到芯片的成本,面积越大,成本越高,因此,集成电路的设计总是希望面积尽量小,以减小芯片成本。定义面积约束是通过set_max_area命令来完成的,表达式如下:
   current design XXX
   set_max_area 100
 上面的例子给设计施加了一个最大面积100单位的约束。100的具体单位是由Foundry规定的,定义这个单位有三种可能的标准:一种是将一个二输入与非门的大小作为单位1;第二种是以晶体管的数目规定单位;第三种则是根据实际的面积(平方微米等等)。至于设计者具体用的是哪种单位,可以通过下面的一个小技巧得到——即先综合一个二输入与非门,用report_area看他的面积是多少,如果是1,则是按照第一种标准定义的;如果是4,则是第二种标准;如果是其他的值,则为第三种标准。
2.2.1.2 同步设计的时序特点和目标
- 同步时序电路是DC综合的前提。
- 这里所讨论的同步时序电路的特点是——电路中的信号从一个受时钟控制的寄存器触发,到达另一个受时钟控制的寄存器。而我们要达到的目标是——约束电路中所有的时序路径,这些时序路径可以分为三类:输入到寄存器的路径 寄存器到寄存器之间的路径以及寄存器到输出的路径。他们分别对应与下图所示的标号为N、X和S的电路。

- 在电路综合的过程中,所有时序电路以及组合电路的优化都是以时钟为基准来计算路径延迟的,因此,一般都要在综合的时候指定时钟,作为估计路径延迟的基准。
2.2.1.3 定义时钟
- 定义时钟的时候我们必须定义它的时钟源(Clock source),时钟源可以是端口也可以是管脚;另外还必须定义时钟的周期。另外有一些可选项,比如占空比(Duty Cycle)、时钟偏差(Clock Skew)和时钟名字(Clock Name)。定义时钟采用一个语句create_clock完成:
  set clk_period 0.9
  set clk_name "clk"
  set clk_port "clk"
  create_clock -name $clk_name -period $clk_period [ get_ports $clk_port ]
  set_dont_touch_network $clk_port
  这里先定义了一个周期为0.9的clk信号,其时钟源为一个称为clk的端口。第二句对所有定义的时钟网络设置为don’t_touch,即综合的时候不对clk信号优化。如果不加这句,DC会根据clk的负载自动对他产生Buffer,而在实际的电路设计中,时钟树(Clock Tree)的综合有自己特别的方法,它需要考虑到实际布线后的物理信息,所以DC不需要在这里对它进行处理,就算处理了也不会符合要求。

可以看到,定义了系统时钟后,X电路已经被约束起来了,但是电路的输入输出两块还没有施加约束,这可以通过DC的另外两个命令来完成。
2.2.1.4 约束输入路径
- 从上图可以看出,我们所要定义的输入延时是指被综合模块外的寄存器触发的信号在到达被综合模块之前经过的延时,在上图中就是外围触发器的clk-q的延时加上M电路的延时。当确定这段延时之后,被综合模块内部的电路延时的范围也可以确定下来了。假如时钟周期是20ns,输入延时是4ns,内部触发器的建立时间为1ns,那么就可以推断出要使电路正常工作,N电路的延时最大不能超过20-4-1=15ns。设置输入延时是通过DC的set_input_delay命令完成的 :
  set typical_input_delay 0.100
  set typical_output_delay 0.100
  set typical_wire_load 0.010
  set_input_delay $typical_output_delay [all_outputs] -clock $clk_name
- 或者,原tutorial中写作:
  set_input_delay -max 4 -clock clk [get_ports A]
- 如上面的语句指出了被综合模块的端口A的最大输入延时为4ns。-max选项是指明目前设置的是输入的最大延迟,为了满足时序单元建立时间(setup time)的要求。另外还有一个选项是-min,它是针对hold time的约束使用的,-clk是指出这个端口受哪个时钟周期的约束。 
2.2.1.5 约束输出路径
- 定义了输入延时之后,相对应的还要设置电路的输出延时。
- 上图中,信号在被综合模块的触发器U3里触发,被外围的一个触发器接收。对外围电路而言,它有一个T电路延时和外围触发器的建立时间。当确定了他们的延时之后,被综合模块内部的输出路径延时范围也就确定下来了。假如,时钟周期20ns,输入延时5.4ns,U3触发器的clk-q延时为1.0ns,那么输出路径S的最大延时就是20-5.4-1.0=13.6ns。设置输入延时是通过DC的set_output_delay命令完成的:
  set_ouput_delay -max 5.4 -clock clk [get_ports B]
上面的语句指出了被综合模块的输出端口B的最大输出延时为5.4ns。-max选项是指明目前设置的是输入的最大延迟;-clk是指出这个端口受哪个时钟周期的约束。
- 至此,模块的面积时钟输入输出延时都施加了相应的约束。在施加了这些约束之后,可以使用下面的几个命令检查约束是否施加成功
- report_port –verbose
 报告在当前设计中所有的输入输出端口属性和施加的约束值
- report_clock
 报告当前设计中定义的时钟及其属性情况
- reset_design
 删除当前设计中所有的属性值和约束(通常用在约束脚本的第一句) 
- list_libs
 列出内存中所有可用的库
2.2.2 环境属性
- 在2.2.1节中,我们主要讨论了怎样电路中加入时序约束,如设置clock周期、设置输入输出延时等,但是仅仅靠这些约束还是不够的。因为还要考虑到被综合模块周围环境的变化,举个例子说,如果当外界的温度变化,或者电路的供电电压发生变化时,延时会相应的改变,所以这些方面也是必须考虑到的。类似的上一节仅仅约束了输入输出的延时,而没有考虑到他们的电平转化时间(transition time),这些是有输入输出的外围电路的驱动能力和负载大小决定的。另外,电路内部的互连线的延时也没有估计在内。这一节我们主要讨论怎样给电路施加这些环境属性。

- 设置环境属性的命令如上图所示
2.2.2.1 设置输出负载
- 为了更加准确的估计模块输出的时序,除了知道它的输出延时之外还要知道输出所接电路的负载情况,如果输出负载过大会加大电路的transition time,影响时序特性。另外,由于DC默认输出负载为0,即相当于不接负载的情况,这样综合出来的电路时序显然过于乐观,不能反映实际工作情况。
- 设置输出负载是通过DC的set_load命令完成的
  set_load $typical_wire_load [all outputs]
- 该命令有两种用法,一种是直接给端口赋一个具体的值,另外则结合另一个命令load_of指出它的负载相当于工艺库中的哪个单元的负载值。上面既是给出了第一种设置的例子
  set_load [load_of my_lib/and2a0/A] [get_ports OUT1] 
  set_load [expr [load_of my_lib/inv1a0/A] * 3] OUT1
  第一条语句说明OUT1端口接的负载值是my_lib中and2a0单元的A管脚的负载值。第二条语句则多用了TCL语言的表达式的语法,它说的是,OUT1相当于接了三个inv1a0单元的A管脚的负载值。一般后面的这种方法用的多些。
2.2.2.2 设置输入驱动
- 与设置输出负载类似,为了更加准确的估计模块输入的时序,我们同样需要知道输入端口所接单元的驱动能力。在默认的情况下,DC认为驱动输入的单元的驱动能力为无穷大,也就是说,transition time为0
- 设置输入驱动是通过DC的set_driving_cell命令完成的。set_driving_cell是指定使用库中的某一个单元来驱动输入端口。该命令是在输入端口之前假想一个驱动单元,然后按照该单元的输出电阻来计算transition time,从而计算输入端口到门单元电路的延迟:
 set_driving_cell -lib_cell INVX2TR [all_inputs]
 如上这句话就设置了所有的输入端都假设被INVX2TR这个inverter驱动。
2.2.2.3 设置工作条件

- 工作条件包括三方面的内容——温度、电压以及工艺。在Foundry提供的工艺库里,它的各个单元的延时是在一个“标准”(nominal)条件下得到的,比如说温度25.0度、工艺参数1.0和工作电压1.8V。

- 这些工作条件的变化,Foundry在建库的时候已经考虑到了,因此它在工艺库中提供了几种工作条件的模型(operating condition model)以供设计者选择。这些工作条件一般分为三种:最好情况(best case)、典型情况(typical case)以及最差情况(worst case)。

- 我们为了以后能使电路正常的工作在上面的三种情况下,在综合的时候就必需要将他们考虑进来。一般综合只要考虑到最差和最好两种情况,最差情况用于作基于建立时间(setup time)的时序分析,最好情况用于作基于保持时间(hold time)的时序分析。

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

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

set_operating_conditions –max “slow_125_1.62”

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

set_min_library core_slow.db \

-min_version core_fast.db

set_operating_conditions -max slow_125_1.62 \

                      -min fast_0_1.98

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

2.2.2.4 设置连线负载模型

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

- 这个例子可以通过命令report_lib得到,它是ssc_core_slow这个工作条件下的一个名为

160KGATES的负载模型。

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

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

set current_design mult_block

set_wire_load_model –name “ibm13_wl10” –library “typical”

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

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

- 连线负载模式一共有3种,围绕(enclosed)、顶层(top)以及分段(segmented)。如上图所示,一根连线连接了B2和B2两个模块,这两个模块都位于TOP下的SUB这个子模块中,围绕模式是指连接B1和B2的连线的负载模型用围绕它们的模块的负载模型代替,即用SUB的负载模型;顶层模式是指用顶层模块的负载模型代替;分段模式顾名思义,分别根据穿过的三段的模型相加得到。如果要设置成围绕模式,可以使用如下命令:

set_wire_load_mode “segmented”

- 在定义完环境属性之后,我们可以使用下面的几个命令检查约束是否施加成功

- check_timing 

检查设计是否有路径没有加入约束 

check_design 

检查设计中是否有悬空管脚或者输出短接的情况 

write_script 

将施加的约束和属性写出到一个文件中,可以检查这个文件看看是否正确

2.2.3 时序和负载预算

- 前面的两节里我们讨论了怎样给一个被综合的电路模块施加时序约束以及设置环境属性,大家学习完之后可能有这样一个疑问:模块的输入输出延时、负载和驱动单元的具体的值是怎样确定下来的呢?这一节里,我们就着重来探讨这个问题,也就是说怎样在综合模块之前先给它的时序和负载作一个预算,一般而言,这个工作是由项目的体系设计者(Achitecture Designer)完成,当他先确定好各个模块外围的时序和负载预算之后,再由具体的模块设计者(Module Designer)完成模块的综合。

2.2.3.1 时序预算

- 先看时序预算,假设电路中有三个模块X_BLOCK、MY_BLOCK和Y_BLOCK,时钟周期是10ns。如果要先综合MY_BLOCK模块,我们可以看到它的输入部分的N电路必须和X_BLOCK中的S电路共享一个周期的延时,同样输出部分的S电路也必须和Y_BLOCK的N电路共享一个周期的延时。我们可以作这样一个估计,认为处于两个模块交界部分的S和N电路只能分别占用40%的周期延时,也就是说限定所有的S和N电路的延时为最大为4ns,这样可以看出S+N的延时总共只有8ns,小于10ns,因此这是一种保守的预算方法,预留的2ns的延时可以在电路不满足时序的时候再加上。经过预算之后的MY_BLOCK模块的约束如下:

create_clock –period 10 [get_ports clk]

set_dont_touch_network [get_clocks clk]


set_input_delay –max 6 –clock clk [all_inputs]

remove_input_delay [get_ports clk]

set_output_delay –max 6 –clock clk [all_outputs]

2.2.3.2 负载预算

- 负载预算也是在实际综合编译之前体系设计者根据模块将来可能的工作情况估计出来的,一般它的估计有几个原则: 1. 保守起见,假设驱动模块的单元的驱动能力较弱;2. 限制每一个输入端内部的负载电容;3.估计每一个输出端口最多可以驱动几个相同的模块。

- 如下是一个保守的负载预算实例

current_design mult_block

link

source timing_budget.tcl


#assume a weak driving buffer on the inputs

set_driving_cell -lib_cell inv1a0 [all_inputs]

remove_driving_cell [get_ports clk]


#limit the input load

set MAX_INPUT_LOAD [expr [load_of tech_lib/and2a0/A] * 10]

set_max_capacitance $MAX_INPUT LOAD [all_inputs]

remove_attribute [get_ports clk] max_capacitance


#model the max possible load on the outputs, assuming

#outputs will only be tied to 3 subsequent blocks

set_load [expr $MAX_INPUT_LOAD *3] [all_outpus]


- 在这个例子中,我们假设输入的驱动单元是一个inv1a0的反相器,然后限制了最大的输入负载,即每个输入端口的负载最大不得超过10个二输入与非门的负载大小,同时也规定了一个模块最多能同时驱动三个同样大小的其他模块。

2.2.4 时序分析

- Design Compiler是一个约束驱动(Constraint-driven)的综合工具,约束中最重要的就是时序约束,前面我们已经讨论了怎样在设计中施加时序约束,但是综合出来的电路能否满足这些约束条件却是另一个重要的问题。Design Compiler内嵌的一个时序分析引擎Design Time,它是根据工艺库中的单元延时信息和连线负载模型分析电路的静态时序的。

- Design Time是DC的一个内嵌的静态时序分析引擎,DC就是依靠它来计算电路的延时情况。DesignTime和PrimeTime都是静态时序分析的工具,但是两者并不完全相同,PrimeTime是在DesignTime的基础上发展起来的独立的专业的时序工具,而且效率和应用范围更高。

- 静态时序分析(STA)是进行电路时序分析的一种方法,它的主要特点是分析不需要通过动态仿真,并且对电路的覆盖率更高。动态仿真(比如VCS)需要给电路施加一个激励,并检查输出信号,与理想信号比较,这种办法速度较慢,而且不一定能覆盖到所有的逻辑。

- 静态时序分析的分为三个步骤:1. 将电路分解成不同的时序路径(timing paths);2. 计算每段路径的延时;3. 检查所有路径的延时,看是否能满足时序要求

2.2.4.1 分解时序路径

- DesignTime对时序路径的分解是根据时序路径的起点和终点的位置来决定的。每一条时序路径都有一条起点和终点,起点是输入端口或者触发器的时钟输入端;终点是输出端口或者触发器的数据输入端,如图下图就有三条时序路径。

- 另外根据终点所在的触发器的时钟不同还可以对这些时序路径进行分组(Path Group),如下图电路中存在4条时序路径,3个路径组,CLK1和CLK2组分别表示他们的终点是受CLK1和CLK2控制的,DEFAULT组则说明他们的终点不受任何一个时钟控制。

- 再例如下面的一个电路,一共有12条时序路径和3条路径组。

2.2.4.2 计算单个路径延时

- 时序路径的延时包含单元延时和连线延时,为了便于观察,我们将上图的时序路径进一步划分,得到如下图所示

- 可以看出,每条时序路径被分割成了一段段的时序弧(timing arc),每条时序弧代表

的不是一个单元延时就是一段连线的延时。下一步的工作就是计算出它们的值。

单元延时的计算

- 单元延时的计算是根据单元延时模型进行的,这里介绍两种单元延时模型,线性延时模型(Linear Delay Model)和非线性延时模型(Nonlinear Delay Model),他们的计算方法如下图所示


- 线性模型由三部分组成:Dsploe表示单元输入信号的延时、Dintrinsic表示单元的固有延

时、Rcell(Ccell,Cpin)表示输出的管脚电容和连线电容对单元的附加延时。

- 非线性模型是DC计算单元延时的主要模型。它分为两部分:单元的输入延时(transition time)和输出负载的函数。与线性模型不同的是,它是通过查找表的方式得到的,例如下面的这个例子,对于一个单元来说,它有两张查找表,一张用于计算单元延时,另一张用于计算输出延时,并作为下一级单元的输入。在这个例子中,通过查表可以得到,单元延时为6ps,输出的transition time为25个单位,这个单位又作为下一级的输入。

连线延时计算及其拓扑

- 在设置环境属性这一节中我们讲到了连线负载模型,通过连线负载模型我们可以得到一条连线上的电阻和电容的值,但是仅仅有RC值并不能得到连线的延时,还需要知道这些RC的分布,RC分布有三种情况:

1. best_case_tree是一种理想情况,它假设连线的电阻为零,平常很少使用;

2. balanced_tree认为连线的RC均匀的分布在各条负载支路上;

3. worst_case_tree假设RC值全部集中在负载共有的连线上,因此它的延时是最大的

- 连线的不同拓扑结构是通过工作条件的不同体现出来的,工作条件不但影响连线的延时,还通过温度、电压和工艺的变化影响单元延时的计算。

2.2.4.3 计算整条路径的延时

- DesignTime计算完所有的路径延时之后的下一步工作就是根据这些延时,找出电路中延时最大或者最小的路径来。对于设计者而言,他们或许不关心每个单元的延时而更加关注到底电路是不是满足了设定的时序约束的要求。例如下图,有两个触发器FF1和FF2,它们之间是一个很多单元组成的组合逻辑云,当作建立时间检查的时候,设计者就需要知道这个逻辑云的最大延时是否满足建立时间,即最大延时加上FF2的建立时间是否小于一个周期的时钟周期。


- 那么怎样计算整条路径的最大延时呢?是不是把这条路径上的所有单元和连线的最大延时简单相加得到的呢?答案是否定的,因为这里涉及到一个时钟边沿敏感性(Edge Sensitivity)的问题。

- 如上图,一条路径上有两个不同的反相器,他们的固有上升时间和下降时间都不同,要计算他们的最大最小延时,需要弄清楚他们的工作过程——当第一个反相器的输入在时钟上升沿时,它的延时是1.2,同时第二个反相器处于时钟的下降沿,延时为0.3;反之,当第一个反相器输入为时钟下降沿时,它们的延时分别为0.5和1.5。因此,最大路径延时不是简单的1.2+1.5,而是分别检查0.5+1.5,在输入为时钟下降沿得到。实际上,DesignTime在计算每条路径的时候,都会考虑边沿敏感性,即分别根据上升下降沿计算两次。

2.2.4.4 用report_timing检查时序

- 上面讲的是DesignTime作静态时序分析的基本原理和步骤,这节介绍介入DesignTime的命令:report_timing

- report_timing命令的具体参数如下图,默认的时候report_timing报告每一条路径组中的最长路径。



- 报告一共分为4个部分,第一部分显示了路径的基本信息。工作状态是slow_125_1.62,工艺库名称为ssc_core_slow,连线负载模式是enclosed。接下来指出这条最长路径的起点是data1(输入端口),终点是u4(上升沿触发的触发器),属于clk路径组,做的检查是建立时间检查(max)。这一部分的最后还报告了电路的连线负载模型。

3

点赞

刚表态过的朋友 (3 人)

发表评论 评论 (2 个评论)

回复 北夏辰 2017-7-10 18:18
:loveliness:
回复 AlexLee1993 2022-3-13 11:42
thanks for your summary

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 4

    粉丝
  • 0

    好友
  • 3

    获赞
  • 2

    评论
  • 314

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-26 02:49 , Processed in 0.034561 second(s), 15 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部