跳转到主要内容

FPGA时序约束之Tcl命令的对象及属性

demi 提交于

<iframe width="600" height="380" frameborder="0" src="https://v.qq.com/txp/iframe/player.html?vid=n3011e4inso&quot; allowFullScreen="true"></iframe>

<font size="4" style="line-height: 40px;" color="red"><strong>Vivado时序约束中Tcl命令的对象及属性</strong></font>

在前面的章节中,我们用了很多Tcl的指令,但有些指令并没有把所有的参数多列出来解释,这一节,我们就把约束中的Tcl指令详细讲一下。

我们前面讲到过get_pins和get_ports的区别,而且我们也用过get_cells、get_clocks和get_nets这几个指令,下面就通过一张图直观展现它们的区别。

<center><img width="600" src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047118-88740-1.jp…; alt=""></center><br>

get_clocks后面的对象是我们之前通过create_clocks或者create_generated_clocks创建的时钟,不在硬件上直接映射。

我们再来看下各个命令的属性。

<font color="red"><strong>1. port</strong></font>

我们可以通过Tcl脚本查看port的所有属性,比如上面的wave_gen工程中,有一个port是clk_pin_p,采用如下脚本:

<pre>set inst [get_ports clk_pin_p]
report_property $inst</pre>

显示如下:
<img src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047118-88741-2.pn…; alt=""><br>

get_ports的使用方法如下:

<pre># 获取所有端口
get_ports *

# 获取名称中包含data的端口
get_ports *data*

# 获取所有输出端口
get_ports -filter {DIRECTION == OUT}

# 获取所有输入端口
all_inputs

# 获取输入端口中名字包含data的端口
get_ports -filter {DIRECTION == IN} *data*

# 获取总线端口
get_ports -filter {BUS_NAME != ""}</pre>

<font color="red"><strong>2. cell</strong></font>

按照上面的同样的方式,获取cell的property,如下:
<img src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047118-88742-3.pn…; alt=""><br>

get_cells的使用方法如下:
<pre># 获取顶层模块
get_cells *

# 获取名称中包含字符gen的模块
get_cells *gen*

# 获取clk_gen_i0下的所有模块
get_cells clk_gen_i0/*

# 获取触发器为FDRE类型且名称中包含字符samp
get_cells -hier filter {REF_NAME == FDRE} *samp*

# 获取所有的时序单元逻辑
get_cells -hier -filter {IS_SEQUENTIAL == 1}

# 获取模块uart_rx_i0下两层的LUT3
get_cells -filter {REF_NAME == LUT3} *uart_tx_i0/*/*</pre>

<font color="red"><strong>3. pin</strong></font>

获取pin的property,如下:
<img src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047118-88743-4.pn…; alt=""><br>

get_pins的使用方法如下:
<pre># 获取所有pins
get_pins *

# 获取名称中包含字符led的引脚
get_pins -hier -filter {NAME =~ *led*}

# 获取REF_PIN_NAME为led的引脚
get_pins -hier -filter {REF_PIN_NAME == led}

# 获取时钟引脚
get_pins -hier -filter {IS_CLOCK == 1}

# 获取名称中包含cmd_parse_i0的使能引脚
get_pins -filter {IS_ENABLE == 1} cmd_parse_i0/*/*

# 获取名称中包含字符cmd_parse_i0且为输入的引脚
get_pins -filter {DIRECTION == IN} cmd_parse_i0/*/*</pre>

<font color="red"><strong>4. net</strong></font>

获取pin的property,如下:
<img src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047118-88744-5.pn…; alt=""><br>

get_nets的使用方法如下:
<pre># 获取所有nets
get_nets *

# 获取名称中包含字符send_resp_val的网线
get_nets -hier *send_resp_val*
get_nets -filter {NAME =~ *send_resp_val*} -hier

# 获取穿过边界的同一网线的所有部分
get_nets {resp_gen_i0/data4[0]} -segments

# 获取模块cmd_parse_i0下的所有网线
get_nets -filter {PARENT_CELL == cmd_parse_i0} -hier

