前言

理论上,使用Tcl可以在Vivado上完成一切操作,但是没必要,因为命令太多,很难记忆,我们只需要知道几个常用的即可,方便我们使用Vivado。

对于时序约束,我们常用的tcl命令,最多的是时钟相关的,因为约束也是对时钟进行约束。

正文

下面给出几个常用的操作,并给出示例效果(以Xilinx的工程示例Wavegen为例),一起看看吧。

  1. 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都约束。

  1. 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文件里:

Vivado中用于时钟操作的几个Tcl命令_fpga

Vivado中用于时钟操作的几个Tcl命令_自动生成_02

注释掉:

Vivado中用于时钟操作的几个Tcl命令_主时钟_03

综合之后,再运行这条指令:

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

可以更直观看到时钟信息。

  1. 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

为了尝试效果,我们同样注释掉主时钟约束:

# Differential clock only needs one constraint
#create_clock -period 5.000 [get_ports clk_in1_p]
#set_input_jitter [get_clocks -of_objects [get_ports clk_in1_p]] 0.05


#set_property PHASESHIFT_MODE WAVEFORM [get_cells -hierarchical *adv*]

再输入 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)

直接了当。

这篇短文就介绍到这里。