DC综合5--基本的时序路径约束(下)
3、实战
首先设计的模块如下所示:
设计(约束)规格书如下所示:
(时钟的定义)
(寄存器建立时间定义)
(输入输出端口的延时定义)
(组合逻辑的定义)
上面的规格定义用来给我们进行时序约束使用,现在实践开始。
·创建.synopsys_dc.setup文件,设置好DC的启动环境
-->common_setup.tcl文件:
由于这里有物理库,因此可以使用DC的拓扑模式进行启动。
-->dc_setup.tcl文件:
-->.synopsys_dc.setup文件:
-------------------------------------这一步时间不够下可以忽略------------------
·启动DC,查看target_library的信息
-->启动的时候,我们使用管道开关,把DC的启动信息保存到startreport.log里面(dcshell -topo是DC的启动命令,启动时产生的信息,通过 | tee -i 流入start_report.log文件中):
(我们也可以通过启动gui界面进行输入命令,也可以在shell中输入命令)
-->由于我们仅仅是需要查看targetlibrary库的信息,因此我们只需要读入库:readdb sc_max.db
-->然后我们查看与这个库相关联的工艺库:list_libs,结果为:
我们可以看到,scmax.db是targetlibrary的的文件名称,而targetlibrary的库名字是cb13fs120tsmc_max
-->接着我们查看库信息:
这里我们使用重定向的命令,将报告的结果保存到哦lib.rpt这个文件中。redirect是重定向的命令,-file是将命令产生信息保存到文件中,lib.rpt是要保存信息到文件,后面的{}中存放的是要执行的命令。
然后在终端读取相应库的单位信息,时序单位为ns,电容单位为pf
------------------------------------------------------------------------------------------------
·创建约束
在完成启动文件的书写之后,我就需要根据设计规格书,进行书写约束了
-->时钟的约束(寄存器和寄存器之间的路径约束):
1.时钟频率为333.33MHz,因此时钟周期就是3ns:
createclock -period 3.0 [getports clk]
2.时钟源到时钟端口的(最大)延时即source latency是0.7ns
setclocklatency -source -max 0.7 [get_clocks clk]
3.时钟端口到寄存器的时钟端口延时即network latency为0.3ns有0.03ns的时钟偏移:
setclocklatency -max 0.3 [get_clocks clk]
4.时钟周期有0.04ns的抖动
5.需要为时钟周期留0.05ns的建立时间余量
这里我们就要设置不确定因素了,由于设计规格声明是对建立时间留余量,因此我们主要考虑建立时间的不确定因素:
首先是时钟偏移为±30ps,则有可能是前级时钟往后移30ps,同时本级时钟往前移30ps,对于建立时间偏移的不确定因素为30+30 =60ps;
然后是时钟抖动,前级的时钟抖动影响不到本级,因此只需要考虑本级的时钟抖动,由于是考虑建立时间,因此考虑本级时钟往前抖40ps,即对于建立时间抖动的不确定因素为40ps;
最后是要留50ps的建立时间不确定余量;
因此对于建立时间,总的不确定时间为60+40+50=150ps=0.15ns:
setclockuncertainty -setup 0.15 [get_clocks clk]
6.时钟转换时间为0.12ns:
setclocktransition 0.12 [get_clocks clk]
-->输入延迟约束(输入路径的约束):
1.规定模块内data1和data2端口的逻辑S延时最大为2.2ns,并没有直接告诉外部逻辑的延时,因此我们需要计算:
外部最大的延时为:clock period - clock uncertainty - delay of S - register setup time = 3.0 - 0.15 - 2.2 - 0.2 = 0.45ns, 因此有:
setinputdelay -max 0.45 -clock clk [get_ports data*]
2.对于sel端口,由于明显地、直接说了从外部数据发送端(指的是F3的clk)到sel端口的latest(最大)绝对延时是1.4ns,也就是说,这个绝对延时包括了时钟的latency延时,而inputdelay是不包括的,inputdelay是相对时钟的前级逻辑延时,是不包括时钟的latency,那么就需要减去时钟的latency(包括source 和 network):
1.4ns-(700ps + 300ps) = 0.4ns,那么就有:
setinputdelay -max 0.4 -clock clk [get_ports sel]
-->输出延时约束(输出路径的约束):
1.直接告诉了在out1的外部组合逻辑的最大延时为0.42ns,后级触发器的建立时间为0.08ns,也就是外部延时为0.42+0.08=0.5ns:
setoutputdelay -max 0.5 -clock clk [get_ports out1]
2.内部延时为810ns,应用前面的公式:时钟周期-内部延时(翻转与内部组合逻辑延时)-不确定时间=外部延时(外部组合逻辑+后级寄存器的建立时间),于是有:3-0.81-0.15=2.04ns,于是有:
setoutputdelay -max 2.04 -clock clk [get_ports out2]
3.意思是外部延时只有后级寄存器的建立时间要求:
setoutputdelay -max 0.4 -clock clk [get_ports out3]
-->组合逻辑的约束:
根据前面的公式可以得到:
3-0.15-输入延时-2.45=输出延时,于是可以得到:
输入延时+输出延时 = 0.4ns
由于设计规格没有规定这个比例,因此只要满足输入输出延时的关系满足上面的式子都可以,如果综合后有违规,我们后面可以再适当调整一下,设置为:
setinputdelay -max 0.3 -clock clk [get_ports Cin*]
setoutputdelay -max 0.1 -clock clk [get_ports Cout]
-->检查语法:
·启动DC
(·读入设计前的检查)
·读入设计(和查看设计)
这里和流程一样。主要是read、currentdesign 、link、checkdesign,这里就不具体演示了。
·应用约束和查看约束
-->直接执行source scripts/MY_DESIGN.con进行应用约束
-->查看有没有缺失或者冲突的关键约束:
check_timing,返回值为1,表示执行成功。
-->验证时钟是否约束正确:
report_clock
report_clock -skew
report_port -verbose
-->保存约束好的设计:
write -format ddc -hier -out unmapped/MY_DESIGN.ddc
·综合
(简单的步骤跟流程一样)
·综合后检查(与优化)
(简单的步骤跟流程一样)
·保存综合后的设计
(简单的步骤跟流程一样)