此页面是另一页的附加内容,应在本页之前阅读。这两个页面都是一系列页面的一部分,这些页面解释了时序(timing)计算背后的理论,展示了如何编写几个时序约束(timing constraints)并讨论了时序收敛(timing closure)的原理。
除非必须,否则不要使用简单的 search patterns
本页介绍如何使用通配符以 SDC 格式写入时序约束(timing constraints)。尽管通配符可以与多个 Tcl 命令一起使用,但本页重点介绍通常支持“-hierarchical”选项的命令: get_cells、 get_pins 和 get_nets。这些 Tcl 命令在另一个页面上解释。但请注意,某些 FPGA 工具不支持“-hierarchical”和所有这三个命令。
不幸的是,这三个命令的搜索功能非常有限,而且可能造成混淆: 如果不了解通配符的确切工作原理,搜索结果可能会出乎意料。特别是,当使用“-hierarchical”时,结果可能会令人惊讶,如下所示。
因此,当特定的 FPGA 工具支持相关的命令时,最好使用“-filter”选项。如果没有这样的支持,就只能使用简单的通配符。
本页中的所有示例均基于与其他相关页面相同的 Verilog 代码。
简单 search patterns
找到逻辑单元(logic elements)和其他对象(objects)的命令可以与 search pattern一起使用,也可以单独使用。如果没有 search pattern,则会找到所有相关的对象。例如,为了在 top-level hierarchy处找到所有引脚:
get_pins
而在整个 FPGA 设计中找到所有引脚的命令是:
get_pins -hierarchical
如果使用 search pattern ,则结果仅限于此 pattern。例如,要查找一个具有已知名称和 hierarchy中已知位置的特定引脚:
> get_pins foo_reg_reg/Q foo_reg_reg/Q > get_pins pll_i/clk_in1 pll_i/clk_in1 > get_pins pll_i/inst/clk_in1 pll_i/inst/clk_in1
pattern 还可以包括通配符,例如:
> get_pins foo_reg_reg/* foo_reg_reg/Q foo_reg_reg/C foo_reg_reg/CE foo_reg_reg/D foo_reg_reg/R > get_pins pll_i/* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2 > get_pins pll_i/inst/* pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2 > get_pins pll_i/*/* pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2 > get_pins pll_i/*/clk* pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2
通配符的行为
通配符常见的有两种:
- 星号(“*”),用于替代任意数量的字符(characters)。
- 问号(“?”),替代一个字符(character)。
不过,这两款通配符都不适用于 hierarchy separator。换句话说,“*”和“?”不会替代“/”(或“|”与 Quartus)。这对于通配符总是如此,无论是否使用“-hierarchical”选项(但请注意,如果使用“-filter”或“-regexp”,则另当别论)。
因此,对象在 hierarchy 中的确切位置必须明确写入:
> get_pins */clk_* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2 > get_pins */*/clk_* pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2
请注意,不同的工具可能会为 hierarchy separator使用不同的字符。正如刚才提到的, Quartus 为此使用了 pipe 字符(“|”),而不是“/”。
“-hierarchical”选项允许在设计的 hierarchy中的任何位置查找逻辑单元。这样就无需指定 hierarchy中的确切位置,还允许使用单个命令在整个 FPGA 设计中查找逻辑单元。
因此,让我们用“-hierarchical”重复相同的表达式:
> get_pins -hierarchical */clk_* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2 pll_i/inst/clk_in1 pll_i/inst/clk_out1 pll_i/inst/clk_out2 > get_pins -hierarchical */*/clk_* WARNING: [Vivado 12-508] No pins matched '*/*/clk_*'.
“-hierarchical”是指 search pattern 应用于设计的 hierarchy的所有位置。在上面的例子中,“*/clk_*”首先在 top-level hierarchy上都被应用,因此例如找到“pll_i/clk_in1”。然后将相同的 pattern 应用于“pll_i/”内部,因此找到了“pll_i/inst/clk_in1”。
但是为什么应用了“-hierarchical”却找不到“*/*/clk_*”呢?同样的 pattern 在没有这个选项的情况下产生了一些搜索结果。使用“-hierarchical”时不应该总是有更多的搜索结果吗?
使用 -hierarchical 限制 search pattern
奇怪的是,“-hierarchical”选项不仅改变了 search pattern 的应用位置,而且还限制了允许使用的 patterns 。不幸的是,当使用非法的 pattern 时,这些工具不会以错误响应。相反,响应是什么也找不到。
三个 Tcl 命令(get_cells、 get_pins 和 get_nets)各自都有自己的规则来限制 search pattern。要了解确切的限制,请参阅 FPGA 工具的文档。标准解释(详见 Synopsys的文档)概述如下。
请注意,通常使用缩写“-hier”代替“-hierarchical”。意思完全一样。
get_cells -hierarchical
当 get_cells 与 -hierarchical一起使用时, pattern 仅与对象的名称匹配。如果 pattern中有 hierarchy separator ,则结果始终为空。例如:
> get_cells -hierarchical *_buf pll_i/inst/clkf_buf pll_i/inst/clkout1_buf pll_i/inst/clkout2_buf > get_cells -hierarchical inst/*_buf WARNING: [Vivado 12-180] No cells matched 'inst/*_buf'.
请注意,如果 pattern中有“/”,则会出现错误,因为像这样的 pattern 根本找不到任何内容。但是,工具不会响应错误,而命令则不会产生任何结果。
因为在 pattern中不允许出现 hierarchy separator ,所以 get_cells 仅限于以下几种可能:
- 在 hierarchy 的特定位置搜索 cells (当不使用 -hierarchical 时)。
- 通过使用 -hierarchical在整个 FPGA 设计中搜索 cells 。
- 如果支持,请改用 -filter 或 -regexp 。这些选项不限于此。
此示例显示如何使用特定名称格式为所有 cells 声明 false 路径:
set_false_path -to [get_cells -hierarchical *metaguard*]
对于这样的时序约束,对于所有用作 metastability guards的寄存器(registers),使用包含单词“metaguard”的名称就足够了。但是,这个时序约束的风险在于表达式(expression)可能会无意中与 FPGA 设计中某个不相关的逻辑单元匹配。因此,最好选择比“metaguard”更不常见的名称。
get_nets -hierarchical
get_nets 遵循与 get_cells相同的规则: 如果没有 -hierarchical, get_nets 会在 top-level hierarchy 处找到与 pattern匹配的所有网络(nets)。对于 -hierarchical, pattern 仅与对象的名称相匹配。如果 pattern中有 hierarchy separator ,则结果始终为空。
> get_nets pll_i/clk_i* pll_i/clk_in1 > get_nets clk_i* WARNING: [Vivado 12-507] No nets matched 'clk_i*'. > get_nets -hierarchical clk_i* pll_i/clk_in1 pll_i/inst/clk_in1 > get_nets -hierarchical pll_i/clk_i* WARNING: [Vivado 12-507] No nets matched 'pll_i/clk_i*'.
get_pins -hierarchical
当 get_pins 与 -hierarchical一起使用时, pattern 与引脚的全名相匹配,例如 baz_reg/Q、 clkout1_buf/I 等。“/”被视为名称的一部分,而不是 hierarchy separator。换句话说, cell 的名称和引脚的标识符之间的字符可以替换为通配符。这仅适用于最后一 hierarchy separator ,并且仅在使用 -hierarchical 时适用。
所以,例如:
> get_pins -hierarchical clkout1_buf/* pll_i/inst/clkout1_buf/O pll_i/inst/clkout1_buf/CE pll_i/inst/clkout1_buf/I > get_pins -hierarchical clkout1_bu* pll_i/inst/clkout1_buf/O pll_i/inst/clkout1_buf/CE pll_i/inst/clkout1_buf/I > get_pins -hierarchical clkout1_buf WARNING: [Vivado 12-508] No pins matched 'clkout1_buf'.
请注意, clkout1_bu* 与 clkout1_buf/O (以及其他)匹配。 “*”可以用“/O”代替,只是因为 -hierarchical。
和 get_cells一样,如果 pattern里面有 hierarchy separator ,结果总是空的。这与上面的例子并不矛盾: 如前所述,最后一个“/”被视为引脚名称的一部分。
> get_pins pll_i/inst/clkout1*/I pll_i/inst/clkout1_buf/I > get_pins -hierarchical pll_i/inst/clkout1*/I WARNING: [Vivado 12-508] No pins matched 'pll_i/inst/clkout1*/I'. > get_pins -hierarchical pll_i/inst/*/* WARNING: [Vivado 12-508] No pins matched 'pll_i/inst/*/*'. > get_pins -hierarchical pll_i/*/*/* WARNING: [Vivado 12-508] No pins matched 'pll_i/*/*/*'. > get_pins -hierarchical pll_i/*/* WARNING: [Vivado 12-508] No pins matched 'pll_i/*/*'. > get_pins -hierarchical pll_i/* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2 > get_pins pll_i/* pll_i/clk_in1 pll_i/clk_out1 pll_i/clk_out2
请注意,当不使用 -hierarchical 时,通配符永远不会与 hierarchy separator匹配,即使不是最后一个:
> get_pins pll_i/inst/clkout1_buf/I pll_i/inst/clkout1_buf/I > get_pins pll_i/inst/clkout1_buf/* pll_i/inst/clkout1_buf/O pll_i/inst/clkout1_buf/CE pll_i/inst/clkout1_buf/I > get_pins pll_i/inst/clkout1_bu* WARNING: [Vivado 12-508] No pins matched 'pll_i/inst/clkout1_bu*'. > get_pins pll_i/inst/clkout1_bu*/* pll_i/inst/clkout1_buf/O pll_i/inst/clkout1_buf/CE pll_i/inst/clkout1_buf/I
从这些示例中可以明显看出 get_pins 有多么令人困惑。和以前一样,如果支持,请改用 -filter 或 -regexp 。
概括
尽管通配符可用作查找逻辑单元的方法,但搜索结果并不总是自然预期的结果。同样, -hierarchical 选项在某些情况下可能会有帮助,但这种可能性伴随着对 search pattern 的限制以及更令人困惑的行为。
因此建议使用其他方法选择逻辑单元: 如果 FPGA 工具支持 -filter、 -regexp 或 -of_objects ,则这些选项之一可能是更好的解决方案。仅当这些其他选项都不可用或在特定情况下都无用时,使用简单的通配符才有意义。在这种情况下,必须格外警惕 search pattern的含义。