このページは、別のページの補足です。先にそのページをお読みください。どちらのページもタイミングに関する連載ページの一部であり、タイミング計算の背後にある理論、いくつかのタイミング制約(timing constraints)の書き方、そしてタイミングクロージャ(timing closure)の原則を解説しています。
やむを得ない場合以外は単純な検索パターンを使わない
このページでは、SDC 形式でタイミング制約を書くためのワイルドカードの使い方を説明します。ワイルドカードは複数の Tcl コマンドで使えますが、ここでは通常「-hierarchical」オプションをサポートするコマンド、つまり get_cells、get_pins、get_nets に焦点を当てます。これらの Tcl コマンドは別のページで説明しています。ただし、FPGA ツールによっては、これら 3 つのコマンドすべてで「-hierarchical」をサポートしているわけではないことに注意してください。
残念ながら、これらのコマンドの検索機能はかなり限定的で、混乱を招く可能性があります。ワイルドカードがどのように機能するかを正確に理解していないと、検索結果が予想外になることがあります。特に「-hierarchical」を使うと、下に示すように、結果が驚くべきものになることがあります。
このため、使用する FPGA ツールが関連コマンドで「-filter」オプションをサポートしている場合は、常にそちらを使う方が良いです。サポートされていない場合には、単純なワイルドカードを使うしかありません。
このページの例は、すべてもう一方の関連ページと同じ Verilog コードに基づいています。
単純な検索パターン
論理エレメントや他のオブジェクトを検索するコマンドは、検索パターンありでもなしでも使えます。検索パターンなしで使うと、関連するすべてのオブジェクトが見つかります。たとえば、トップレベルの階層にあるすべてのピンを探すには、次のようにします。
get_pins
FPGA 設計全体にあるすべてのピンを探すコマンドは、次のとおりです。
get_pins -hierarchical
検索パターンを使うと、結果はそのパターンに限定されます。たとえば、名前と階層内の位置が既知の特定の 1 本のピンを探すには、次のようにします。
> 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
パターンにはワイルドカードを含めることもできます。たとえば、次のとおりです。
> 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
ワイルドカードの動作
よく使われるワイルドカードは 2 つあります。
- アスタリスク("*")は、任意の数の文字に置き換わります。
- クエスチョンマーク("?")は、1 文字に置き換わります。
ただし、これらのワイルドカードは階層の区切り文字には決してマッチしません。言い換えれば、"*" と "?" は "/"(Quartus では "|")を置き換えません。これは、"-hierarchical" オプションを使うかどうかに関係なく、ワイルドカードでは常に当てはまります(ただし、"-filter" や "-regexp" を使う場合は話が別です)。
その結果、オブジェクトの階層内での正確な位置を明示的に書かなければなりません。
> 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
ツールによって、階層区切り文字として異なる文字を使う場合があることに注意してください。先ほど述べたように、Quartus はこの目的に "/" ではなくパイプ文字("|")を使います。
「-hierarchical」オプションを使うと、設計階層のどこにある論理エレメントでも見つけられます。これにより、階層内の正確な位置を指定する必要がなくなり、さらに 1 つのコマンドで 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」は、検索パターンが設計階層内のすべての位置に適用されることを意味します。上の例では、"*/clk_*" がまずトップレベルの階層に適用され、たとえば "pll_i/clk_in1" が見つかりました。同じパターンが次に "pll_i/" の内部にも適用されたため、"pll_i/inst/clk_in1" も見つかったのです。
しかし、"-hierarchical" を適用したときに "*/*/clk_*" で何も見つからなかったのはなぜでしょうか。同じパターンは、このオプションなしではいくつかの検索結果を返していました。"-hierarchical" を使えば、常に検索結果が多くなるはずではないのでしょうか?
「-hierarchical」を使うと検索パターンが制限される
奇妙なことに、"-hierarchical" オプションは、検索パターンが適用される場所を変えるだけでなく、使用できるパターンも制限します。残念ながら、不正なパターンを使ってもツールはエラーを返しません。その代わり、何も見つからないという応答が返ってきます。
get_cells、get_pins、get_nets の 3 つの Tcl コマンドにはそれぞれ、検索パターンを制限する独自の規則があります。正確な制限事項を調べるには、お使いの FPGA ツールのドキュメントを参照してください。標準的な解釈(Synopsys のドキュメントに詳しく説明されています)は、以下のとおりです。
「-hierarchical」の代わりに、省略形の「-hier」が使われることもよくあります。意味はまったく同じです。
get_cells -hierarchical
get_cells を -hierarchical と一緒に使うと、パターンはオブジェクトの名前だけにマッチします。パターンに階層区切り文字が含まれている場合、結果は常に空になります。次に例を示します。
> 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'.
パターンに "/" が含まれていると、そのようなパターンでは何も見つからないため、エラーになります。ただし、ツールはエラーを返さず、コマンドは結果を何も返しません。
パターン内で階層区切り文字が許可されていないため、get_cells は次の可能性に限定されます。
- 階層内の特定の位置にあるセルを検索する(-hierarchical を使わない場合)。
- -hierarchical を使って、FPGA 設計全体のセルを検索する。
- サポートされている場合は、代わりに -filter または -regexp を使いましょう。これらのオプションには、このような制限はありません。
次の例は、特定の名前形式を持つすべてのセルに対してフォールスパス(false path)を宣言する方法を示しています。
set_false_path -to [get_cells -hierarchical *metaguard*]
このようなタイミング制約を使えば、メタスタビリティガード(metastability guard)として使うすべてのレジスタに "metaguard" という語を含む名前を付けるだけで十分です。ただし、このタイミング制約のリスクは、その式が FPGA 設計内のどこかにある無関係な論理エレメントに意図せずマッチすることです。したがって、"metaguard" よりも一般的でない名前を選ぶ方が良いでしょう。
get_nets -hierarchical
get_nets は get_cells と同じ規則に従います。-hierarchical なしでは、パターンにマッチするトップレベル階層のすべてのネットが見つかります。-hierarchical を使うと、パターンはオブジェクトの名前だけにマッチします。パターンに階層区切り文字が含まれている場合、結果は常に空になります。
> 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 と一緒に使うと、パターンはピンの完全な名前、たとえば baz_reg/Q、clkout1_buf/I などにマッチします。"/" は名前の一部と見なされ、階層区切り文字ではありません。言い換えれば、セル名とピン識別子の間にある文字は、ワイルドカードで置き換えることができます。これは、最後の階層区切り文字に関してのみ、そして -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 と同様、パターンに階層区切り文字が含まれていると、結果は常に空になります。これは上の例と矛盾しません。前述のとおり、最後の "/" はピン名の一部と見なされるからです。
> 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 を使わない場合、ワイルドカードは階層区切り文字にはマッチしないことにも注意してください。最後の区切り文字でさえもマッチしません。
> 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 オプションは一部のシナリオで役立ちますが、その機能には検索パターンの制限と、さらに紛らわしい動作が伴います。
そのため、論理エレメントを選択するときは他の方法を使うことをお勧めします。FPGA ツールが -filter、-regexp、-of_objects をサポートしているなら、そのいずれかがおそらくより良い解決策です。単純なワイルドカードを使うのが合理的なのは、これらの選択肢がどれも使えない場合か、特定のシナリオでどれも有用でない場合だけです。そのような状況では、検索パターンの意味について特に注意深くあることが重要です。