前言
理论上,使用Tcl可以在Vivado上完成一切操作,但是没必要,因为命令太多,很难记忆,我们只需要知道几个常用的即可,方便我们使用Vivado。
对于时序约束,我们常用的tcl命令,最多的是时钟相关的,因为约束也是对时钟进行约束。
正文
下面给出几个常用的操作,并给出示例效果(以Xilinx的工程示例Wavegen为例),一起看看吧。
- report_clocks
直接在Tcl Console框内输入:
report_clocks
即可显示,工程中关于时钟的约束情况。
但是,前提是,打开了Elaborated Design或者Synthesized Design或者implemented Design。
如果没有打开三者之一,则会提示:
ERROR: [Common 17-53] User Exception: No open design.
Please open an elaborated, synthesized or implemented design before executing this command.
例如我打开了Elaborated Design之后,输入该命令:
Clock Report
Attributes
P: Propagated
G: Generated
A: Auto-derived
R: Renamed
V: Virtual
I: Inverted
S: Pin phase-shifted with Latency mode
Clock Period(ns) Waveform(ns) Attributes Sources
clk_pin_p 5.000 {0.000 2.500} P {clk_pin_p}
virtual_clock 6.000 {0.000 3.000} V {}
clk_samp 192.000 {0.000 96.000} P,G {clk_gen_i0/BUFHCE_clk_samp_i0/O}
spi_clk 6.000 {3.000 6.000} P,G,I {spi_clk_pin}
clk_rx_clk_core 5.000 {0.000 2.500} P,G,A {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKOUT0}
clk_tx_clk_core 6.000 {0.000 3.000} P,G,A {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKOUT1}
clkfbout_clk_core 5.000 {0.000 2.500} P,G,A {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKFBOUT}
====================================================
Generated Clocks
====================================================
Generated Clock : clk_samp
Master Source : clk_gen_i0/clk_core_i0/clk_tx
Master Clock : clk_tx_clk_core
Divide By : 32
Generated Sources : {clk_gen_i0/BUFHCE_clk_samp_i0/O}
Generated Clock : spi_clk
Master Source : dac_spi_i0/out_ddr_flop_spi_clk_i0/ODDR_inst/C
Master Clock : clk_tx_clk_core
Divide By : 1
Generated Sources : {spi_clk_pin}
Generated Clock : clk_rx_clk_core
Master Source : clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKIN1
Master Clock : clk_pin_p
Multiply By : 1
Generated Sources : {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKOUT0}
Generated Clock : clk_tx_clk_core
Master Source : clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKIN1
Master Clock : clk_pin_p
Edges : {1 2 3}
Edge Shifts(ns) : {0.000 0.500 1.000}
Generated Sources : {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKOUT1}
Generated Clock : clkfbout_clk_core
Master Source : clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKIN1
Master Clock : clk_pin_p
Multiply By : 1
Generated Sources : {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKFBOUT}
====================================================
User Uncertainty
====================================================
====================================================
User Jitter
====================================================
时钟的属性也一览无余,我们注意到这三个时钟:
clk_rx_clk_core 5.000 {0.000 2.500} P,G,A {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKOUT0}
clk_tx_clk_core 6.000 {0.000 3.000} P,G,A {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKOUT1}
clkfbout_clk_core 5.000 {0.000 2.500} P,G,A {clk_gen_i0/clk_core_i0/inst/mmcm_adv_inst/CLKFBOUT}
其时钟属性包括A,即自动生成的时钟,也就是这几个时钟不是我们手动在Xdc文件中约束的时钟,而是IP核根据用户定制设置,自动约束的时钟。
对于经过时钟IP的主时钟,约束只需要约束输入即可,输出时钟IP会自动推断。有的时候,(可能是高版本的Vivado工具),输入时钟也给你自动约束好了,再约束一次反而会有warning?面对这种情况,约束与不约束都行,看个人习惯,可不用理会这种warning。
至于为什么多了一个clkfbuf_clk_core,看看IP,我们没有生成这么一个时钟呀。
嗯,了解一下IP就知道这是IP自动生成的一个反馈时钟。
我们还注意到,对于差分输入时钟的约束:
clk_pin_p 5.000 {0.000 2.500} P {clk_pin_p}
仅仅约束P端即可。
这是允许且推荐的,对差分时钟的约束方式,没有必要对PN都约束。
- report_clock_networks
这个tcl命令主要还是用于查看有没有遗忘的主时钟约束,如果没有,例如我们的wavegen工程:
report_clock_networks
------------------------------------------------------------------------------------
| Tool Version : Vivado v.2019.1 (win64) Build 2552052 Fri May 24 14:49:42 MDT 2019
| Date : Thu Oct 7 22:45:10 2021
| Host : DESKTOP-REBORN running 64-bit major release (build 9200)
| Command : report_clock_networks
| Design : wave_gen
| Device : 7k70t-fbg676
| Speed File : -1 PRODUCTION 1.12 2017-02-17
------------------------------------------------------------------------------------
Clock Networks Report
Constrained Clocks
-------------------
Clock clk_pin_p (200MHz)(endpoints: 645 clock, 1 nonclock)
Port clk_pin_p
Clock virtual_clock (166.667MHz)(endpoints: 0 clock, 0 nonclock)
如果我们将约束文件中的主时钟约束注释掉,注意, wavegen工程的主时钟在IP的XDC文件里:
注释掉:
综合之后,再运行这条指令:
Clock Networks Report
Constrained Clocks
-------------------
Clock virtual_clock (166.667MHz)(endpoints: 0 clock, 0 nonclock)
Unconstrained Clocks
-------------------
Clock clk_pin_p (endpoints: 645 clock, 1 nonclock)
Port clk_pin_p
可见,就会出现提示,这个主时钟未约束。
只要是它提示的,都要尽量给予约束。
注:如果要在GUI界面显示clock networks,可输入命令:
report_clock_networks -name mainclock
可以更直观看到时钟信息。
- check_timing
该命令可以检查更过内容,我们在wavegen中尝试输入,可得:
check_timing report
Table of Contents
-----------------
1. checking no_clock
2. checking constant_clock
3. checking pulse_width_clock
4. checking unconstrained_internal_endpoints
5. checking no_input_delay
6. checking no_output_delay
7. checking multiple_clock
8. checking generated_clocks
9. checking loops
10. checking partial_input_delay
11. checking partial_output_delay
12. checking latch_loops
1. checking no_clock
--------------------
There are 0 register/latch pins with no clock.
2. checking constant_clock
--------------------------
There are 0 register/latch pins with constant_clock.
3. checking pulse_width_clock
-----------------------------
There are 0 register/latch pins which need pulse_width check
4. checking unconstrained_internal_endpoints
--------------------------------------------
There are 0 pins that are not constrained for maximum delay.
There are 0 pins that are not constrained for maximum delay due to constant clock.
5. checking no_input_delay
--------------------------
There are 0 input ports with no input delay specified.
There is 1 input port with no input delay but user has a false path constraint. (MEDIUM)
6. checking no_output_delay
---------------------------
There are 0 ports with no output delay specified.
There are 0 ports with no output delay but user has a false path constraint
There is 1 port with no output delay but with a timing clock defined on it or propagating through it (LOW)
7. checking multiple_clock
--------------------------
There are 0 register/latch pins with multiple clocks.
8. checking generated_clocks
----------------------------
There are 0 generated clocks that are not connected to a clock source.
9. checking loops
-----------------
There are 0 combinational loops in the design.
10. checking partial_input_delay
--------------------------------
There are 0 input ports with partial input delay specified.
11. checking partial_output_delay
---------------------------------
There are 0 ports with partial output delay specified.
12. checking latch_loops
------------------------
There are 0 combinational latch loops in the design through latch input
可见,其检查内容之多:
1. checking no_clock
2. checking constant_clock
3. checking pulse_width_clock
4. checking unconstrained_internal_endpoints
5. checking no_input_delay
6. checking no_output_delay
7. checking multiple_clock
8. checking generated_clocks
9. checking loops
10. checking partial_input_delay
11. checking partial_output_delay
12. checking latch_loops
为了尝试效果,我们同样注释掉主时钟约束:
再输入 check_timing :
check_timing report
Table of Contents
-----------------
1. checking no_clock
2. checking constant_clock
3. checking pulse_width_clock
4. checking unconstrained_internal_endpoints
5. checking no_input_delay
6. checking no_output_delay
7. checking multiple_clock
8. checking generated_clocks
9. checking loops
10. checking partial_input_delay
11. checking partial_output_delay
12. checking latch_loops
1. checking no_clock
--------------------
There are 604 register/latch pins with no clock driven by root clock pin: clk_pin_p (HIGH)
There are 41 register/latch pins with no clock driven by root clock pin: clk_gen_i0/BUFHCE_clk_samp_i0/O (HIGH)
2. checking constant_clock
--------------------------
There are 0 register/latch pins with constant_clock.
3. checking pulse_width_clock
-----------------------------
There are 0 register/latch pins which need pulse_width check
4. checking unconstrained_internal_endpoints
--------------------------------------------
There are 1468 pins that are not constrained for maximum delay. (HIGH)
There are 0 pins that are not constrained for maximum delay due to constant clock.
5. checking no_input_delay
--------------------------
There is 1 input port with no input delay specified. (HIGH)
There is 1 input port with no input delay but user has a false path constraint. (MEDIUM)
6. checking no_output_delay
---------------------------
There are 0 ports with no output delay specified.
There are 0 ports with no output delay but user has a false path constraint
There is 1 port with no output delay but with a timing clock defined on it or propagating through it (LOW)
7. checking multiple_clock
--------------------------
There are 0 register/latch pins with multiple clocks.
8. checking generated_clocks
----------------------------
There are 2 generated clocks that are not connected to a clock source. (HIGH)
9. checking loops
-----------------
There are 0 combinational loops in the design.
10. checking partial_input_delay
--------------------------------
There are 0 input ports with partial input delay specified.
11. checking partial_output_delay
---------------------------------
There are 0 ports with partial output delay specified.
12. checking latch_loops
------------------------
There are 0 combinational latch loops in the design through latch input
可见,也报出了缺时钟:
1. checking no_clock
--------------------
There are 604 register/latch pins with no clock driven by root clock pin: clk_pin_p (HIGH)
There are 41 register/latch pins with no clock driven by root clock pin: clk_gen_i0/BUFHCE_clk_samp_i0/O (HIGH)
为了专门检查:checking no_clock
可以针对输入命令:
check_timing -override_defaults no_clock
可得:
check_timing report
Table of Contents
-----------------
1. checking no_clock
1. checking no_clock
--------------------
There are 604 register/latch pins with no clock driven by root clock pin: clk_pin_p (HIGH)
There are 41 register/latch pins with no clock driven by root clock pin: clk_gen_i0/BUFHCE_clk_samp_i0/O (HIGH)
直接了当。
这篇短文就介绍到这里。