DC实战
- 0. 学习目标
- 1. Design
- 1.1 Design Schematic
- 1.2 Design Specification
- 2. 配置文件和约束文件
- 2.1 配置文件
- (1) common_setup.tcl 文件
- (2) dc_setup.tcl 文件
- (3) .synopsys_dc.setup 文件
- 2.3 启动工具查看单元库信息
- (1) 查看目标库的时间单位
- 2.3 设计约束文件
- (1) 时钟约束
- (2) 输入输出路径时序约束
- (3) 组合逻辑约束
- (4) 工作条件约束
- (5) 语法检查
- 3. 逻辑综合
- 3.1 启动工具并检查信息
- 3.2 综合
- 3.3 脚本文件
官方 Lab_workshop 里面的实例(Lab 3 & Lab4)。
重点是时序约束文件的编写。
0. 学习目标
1. Design
1.1 Design Schematic
1.2 Design Specification
2. 配置文件和约束文件
官方给出 lab 的文件内容如下:
这里,可以自己先创建两个文件夹,如下所示:
① 和 ④ 主要存放的是综合前后的文件,比如读入设计文件之后,可以以 .ddc 格式保存在unmapped文件夹中。对于综合完成之后设计,可以以 .ddc 格式保存在 mapped 文件夹中。 .ddc 是DC工具内置的一种数据格式。
2.1 配置文件
lab中写好的两个文件:
(1) common_setup.tcl 文件
① .sdb 结尾的库文件是符号库。
(2) dc_setup.tcl 文件
(3) .synopsys_dc.setup 文件
该文件需要放在DC的启动目录下。
基于lab提供的文件,自己简单配置一下该文件的内容,具体如下:
2.3 启动工具查看单元库信息
使用如下命令启动工具:
$ dc_shell -topo | tee -i lab3.log
① | tee -i lab3.log
会把工具运行过程输出在中,终端显示的全部内容保存到文件中
(1) 查看目标库的时间单位
一般情况下,在读入设计文件的时候,链接库和目标库才会被读入到DC的内存中。
① 这里,为了查看时间单位,就手动读入库文件,使用到的命令如下:
dc_shell -topo> read_db <target_library_FILE_NAEM>
这里使用的是 LIBRARY FILE NAME
结果如下:
② 然后,使用lsit_libs
可以查看读取到的库文件信息:
这里,一个是库名称,一个是库文件的名称。
③ 使用如下命令,报告库的信息:
redirect -file lib.rpt {report_lib <LIBRARY_NAME>}
- 这里使用的是 LIBRARY NAME
redirect
是重定向的命令,-file
是将命令产生信息保存到文件中,lib.rpt
是要保存信息到文件,后面的{}
中存放的是要执行的命令。
lib.rpt
中的部分信息如下:
可以看出,时间单位是 1ns
。
线负载模型信息:
延时计算时候的一些信息:
除此之外,还有其他各种信息,这里就不再具体给出了。
2.3 设计约束文件
根据设计的Specification,编写综合时要用的约束文件。
(1) 时钟约束
① 时钟频率为 333.33 Mhz,对应的时钟周期就是 3ns
create_clcok -period 3.0 [get_ports clk]
② source_latency(时钟源到时钟定义位置的延迟) 的最大值为 700ps
set_clock_latency -source -max 0.7 [get_porst clk]
③ network_latency (时钟定义位置到触发器时钟输入端的延迟) 最大值为300ps
set_clock_latency -max 0.7 [get_porst clk]
④ clock skew = +/- 30ps,clock jitter = +/- 40ns,setup time slack = 50ns
时钟源沿着不同的路径到达寄存器的时钟端口,skew 和 jitter 就是说是时钟的真正的到达时间可能比预期早或者晚。
首先,skew为 ±30 ps,那么就可能是发射时钟滞后30ps,捕获时钟提前30ps,那么对于建立时间而言,时钟的不确定性就是60ns。(就是说,时钟周期减去60ns之后的,然后才进行时序约束,才能满足上述情况。)
然后, jitter 为 ±40ps。发射沿和捕获沿的时钟抖动是互相不影响的,这里没有加倍。对于建立时间而言,考虑的是最查的情况,及提前 40 ps。
最后,再加上 50 ps 的建立时间裕量。
最终得到的时钟不确定性约束为:
set_clock_uncertainty -setup 0.15 [get_clocks clk]
⑤ 时钟的转换时间为120ns
set_clock_transition 0.3 [get_clocks clk]
(2) 输入输出路径时序约束
① data1和data2外部延时的计算
这里直接给出了输入到寄存的组合路径的延时,但是DC是通过输入延时来对这一部分路径进行约束的,所以要自己计算外部输出延时。
set_input_delay -max 0.45 -clock clk [get_ports data*]
② sel端口的外部延时
数据到达的最晚绝对时间是 1.4ns,就是说这个延时包含了时钟的 latency (source 和 network两部分,所以是700ps+300ps = 1ns)。
而 输入端口约束命令用的是相对延时,所以最终的约束如下:
set_input_delay -max 0.4 -clock clk [get_ports sel]
③ out1约束
这里是直接给除了外部延时为:420ps + 80ps = 0.5ns
set_output_delay -max 0.5 -clock clk [get_ports out1]
④ out2约束
给出的是out2内部组合逻辑的最大延时为810ns,那么外部延时的计算方式如下:
外部延时 = 时钟周期 - 内部路径延时 - 时钟不确定性 = 3 - 0.81 -0.15 = 2.04ns
set_output_delay -max 2.04 -clock clk [get_ports out2]
⑤ out3约束
out3只需要满足外部的一个400ns的建立时间即可,所以其约束如下:
set_output_delay -max 0.4 -clock clk [get_ports out3]
(3) 组合逻辑约束
组合路径的约束也可以通过set_input_delay
和 set_output_delay
来实现。
输入延时和输出延时的总和 = 3 - 2.45 - 0.15 = 0.4 ns
0.4 ns 分配个输入和输出就会有各种不同的组合,选取其中一种即可,后续可以分局综合的结果进行调整。
set_output_delay -max 0.3 -clock clk [get_ports Cin*]
set_output_delay -max 0.1 -clock clk [get_ports Cout]
(4) 工作条件约束
① 输入驱动强度
使用库里面的 bufbd1 来驱动除了 clk 和 Cin* 之外的所有输入端口:
set_driving_cell -lib_cell bufbd1 -library cb13fs120_tsmc_max \
[remove_from_collection [all_inputs] [get_ports "clk Cin*"]]
对于 Cin* 端口,指定了一个最大转换时间作为约束条件:
set_input_transition 0.12 [get_ports Cin*]
② 输出负载
set_load [expr 2 * {[load_of cb13fs120_tsmc_max/bufbd7/I]}] [get_ports out*]
set_load 0.025 [get_ports Cout*]
(5) 语法检查
最终得到的时序约束文件如下:
完成设计约束文件之后,可以进行语法检查,没有错误的情况下,显示如下:
如果出错,就会给出提示:
3. 逻辑综合
3.1 启动工具并检查信息
使用如下命令启动工具:
dc_shell -topo | tee -i lab3.log
(输出在终端的内容都会被记录到文件中,退出后再次启动会清除文件中原来的内容,然后写入新的内容。使用 -a
选项是在原来文件内容后面追加新的内容。这个主要是 tee
命令的功能,和逻辑综合工具关系不大。)
检查设置的库文件和路径
3.2 综合
读入设计:
连接和查看设计:
后面就是读取约束文件,编译和保存一些输出文件等内容。
3.3 脚本文件
综合的过程可以写到一个脚本文件中如下:
这里需要说明的是,因为是在拓扑模式下启动的,涉及到物理信息的读取,编译命令只能使用 compile_ultra
。
lab中给出的另一个脚本示例,这里主要涉及的是及进行综合前的一些操纵。