在前面介绍了如何进行添加约束,一遍所有的组合逻辑都能正确的进行时间优化,满足寄存器的setup、hold.
但是呢,往往这些约束信息,需要很多条目。如果每次都手动输入,就有很大几率出错。 所以脚本化,是必然要进行的、
DC运行后,会自动的执行tcl脚本。我们所有的anlayze、elaborate、set_max_area、creat_clock等等约束,都要在这里面书写。
其中 | 是unix的管道,把输出结果,送至tee命令。
tee命令 又把管道内容,一边输出至屏幕,一边存入run.log文件内。
推荐流程:
Erase all constraints from the current design before applying new constraints.
我们完全可以把整个digital分成几个模块,然后一个个的设为current-design,然后施加约束。 最好每次都进行reset_design操作。
多多使用备注 : Include comments in your scripts。
避免脚本文件过多层次的source文件,一致两层即可。
dcprocheck命令可以用于检查 语法。
check_timg会报出所有未约束的信息。
使用redirect命令,可以把不同阶段的log信息,存入不同的文件内,以便于后面debug。因为DC log文件太大了。
实验lab4
我们要学习怎么去创建setup文件,怎么去读入约束综合保存.
创建.synnopsys_dc.setup ,里面填入 search_path target_librarylink_library
启动dc-shell-xg-t
貌似我们搞错了,这个是用脚本实现的. 但是我们连dv界面实现都没有过,可以先进行尝试.
第二步, analyze 文件, 并进行elabrate ,之后current_design可以查看到。
第三步: 我们可以start_gui,用界面看下这个current的 hierarchical结果
没找到怎么看hierarchical的按钮啊, 我靠,好生气,dc崩掉了,刚才这些东西还得重新来一遍. 看来还是脚本好啊,
可重复性好.
00
这个怎么约束? 先看设计指标,
时钟333M 晶体源到clk_port最大延迟700ps network延迟是 300±30ps
时钟jitter 是±40ps setup_marging时间是50ps 时钟transition时间为120ps
寄存器的固有setup是0.2ns
组合逻辑S的延迟是2.2ns
左下角虚线框的F3寄存器 到sel[1:0]的之间延迟为1.4ns
combo的输出至Cout的最大时间延迟是400ns
右上角虚线框的F6寄存器的固有setup时间为80ns
逻辑V,输出至out2的最大延迟为810ps
out3 后面需要有一个充clk电时间400ps,才能完成跳变.
cin12至cout的最大延迟是2,45ns
整个面积是540门
我们先建一个srcipt约束脚本吧 先试试写.
哎, 好多都没算对........
我们需要再进一步的理解到底怎么计算:
clock_uncertainty = jitter + skew + set_margin
其中 clock_skew是代表如下情况: 由于时钟树cell_delay不一样,时钟到达每个寄存器的时刻就会不一样。clock_skew的值 = 最早和最慢的时间差值。
所以在分析每个寄存器的setup、hold时候,都需要认为 前一级是最慢到达,自己是最早到达。 这样时序最紧张。 所以我们分析时,只需要考虑一倍的clock_skew
就可以,不用考虑两倍的skew值。因为skew本身就是一个 最大- 最小
jitter值:是±40ps。jitter是什么?怎么计算的?
其实,有许多种jitter的计算方法,比如cycle-to-cycle 、Period_jitter、half_ Period_jitter、
但一般jitter值是指cycle_to_cycle jitter = T2 -T1、 T3-T2 .... 即两个相邻周期的差值。故而是正负值。
在分析setup时,需要怎么考虑? 考虑1倍的jitter,即意味着,考虑了T2提前到来的情况。两个相邻时钟周期都需要这样考虑。而且仅需要考虑1倍的jitter。
下面我们再重新分析下时钟约束:
1. 周期是3ns,这个比较容易
2、第二个是clk_source_delay 0.7ns ,也比较容易
3、第三个 到达每个寄存器的时钟时间为 300±30ps,意味着 clock_network_delay =300ps,skew = 30 * 2 =60 ps
4 、jitter是40ps
5. setup_margin 值为 50ps
6 . transition 值为120ps
所以
create_clock -period 3.0 [get_ports clk]
set_clock_latency -source -max 0.7 [get_clocks clk]
set_clock_latency -max 0.3 [get_clocks clk]
set_clock_uncertainty -setup 0.15 [get_clocks clk] # 0.15 = 0.6 + 0.4 +0.5
set_clock_transition 0.12 [get_clocks clk]
下面考虑 input_delay约束
先清楚一个概念,input_delay是描述哪段时间的? 是下面箭头所对应的时间。如果DC知道了这段时间,根据时钟周期,自然就能推断
组合逻辑N所最大能占用的时间了。
我们知道寄存器的setup时间是0.2ns
Input Port 是说:data1、data2穿过组合逻辑的最大时间为2.2ns(在这认为S是一个已经综合好的模块,其最大delay就是2.2),以为着 3- 2.2 - 0.2 - x =0
这里的x就是 input_delay值: x = 0.6 这个思路是对的,但是错在把 时钟当成了标准的3ns来看,没有考虑时钟network延迟、时钟uncertainty,
如果考虑network_delay,这样整个约束会宽松,所以不考虑。考虑uncertainty,认为可以认为时钟提前到来,这样约束能紧凑。
# The maximum "input delay" (external) on ports data1 and data2 is:
# clock period - clock uncertainty - delay of S - register setup time =
# 3.0 - 0.15 - 2.2 - 0.2 = 0.45ns
#
set_input_delay -max 0.45 -clock clk [get_ports data*]
再看sel1怎么约束:
The latest F3 data arrival time at the sel port is 1.4ns (absolute time).
这句话的意思是: F3到达sel的绝对时刻是1.4ns时刻。 因为F3的时钟跟clk一样,具有source_delay network_delay 共计1ns,
从0时刻开始算,1ns时刻之时,F3时钟才刚有,然后要保证1.4ns时,送达selport, 意味着 F3---sel之间的时间是 1.4-1ns = 0.4ns
set_input_delay -max 0.4 -clock clk [get_ports sel]
从cin1、2到cout的时间最大为2.45ns? 这以为这什么?好像我们不能直接对cin1、2进行input_delay约束。
假设 cin1、2前连接了一段逻辑、cout连接了一段逻辑。 这样两个时钟之间,我们需要考虑 边沿不对齐的情况,uncertainty值。
此时 source_delay,network_delay我们都不用考虑,因为我们此时不知道。我们所知道的 source_delay、network_delay都是局限在my_design内的。
而且,DC知道了这两个信息后,会自动延后时钟处理。所以不考虑,只考虑时钟固有的特性 uncertainty导致时钟沿对不齐的情况。
此时 input_delay 和output_delay共剩余了 3- 0.15- 2.45 = 0.4ns的时间。
我们可以分配 0.2 0.2 、0.3 0.1 等
set_input_delay -max 0.3 -clock clk [get_ports Cin*]
set_output_delay -max 0.1 -clock clk [get_ports Cout]
接下来看output-delay的约束
output_delay的值 = 图书箭头的值即 Comb T + steup FF4
1. The maximum delay of the external combo logic at port out1 is 420ps; F6 has a setup time of 80ps.
描述的就是 组合逻辑最大为420ps,F6setup是80ps,直接 output_delay = 0.5ns
set_output_delay -max 0.5 -clock clk [get_ports out1]
其实这个地方不明白为什么不考虑uncertainty了啊? 因为此时如果F6滞后到来,我觉得需要设置 0.5+ 0.15 = 0.65ns
2. The maximum internal delay to out2 is 810ps
这个810ps是说哪个? 是整个R4---V----out2的时间最大为810ps,
所以需要约束 3- 0.15 - 0.81
set_output_delay -max 2.04 -clock clk [get_ports out2]
3. set_output_delay -max 0.4 -clock clk [get_ports out3]
这里强调下:为什么有时候需要考虑uncertaity,有时候又不要呢? 因为input_delay、output_delay都是描述的时间值。
如果这段时间很明确,就直接写就可以了。
所有需要考虑uncertainty的,都是因为给出了 内部的组合逻辑的最值,反过来去推导input_delay、output_delay怎么约束,不是直接告诉你