综合各个库,和约束
综合过程包括,
synopsis综合的工具叫dc_shell,直接在linux命令行输入dc_shell就可以运行综合工具了。在综合前要进行一大堆的综合设置,包括库的设定、时序约束、面积约束、RTL读入、网表输出等操作,都是需要在dc_shell这个命令窗口下一个个如如命令来完成。
当然也可以把命令写在一个文件中,通过调用
dc_shell -xg -t -x "set HDL_PATH ../rtl; .." -f ../dc_cmd | tee ../dc.log -x:要执行的命令,这里吧HDL_PATH设置为../rtl -f:设置放置命令的文本文件,即dc_cmd,里边包括了所有综合需要设置的参数 tee:用于输出综合log进入shell后可以通过man xxx来查看命令的含义,比如:man remove_generated_clock
1、库的设定 Library
(1)GTECH Library:
GTECH是synopsys通用工艺库,是Design Compiler(DC)自带的,是独立于厂商工艺。该库中包含的元件仅代表一定的逻辑功能而不带有任何工艺参数,与工艺无关。综合的时首先将HDL代码Translate到GTECH库,然后综合(compile)时再映射(Map)到工艺库。例如,我们在代码中写 “assgin a = b&c”,那么读入 HDL 代码后,DC 将 HDL translate 到 Gtech cell 表现,即使用一个 GTECH 的与门例化。 在综合过程中,DC自动调用 GTECH 库,不需要任何设置。
(2)Designware Library:
DesignWare Library是由Synopsys(或者第三方)提供的一些可重用的电路宏单元。它们可以完成诸如复杂的算术运算(+,-, * , / 等),数值比较(==,>=,<=等),以及 FIFO 、CPU 等功能,DesignWare 库就包含了这些电路模块。例如我们在 HDL 代码中的“A*B”,在 Translate 过程中工具就会调用Designware 来实现。我们也可以在设计中直接例化这些 Designware 中的电路单元。DC 识别的 DesignWare 是 .sldb 格式的 Library。DesignWare 库一般由 Synopsys 或者第三方提供。
(3)Technology Library:
Technoligy Library 是由芯片生产厂家提供的,它包含特定的工艺器件以及一些必须的参数信息,如工作环境、逻辑延时、驱动负载以及线负载模型等。工艺库一般由Vendor 提供。DC 支持的 .db 格式的工艺库
三个库中,GTECH Library不需要设置,DesignWare Library库使用变量synthetic_library设置。Technology Library库使用link_library变量设置。
Compile 的Map 过程,是进行工艺库的映射,调用 target_library 中的 Library Cell 来完成映射,映射后也需要维持网表关系,因此 target_library 中的 Library,一般也要在 link_library 定义。 图形显示需要显示元件的形状,管脚位置等信息,因此需要 symbol_library。 下面再举一个例子,可以更好的理解 link_library 和 target_library。 假设我们有 A library 实现的网表,但是我们想用B library 替换 A library 来实现。那么我们可以将 A library 和 B library 设置到 link_library 中,而 target_library 中只包含 B library。 让 DC 读入 A library 的实现的网表,Compile后,我们就可以得到用 B library 实现同样功能的设计网表。
通常一个设计中可能要调入很多的库,那么在设计库是每一个库都写全路径比较麻烦,因此可以使用“search_path”。当你只指明文件名时,DC 会使用search_path 中定义的路径进行搜索。search_path 可以按照下面的方法定义:
2、HDL设计读入
Library 设置完成后,我们就可以读入我们的设计文件了。常有两种方法读入代码,read_file 和 analyze / elaborate 。读入代码的过程就是将 HDL 文件Translate GTECH Library 的描述。当读入了 HDL 代码,此时得到的设计是一个 Unmapped 的设计。此时的设计组合逻辑使用 GTECH 例化,时序逻辑使用 SEQGEN 表现,而算术运算符则使用 DesignWare 表现。你可以使用report_cell 或者 write 命令察看。
这种方法读入代码分两个部分:
analyze HDL Code file
elaborate Top Module
其中,analyze 命令执行下面的操作:
读入 HDL 代码(verilog 或者 VHDL),并且执行语法检查,Synopsys
Rules 的检查。
转化HDL 代码为中间格式。
而 elaborate 命令执行下面的操作
将设计转化为 GTECH 逻辑描述
允许代码中的参数重定义操作
执行 VHDL architecture 的选择
将HDL 中的算数操作替换为DesignWare 元件
自动执行 Link 操作
命令示意如下:
dc_shell-t> analyze “Demo1.v Demo2.v”
dc_shell-t> elaborate TOP
3、设计环境定义
设置工作条件
工作条件指的是芯片的工作温度(Operating temperature)、工作电压(Supply voltage)和工艺参数(Process)。这三个因素的变化会对芯片的性能造成很大的影响。Design compiler 在进行时序分析时将综合考虑这些因素的最坏和最好情况。 在大多数工艺库中已经预定义了多种情况下的工作条件,在设定工作条件之前应先用 report_lib命令查看工艺库中提供了哪些预定义的工作条件。注意如果库没有在内存中的话要先把库读进来。注意有些库的文件名和库的名字是不一样的。我们可以使用 list_libs 得到调到内存中的所有库文件,以及库的名字。
负载模型
线负载模型用来估算电路中线的长度和扇出数对电阻、电容和面积的影响。它根据连线的扇出数给出连线的等效长度,根据这个长度值又可进一步估算出线的电容和电阻值。线负载模型是由芯片生产厂家根据特定工艺的统计信息建立的,并且在工艺库中给出了定义。在层次化的设计中,Design Compiler 用 top、enclosed 和segmented三种模式来确定子模块的线负载模型,这三种模式示意如下:
4、设计规则约束
设计规则(Design Rule)反映了特定工艺对设计的要求,这些要求是必须满足的。Design Compiler支持如下的 Design Rule约束:
Transition time (最大值和最小值)。
Fanout load (最大值和最小值)。
Capacitance (最大值和最小值)。
Cell degradation。
Connection class。
在一些工艺库中给出了 Design Rule 约束的缺省值,在这种情况下一般不需要再另外定义。如果需要更严格的约束,可以自己手工定义。对于同一个约束的重复定义,Design Compiler 总是取最严格的一个值。在优化的过程中,Design Rule约束相对于其他的约束条件具有更高的优先级,即Design Compiler 总是首先考虑保证满足Design Rule的要求。 在一般的设计中,需要人工调整的 Design Rule约束主要是最大 Transition time(max_transition)和最大 Fanout(max_fanout),其它约束一般采用库中的缺省值就可以了。下面就详细说明一下这两个约束的含义和设定方法,如果想了解其它几个约束可以查阅 Synopsys 的相关资料。
max_transition:
一根连线(net)的Transition time指的是驱动它的pin的逻辑电平跃变所需要的时间。Design Compiler计算Transition time 的方法是用驱动 pin 的驱动强度乘以它驱动的连线上的所有容性负载的总和。用公式表示为: TT = Rdrive ( Cwire + Cpin ) 设定max_transition用命令 set_max_transition,它的语法格式如下:
set_max_transition value { object_list }
max_fanout:
一根 net的扇出负载(Fanout load)指的是它所驱动的所有输入 pin 的fanout load 的总和。注意区分load、fanout load和 fanout number的区别。load指的是 net 上的各种容性负载的总和,单位是电容的单位;fanout load 是一根 net所驱动的所有输入 pin 的 fanout load 的总和,它没有单位,并且一个输入 pin的fanout load值可以不为 1;fanout number 则指的是一根 net所驱动的输入pin的总个数。请看如下例子:
5、时序约束
(1)时钟和时钟网络
当 design compiler 对一个设计进行 timing 约束和分析时,它不能自动产生时钟,必须对设计中的时钟源进行显式的定义。 design compiler中时钟分为两种:真实时钟(real clock)和虚拟时钟(virtual clock)。 真实时钟有时钟源,它可以是理想时钟(ideal clock)和传播时钟(propagated clock)。理想时钟在时钟树上不会引起延时,当定义时钟后,缺省就是理想时钟。而传播时钟和理想时钟不同,若一个寄存器的时钟输入是传播时钟,那么就会计算时钟源到寄存器时钟输入端路径的所有延时,得到时钟的到达时间。使用命令 set_propagated_clock 可以把理想时钟转变为传播时钟(在综合时我们一般不使用传播时钟,后面给出原因)
虚拟时钟(virtual clock)没有时钟源。使用虚拟时钟作参考可以定义input 和output 相对的延时。在某些情况下,例如在定义组合逻辑的时序约束时,使用虚拟时钟特别有用。 时钟树(clock tree),又称时钟网络, 是指位于时钟源和它所有扇出的寄存器时钟输入端之间的组合逻辑。
上图圆圈内为一个简单的时钟网络。
时钟树一般由厂家根据物理布局的情况综合产生,一般不使用 design compiler对时钟树进行综合(CTS)。通常,后端的P&R工程师进行时钟网络综合,并给出一个保证的 clock skew (clock skew指时钟树不同分支之间的最大延时差),以及Clock 的 Insertion Delay(就是指时钟树的延时)。因此,在我们进行逻辑综合时,可以使用 set_clock_uncertainty、和 set_clock_latency 对时钟网络进行模型化。
理想时钟的 Clock skew / Clock insertion Delay的值为 0。
在目前的流程中,通常时钟网络的由后端的P&R完成,我们在综合时只是保证功能的正确。因为在综合时,工具不考虑触发器的摆放位置,而在后端工程师在CTS (Clock tree synthesis),触发器的摆放已经确定。这样根据触发器的具体摆放位置,进行时钟树的生成,可以更好的平衡触发器时钟的 Skew,Insertion Delay 等。下图示意中表现了综合以及CTS。
CTS前后
在综合时,时钟网络是理想的,没有延时(延时为0),没有Skew(Skew 为0),时钟的沿也是理想的(Transition 时钟为 0)。这样和 CTS 后的时序就有了很大的不一致。因此在综合时,我们尽管没有 CTS,但应该把以后这些CTS 的特性表示出来,通常我们会使用下面这3个命令来表现。
A.set_clock_latency 命令
set_clock_latency:其语法如下:
set_clock_latency value [-rise] [-fall] [-min] [-max] [-source][-early] [-late] [clocks object_list]
使用 set_clock_latency 我们可以表现 CTS 的 Insertion Delay (就是时钟源点到触发器时钟Pin 的延时)。例如,
dc_shell_t> set_clock_latency 4.0 [get_clocks SYSCLK]
表示我们定义了时钟 SYSCLK 的 Insertion Delay 为 4(ns)。
B.set_clock_uncertainty 命令
set_clock_uncertainty其语法如下:
set_clock_uncertainty value [-from object_list -to object_list] [-rise] [-fall] [-setup] [-hold] clocks object_list
set_clock_uncertainty 描述了 clock 沿的不确定区间,因此我们可以使用该命令表现 CTS 的 Skew。例如, dc_shell_t> set_clock_uncertainty 0.5 –setup [get_clocks SYSCLK] 使用 –setup 选项,
由于一般综合不考虑 Hold 的 Timing check,因为此时的物理位置、延时都没有最终确定,因此可能此时修复的 Hold,在 P&R 后就变的多余了。因此综合时只考虑最大延时(即 Setup check)满足时序要求。 表示在 Setup 检查时,Capture Clock 的时钟沿会提前 0.5(ns)。
由于在 CTS 后,CTS Skew 导致 Capture Clock 的沿可能提前,当然也可能滞后,但是不可预知,因此我们按照比较严格的约束。 使用 set_clock_uncertainty 也可以模拟时钟源的抖动,时钟源的抖动也是导致Capture Clock 的沿可能提前或者滞后。例如,假设,时钟源的抖动是 0.2ns,CTS 的最大Skew 为 0.5 ns,那么,我们在约束时钟的 Uncertainty 时应该为:
dc_shell_t> set_clock_uncertainty [expr 0.2 + 0.5] –setup [get_clocks SYSCLK]
C.set_clock_transition 命令 set_clock_transition 的语法如下:
set_clock_transition transition_value [-rise | -fall][-min] [-max] clock_list
由于实际的 CTS,时钟的上升、下降沿不可能是理想的,都可能存在一定的 Transition 时间,我们可以使用该命令定义时钟的上升、下降沿的 Transition 时
间。例如:
dc_shell_t> set_clock_ transition 0.5 [get_clocks SYSCLK]
表示时钟上升、下降沿的Transition 时间为0.5(ns)。时钟的 transition 时间会影响触发器输出数据的Delay。
(2)I/O端口的时序设定
Design Compiler 默认Input ports 信号的到达时间为0,并且不对Output ports 进行任何的约束。 design compiler提供set_input_delay 和set_output_delay,分别对对I/O端口的Input Ports 和 Output Ports 进行时序约定。
A.set_input_delay 命令
set_input_delay 是设置设计的输入端口的延时相对于时钟的延时,延时值是外部逻辑的延时,语法如下:
set_input_delay delay_value [-clock clock] [-clock_fall] [-level_sensitive] [-network_latency_included] [-source_latency_included] [-rise] [-fall] [-max] [-min] [-add_delay] port_pin_list
如果前级电路(芯片)的DO 相对以时钟 Clk 的延时为 10 ns,那么我们可以设置输入的 Input Delay 为 10ns,在 DC 中设置如下, dc_shell-t> create_clock –name clk –period 20 [get_ports CLK] dc_shell-t> set_input_delay 10 –clock clk [get_ports DI] 延时值是在指定的目标( DI)相对与时钟(–clock clk)的延时。
B.set_output_delay 命令
set_output_delay 是设置设计的输出端口相对于时钟的延时。要特别注意,延时值也是外部逻辑的延时,set_output_delay 的含义如下图所示: set_output_delay 的语法如下:
set_output_delay delay_value [-clock clock] [-clock_fall][-level_sensitive] [-network_latency_included] [-source_latency_included] [-rise] [-fall] [-max] [-min] [-add_delay] [-group_path group_name] port_pin_list
Output Delay 设置示意如下,延时值是设置片外的Delay。
6、Multiple Instance问题
Multiple Instance 是指在上层设计中多次调用同一个子层设计单元,如图所示,U2/U3 和 U2/U4 都是实例化设计单元C
对于这种包含多次调用同一个设计单元的设计,在综合前必需给出处理办法,否则无法直接Compile。常用的方法有 Uniquify, Don’t-Touch 以及 Ungroup
7、Compile
当环境、约束设定完成后,就可以使用 Compile 命令进行逻辑的映射和优化了。如下:
dc_shell-t > compile
8. 输出报告,网表
综合完成后,我们需要察看综合结果是否满足我们的时序要求,可以使用如下的命令:
dc_shell-t> report_timing
dc_shell-t>report_constraint
dc_shell-t> report_area
如果要输出综合的网表,可以使用 Write 命令,该命令也支持多种文件格式的网表,通常我们要保存 DB 和Verilog 格式的网表,如下:
dc_shell-t> write –f db –h –o TOP.db
dc_shell-t> write –f verilog –h –o TOP.db