[FPGA18]时序约束辅助工具_Tcl命令的使用

Vivado时序约束辅助工具,Tcl命令的对象及属性

时序约束辅助工具

在之前的章节中,我们都是通过编写xdc文件的方式进行时序约束,其实,Vivado中还提供了两种图形界面的方式,帮我们进行时序约束:时序约束编辑器(Edit Timing Constraints )和时序约束向导(Constraints Wizard)。两者都可以在综合或实现后的Design中打开。

时序约束编辑器

  1. 点击"Window -> Timing Constraints"或者"SYNTHESIS -> Edit Timing Constraints"或者"IMPLEMENTATION -> Edit Timing Constraints",打开时序约束编辑器。
  2. 在编辑器中,可以看到我们之前做的所有约束,当然,还可以再添加、删除或修改时序约束。
  3. 比如我们要新添加一个主时钟,先选中左边的Create Clock,再点击+号添加约束,然后就会弹出"Create Clock"界面。
  4. 在"Clock name"选项中可设置时钟名字,在"Source objects"选项中可选择时钟,在"Waveform"选项中可设置时钟的周期、上升沿时间与下降沿时间,点击"OK" 完成约束
  5. 采用类似的方法我们还可以在时钟约束编辑器中进行各种类型的时钟约束

时序约束向导

  1. 点击"SYNTHESIS -> Constraints Wizard"或者"IMPLEMENTATION -> Constraints Wizard",可打开时钟约束向导
  2. 在向导中,我们可以看到已经编写的时序约束,还会自动识别出未约束的主时钟,我们可对其进行约束
  3. 同理,时序约束向导会按照主时钟约束、衍生时钟约束、输入延迟约束、输出延迟约束、时序例外约束、异步时钟约束等的顺序引导设计者创建约束。使用时钟约束向导可方便系统的完成时序约束全流程。

Tcl命令的对象及属性

  • 在Tcl指令中,常用到get_pins,get_ports,get_cells、get_nets和get_clocks这几个指令。
  • get_pins,get_ports,get_cells、get_nets这几条指令的访问对象均为具体硬件,具体如下:
  • get_clocks后面的对象是我们之前通过create_clocks或者create_generated_clocks创建的时钟,不在硬件上直接映射。

get_ports

  • 我们可以通过Tcl脚本查看某个port或者一些ports的所有属性,可采用如下脚本:
report_property [get_ports <ports_name>]
  • get_ports的使用方法如下:
# 获取所有端口
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 != ""}

get_cells

  • 我们可以通过Tcl脚本查看某个cell或者一些cells的所有属性,可采用如下脚本:
report_property [get_cells <cells_name>]
  • get_cells的使用方法如下:
# 获取顶层模块
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/*/*

get_pins

  • 我们可以通过Tcl脚本查看某个pin或者一些pins的所有属性,可采用如下脚本:
report_property [get_pins <pins_name>]
  • get_pins的使用方法如下:
# 获取所有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/*/*

get_nets

  • 我们可以通过Tcl脚本查看某个net或者一些nets的所有属性,可采用如下脚本:
report_property [get_nets <nets_name>]
  • get_nets的使用方法如下:
# 获取所有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[*]

Tcl指令常用选项

  • 这5个tcl指令的常用选项如下表所示:
命令 -hierarchy -filter -of_objects -regexp -nocase
get_cells
get_nets
get_pins
get_ports ×
get_clocks ×
  • 这5个Tcl命令对应的5个对象之间也有着密切的关系,下图所示的箭头的方向表示已知箭头末端对象可获取箭头指向的对象。
  • 以wave_gen中的clk_gen_i0模块为例来说明上面的操作:
# 获取模块的输入引脚
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]
  • 需要注意的是:
  1. hier不能和层次分隔符“/”同时使用,但“/”可出现在-filter中
  2. 可根据属性过滤查找目标对象
  3. -filter中的属性为:“==”(相等)、“!=”(不相等)、"="(匹配)、"!"(不匹配),若有多个表达式,其返回值为bool类型时,支持逻辑操作(&& ||)

参考:
1.Vivado时序约束辅助工具-Author:猫叔
2.Vivado时序约束中Tcl命令的对象及属性-Author:猫叔