# 获取模块cmd_parse_i0下的名称中包含字符arg_cnt[]的网线
get_nets -filter {PARENT_CELL == cmd_parse_i0} -hier *arg_cnt[*]</pre>

这5个tcl指令的常用选项如下表:

<table style="width: 484px;" border="1" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th style="width: 75px;" width="90">命令</th>
<th style="width: 83px;" width="58">-hierarchy</th>
<th style="width: 53px;" width="63">-filter</th>
<th style="width: 96px;" width="94">-of_objects</th>
<th style="width: 66px;" width="57">-regexp</th>
<th style="width: 71px;" width="84">-nocase</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 75px;" width="94">get_cells</td>
<td style="width: 83px;" width="56">√</td>
<td style="width: 53px;" width="61">√</td>
<td style="width: 96px;" width="100">√</td>
<td style="width: 66px;" width="59">√</td>
<td style="width: 71px;" width="62">√</td>
</tr>
<tr>
<td style="width: 75px;" width="87">get_nets</td>
<td style="width: 83px;" width="56">√</td>
<td style="width: 53px;" width="61">√</td>
<td style="width: 96px;" width="100">√</td>
<td style="width: 66px;" width="60">√</td>
<td style="width: 71px;" width="62">√</td>
</tr>
<tr>
<td style="width: 75px;" width="87">get_pins</td>
<td style="width: 83px;" width="56">√</td>
<td style="width: 53px;" width="61">√</td>
<td style="width: 96px;" width="100">√</td>
<td style="width: 66px;" width="60">√</td>
<td style="width: 71px;" width="62">√</td>
</tr>
<tr>
<td style="width: 75px;" width="87">get_ports</td>
<td style="width: 83px;" width="56">&nbsp;</td>
<td style="width: 53px;" width="61">√</td>
<td style="width: 96px;" width="100">√</td>
<td style="width: 66px;" width="60">√</td>
<td style="width: 71px;" width="62">√</td>
</tr>
<tr>
<td style="width: 75px;" width="87">get_clocks</td>
<td style="width: 83px;" width="56">&nbsp;</td>
<td style="width: 53px;" width="61">√</td>
<td style="width: 96px;" width="100">√</td>
<td style="width: 66px;" width="60">√</td>
<td style="width: 71px;" width="62">√</td>
</tr>
</tbody>
</table>

这5个Tcl命令对应的5个对象之间也有着密切的关系,下图所示的箭头的方向表示已知箭头末端对象可获取箭头指向的对象。

<center><img src="http://xilinx.eetrend.com/files/2020-01/wen_zhang_/100047118-88745-6.pn…; alt=""></center><br>

以wave_gen中的clk_gen_i0模块为例来说明上面的操作:

<pre># 获取模块的输入引脚
get_pins -of [get_cells {clk_gen_i0/clk_core_i0}] -filter {DIRECTION == IN}

# 已知引脚名获取所在模块
get_cells -of [get_pins clk_gen_i0/clk_core_i0/clk_in1_n]

# 已知模块名获取与该模块相连的网线
get_nets -of [get_cells {clk_gen_i0/clk_core_i0}]

# 已知引脚名获取与该引脚相连的网线
get_nets -of [get_pins clk_gen_i0/clk_core_i0/clk_rx]

# 已知时钟引脚获取时钟引脚对应的时钟
get_clocks -of [get_pins clk_gen_i0/clk_core_i0/clk_rx]</pre>

需要注意的是:

① -hier不能和层次分隔符“/”同时使用,但“/”可出现在-filter中

② 可根据属性过滤查找目标对象

③ -filter中的属性为:“==”(相等)、“!=”(不相等)、"=~"(匹配)、"!~"(不匹配),若有多个表达式,其返回值为bool类型时,支持逻辑操作(&& ||)

本文转自:<a href="https://mp.weixin.qq.com/s/qO2oJp2GdpWzyDMrIHKX1Q"><u>科学计算technomania</…;,作者:猫叔,转载此文目的在于传递更多信息,版权归原作者所有。