01signal.com

タイミングクロージャへの戦略

このページは、タイミングに関する連載ページの一部です。これまでのページでは、タイミング計算の背後にある理論を説明し、クロック周期制約について論じ、タイミングクロージャ(timing closure)を紹介しました。しかし、正しく設計しようと努力したのに、それでもタイミング問題が発生する場合はどうすればよいのでしょうか。このページでは、その問いに答えようとしています。

はじめに

前のページで、タイミングクロージャの問題を解決する単一の方法など存在しないと述べました。時にはクリティカルパス(critical path)に注目するのが正しく、時にはそうでないこともあります。ツールの設定を少し変えるだけで簡単に解決できることもあれば、それよりもはるかに難しいこともあります。問題の根本原因にたどり着くためには、持てる経験と知恵をすべて使うことに代わるものはありません。タイミングクロージャをチェックリストで要約する方法はないのです。

とはいえ、可能な戦略のリストを持っていると役立つことはよくあります。そこでこのページでは、タイミング問題に直面したときに検討する価値のあるトピックをいくつか集めました。解決すべき具体的なタイミング問題があってこのページを読んでいるなら、これらのアイデアのどれかが解決への手がかりになるかもしれません。ただし、ここに解決策がそのまま書かれているとは期待しないでください。

また、この連載はここで終わるわけではないことにも注意してください。動機付けのために、他の多くのトピックより先にタイミングクロージャを扱うことにしたのです。ただし、後のページで説明する情報も関連があります。

同じ理由で、I/O タイミング制約の説明は後回しにします。ここでは、FPGA 内部で始まり内部で終わるパス(path)に焦点を当てています。

それでは、タイミングクロージャに関連して検討すべきいくつかのアイデアを紹介します。

アイデア #1:ロジック設計を修正する

これは常に最も魅力のない解決策です。特に、その設計がすでに正しく動作することがわかっている場合はなおさらです。動作しているものを変えたくはないでしょう。しかし、問題の根本的な原因が、要求される性能に対して Verilog コードが十分にうまく書かれていないことである場合も少なくありません。ロジック設計を変更すれば、継続的な困難に直面する代わりに、問題を完全に解決できます。

高速なロジックを書くための提案は、前のページにいくつかあります。そして、これをもう一度繰り返す価値があります。開発プロセスの間、常にタイミングを意識しましょう。タイミング問題を後から修正するのは、最初から Verilog コードを適切に書くことよりはるかに困難です。

アイデア #2:ファンアウトを減らす

ネットのファンアウト(fan-out)が大きいと、伝搬遅延(propagation delay)が大きくなります。主な理由は 2 つあります。

設計で同期リセット(synchronous reset)を使用している場合、その信号のファンアウトは大きくなりがちです。このトピックは別のページで説明しています。

しかし、多くの論理エレメントに届くあらゆる信号は、ファンアウトが大きいことによってタイミング問題を引き起こす可能性があります。この大きなファンアウトが明らかな場合もありますが(たとえばクロックイネーブル(clock enable)信号)、予測がそれほど簡単でない場合もあります。FPGA ツールには、ファンアウトが最も大きいネットの一覧を表示する機能が通常あります。

ファンアウトを低く抑えるには、2 つの方法があります。

明らかに、どちらの方法も同じ結果に達します。ファンアウトの大きいレジスタが複数のレジスタに複製されるのです。では、最初の方法でツールが自動的に実行できるのなら、なぜ 2 番目の方法のように手動で行うのでしょうか。

2 番目の方法はより労力を要しますが、大きな利点が 1 つあります。レジスタを賢明な方法で複製できるのです。目標は単にファンアウトを減らすことだけではないことに注意してください。各レジスタの出力が、論理ファブリック上の狭い領域に配置された論理エレメントに分配されることも重要です。そうでなければ、物理的な距離によって配線遅延が大きくなってしまいます。したがって、ファンアウトを意識して Verilog コードを書けば、論理エレメント間の接続を短く保つことができます。これは、同期リセット信号について別のページで実証しています。

対照的に、FPGA ツールがレジスタの複製を担当する場合、結果はそれほど効率的ではないかもしれません。配線遅延の改善は、複製された各レジスタの使い方を決めるアルゴリズム次第です。結果の品質は、使用する FPGA ツールによって異なります。

なお、デフォルトでは、合成ツールがまったく同じ動作をする 2 つのレジスタを検出すると、それらのレジスタは自動的に 1 つに統合されることに注意してください。したがって、Verilog コードでレジスタを複製したとしても、合成ツールはすべての複製を 1 つのレジスタに置き換えてしまいます。これは、それらの等価なレジスタが異なるモジュールで定義されている場合でも、しばしば起こります。この統合を避けるには、この機能を明示的に無効にする必要があります。これを行う一般的な方法は、合成属性(たとえば "dont_touch"、"dont_merge"、"keep")を使うことです。

アイデア #3:フロアプランニングを確認する

デフォルトでは、論理ファブリック上への論理エレメントの配置は、FPGA ツール(より具体的には配置ツール)によって自動的に決定されます。しかし、特定の論理エレメントを FPGA 上の特定の領域に配置するよう要求することは可能です。また、特定の論理エレメントを特定の位置に配置するよう要求することもできます。この種の要求はフロアプランニングと呼ばれます。これらの要求は、多くの場合タイミング制約と似た構文を持つ Tcl コマンドである配置制約によって行われます。

ほとんどの場合、配置制約はタイミング制約の達成をより困難にします。最初の理由は明らかです。配置ツールの選択肢が制限されると、結果は制限がない場合よりも悪くしかなり得ません。しかし、もっと具体的な理由もあります。

ほとんどの設計では、フロアプランニングを避け、配置ツールに論理エレメントの配置を最適化する自由を与えるのが最善です。しかし、配置制約が一般的に使われるケースもあります。たとえば次のような場合です。

タイミングクロージャの観点では、問題の潜在的な原因として配置制約を認識することが重要です。特に、配線遅延が予想より大きい場合、根本原因は配置ツールが論理エレメントの位置を最適化できないことにあるかもしれません。フロアプランニングは、配置が制限された論理エレメントとは無関係なパスにも悪影響を及ぼし得ることを忘れないでください。

アイデア #4:タイミング制約を確認する

タイミング制約(timing constraints)は、FPGA の信頼性の高い動作に不可欠です。したがって、プロジェクトのインプリメンテーションの前に検証されるべきです。しかし、タイミング制約が結局は間違っていることもあります。その誤りはタイミングクロージャの過程で明らかになることがあります。本来これは起こるべきではありませんが、起こった場合には、もちろん問題を修正する方が良いです。

タイミング制約のチェックについては専用ページがあります。ここでは、タイミングクロージャの問題につながり得る 2 つの一般的な誤りだけを説明します。

まず、無関係クロックについてです。クロックドメイン横断(clock domain crossing)の話題はすでに前の方で説明しました。どのクロックが関連クロック(related clocks)であり、どれがそうでないかをタイミング制約が反映することが重要な理由はいくつかあります。最も重要な理由はロジックの正常な動作を保証することですが、タイミングクロージャにも影響します。ある 2 つのクロックがツールによって不必要に関連クロックとして扱われると、その 2 つのクロック間のパスに不要なタイミング要件が課されます。その結果、ツールはそれらのパスに労力を浪費し、本当にその労力を必要とするパスを犠牲にします。

この問題を修正するタイミング制約については、この連載の後半で説明します。

非同期リセットについてです。ほとんどの場合、非同期リセットで終わるパスにタイミング制約を課す必要があります。しかし、それが不要な場合もあります。たとえば、リセットが非アクティブに変化するときにクロックが動作しないことが保証されている場合です。別の可能性としては、非同期リセットを受け取るフリップフロップが、クロックドメイン横断の場合と同様に、タイミング違反に対する保護メカニズムを持っている場合です。これらの状況では、タイミング要件を満たそうとするツールの努力は無意味です。

この種の問題がタイミングクロージャを困難にしていることに気づくのは難しい場合があります。クリティカルパスが、不必要に関連クロックとして扱われている 2 つのクロックとは無関係なこともあります。非同期リセットがツールの労力をそらしている場合は、さらに気づきにくいです。そのような状況では、タイミングを改善するためにクリティカルパスに集中しようとしても、無駄になることがあります。

もちろん、タイミング制約は他のさまざまな方法で間違っている可能性があります。ここで説明した状況は 1 つの可能性にすぎません。したがって、タイミングの問題は、タイミング制約全般を見直す良い機会にもなり得ます。

アイデア #5:もう一度やってみる

配置配線(place and route)のプロセスは、論理エレメントを論理ファブリック上にかなり恣意的にばらまくことから始まるのを思い出してください。その後、ツールは繰り返しの試行を通じてタイミングを改善しようとします。したがって、このプロセスの成功はある程度の運に依存しています。また、配置配線アルゴリズムの挙動が少し異なるだけで、論理的な説明がなくても良い結果が得られる可能性があります。

つまり、タイミング制約が未達で、負のスラック(slack)が比較的小さい場合(合計遅延の約 10〜20%)、もう一度やり直すだけで十分かもしれません。しかし、単にインプリメンテーションを再実行しても効果はないでしょう。ほとんどの FPGA ソフトウェアは、同じ入力を与えて実行すると、その結果を正確に再現するように設計されています。したがって、再実行する前に何かを変更する必要があります。その変更はクリティカルパスに関連している必要はありません。重要なのは、前回のインプリメンテーションの正確な繰り返しを避けることだけです。

たとえば、Vivado では各ランに「strategy」という属性があります。その名前が示すとおり、この属性はインプリメンテーション中にツールが適用する戦略を制御します。この属性を変更すれば、次のインプリメンテーションが前回と同一にはならないことが保証されます。また、特定の論理設計に関連して、別の戦略の方が理にかなっている可能性もあります。

すべての FPGA ツールは、インプリメンテーションプロセスのパラメータを変更する同様の方法を提供しています。設計目標を達成するためにより高い努力レベルを要求できることがよくあります。より高い努力が本当に必要なこともありますが、多くの場合、より高い努力レベルを要求すると、ツールが別のことをするから効果があるのです。

繰り返しを避けるもう 1 つの方法は、Verilog コードを変更することです。繰り返しますが、その変更はクリティカルパスに関連している必要はありません。前回とは十分に異なるインプリメンテーションを得るには、レジスタの名前を変えるだけで十分なこともあります。

このアイデアは極端にまで推し進められます。複数のコンピューターでインプリメンテーションを並行して実行し、それぞれのインプリメンテーションにわずかに異なるパラメータを与えることが可能です。これは、FPGA の価格が重要な場合に意味を持つことがあります。このシナリオでは、より安価な FPGA でタイミング制約を達成するために、コンピューターに懸命に働かせる価値があるのです。

要約すると、この方法は主に運に依存します。期待はそれに応じて持つべきです。再試行が役立つのは、ツールがタイミング制約を達成できないことがたまにある場合だけです。しかし、可能であれば、他の方法でタイミングを改善する方が常に良いです。

アイデア #6:FPGA は一杯か?

FPGA の使用率が約 70% に達した頃からタイミング制約の問題が始まるのは、かなりよくあることです。これには主に 3 つの理由があります。

上記の 3 つの理由のうち、何らかの解決策があるのは 3 番目だけです。たとえば、どのロジックが FPGA のブロック RAM やその他の同様のリソースを使うかを手動で決めると効果があるかもしれません。これ以外に、FPGA が一杯になった場合の唯一の解決策は、より大きな FPGA を選ぶことです。しかし、それが常に選択肢になるとは限りません。したがって、ロジックが追加されるにつれてタイミングクロージャが難しくなることを予測しておくことが重要です。

アイデア #7:別の FPGA が必要かもしれない?

時には、その FPGA では役割を果たせないと認めるしかないこともあります。同じ FPGA により高速なスピードグレードが存在するなら、より高速な FPGA にアップグレードするという判断が解決策になることがあります。この判断はもちろん購入コストを増やしますが、もう 1 つあまり予想されない結果をもたらすこともあります。より高速なスピードグレードの FPGA は品薄になる可能性があるのです。たとえ特定の時点でそれらの高速 FPGA が豊富にあっても、需要が供給を上回るとき、市場から最初に消えるのは通常、高速な FPGA です。

これはごく自然なことです。高速な FPGA はテストをよりよく通過したものであり、常に低速な FPGA の代わりに使用できます。メーカーが高速な FPGA を生産できないこともあれば、扱えるものをすべて買ってしまう大口顧客がいることもあります。

したがって、長期間にわたって生産される予定の製品に取り組んでいるなら、設計が動作する最も低いスピードグレードを常に選んでください。これは、お金が問題にならない場合でも当てはまります。

まったく異なる種類のアップグレードとして、より新しい FPGA ファミリから選ぶという方法があります。あるいは、別のベンダーの FPGA を選ぶことも考えられます。この変更はより抜本敵ですが、プロジェクトが初期段階にあるなら検討する価値があります。私たちは皆、慣れ親しんだツールや部品に愛着を持ってしまう傾向があります。しかし、すべてが馴染みすぎていると感じるときは、代替案を探し回る良い機会です。

とはいえ、経験豊富な FPGA エンジニアは、最新の真新しい FPGA とそのツールを選ぶことが危険な賭けであることを知っています。しかし、現在選んでいる FPGA よりもはるかに優れた、かなり確立された代替案があることもよくあります。そのような状況では、快適な領域を離れて新しいものを試す方が良いです。

アイデア #8:温度範囲を狭める

この可能性をほぼ最後に置いたのには理由があります。これはすべての解決策の中で最も醜い方法だからです。しかし、他に選択肢がないこともあります。

デフォルトでは、ツールによるタイミング制約の適用は、データシートに定義された全温度範囲で FPGA が確実に動作することを保証します。一部の FPGA ツールでは、プロジェクトに別の温度範囲を選択できます(たとえば Quartus には、この目的のための "MAX_CORE_JUNCTION_TEMP" という属性があります)。これを使うと、全温度範囲をサポートする必要がないことをツールに知らせることができます。

一般に、FPGA 内の論理エレメントの遅延は温度が上昇すると増加します。最大温度を下げれば、タイミング計算で使用される遅延の値も小さくなります。これにより、ツールが tsetup 要件を達成しやすくなります。ツールにタイミング制約を達成させることができる唯一の方法である場合もあります。

この方法を使用するリスクを理解することが重要です。特に、ここで話しているのはジャンクション温度であることに注意してください。つまり、FPGA のシリコン上の温度です。周囲温度ではありません。

したがって、最大温度が 85°C だからといって、FPGA がその温度のオーブンの中で動作するという意味ではありません。この温度は室温(25°C)でも到達し得ます。特に、FPGA にヒートシンクがない場合はそうです。ジャンクション温度と周囲温度の間には常に差があります。この差の大きさは、FPGA の消費電力と冷却方法に依存します。

商用製品に取り組んでいるなら、FPGA の周囲温度が室温よりかなり高くなり得ることを認識してください。特に、FPGA が空気の流れの悪い筐体の中にある場合、筐体内部の温度は外部の温度よりはるかに上昇することがあります。さらに悪いことに、ほとんどの電子製品は約 0°C から 40°C の範囲で動作することが期待されています(おおよその数値で、製品によって異なります)。最終製品が最高温度でテストされ、その製品の筐体内に FPGA があるとき、ジャンクション温度はいくつになるでしょうか。それが問うべき質問です。タイミング計算は、その温度(またはそれ以上)に基づいていなければなりません。

つまり、タイミング制約を達成するために最大温度を下げ、実験室ではすべてがうまく動作したとしても、それは何の意味もありません。タイミング制約に関しては、FPGA 設計が実験室で動作することは常に何の意味もないことを思い出してください。しかし、最大温度を下げることは、この点でさらに悪いことです。温度範囲を無思慮に狭めることは、実際のトラブルを招く恐れがあります。生産前の最終テストは最高温度で行われますが、そこで失敗するかもしれません。そして、温度範囲を修正したら、タイミング制約を達成するのは不可能になるでしょう。この問題を解決する唯一の方法は、FPGA 設計を最初から書き直すことです。

したがって、タイミングクロージャのために温度範囲を変更する前に、それが安全であることを確認してください。すべての可能な動作条件におけるジャンクション温度の範囲を厳密に評価してください。

インプリメンテーションのパラメータを変更しても、デフォルトを超えて温度範囲を拡大することは不可能であることに注意してください。ツールのデフォルトの温度範囲は、常にデータシートに記載されているものと同じです。したがって、このデフォルトの温度範囲を超えて FPGA の信頼性の高い動作を保証することはできません。

アイデア #9:整列していない関連クロック

これはかなり難解な状況であり、少し理解しにくいものでもあります。だからこのトピックを最後にしました。

整列していない 2 つの関連クロックの間にクロックドメイン横断があるとします。つまり、2 つのクロックは同じ基準クロックから派生していますが、これらのクロック間のクロックスキュー(clock skew)を制御する仕組みがありません。

その結果、ツールがこれらの 2 つのクロック間のパスのタイミング要件を満たすことが難しくなります。困難には 2 つの種類があります(tsetup と thold は以前に説明しました)。

ツールがこれらの困難を克服するために通常より懸命に働く必要があるとき、それは他のパスの最適化を犠牲にして行われる可能性があることに注意することが重要です。

しかし、整列していない関連クロックはエラーではなく、時には避けられないものです。この状況は、ツールがより懸命に働く必要があることを意味するだけです。タイミング制約が達成されていれば、設計に問題はありません。しかし、これは、妥当な努力で可能な限り避けるべきです。

上記の「アイデア #4」で述べた誤りは、両方ともツールにとって不必要に困難にさせるものであり、両方ともクロックドメイン横断に関連していますが、別のものであることに注意してください。

整列していない関連クロックの状況を解決する最善の方法は、これらのクロックを整列させることです。これは通常、PLL を追加するか、既存の PLL にクロック出力を追加することによって行われます。目標は、問題の両方のクロックが同じ PLL の出力になるようにすることです。

もう 1 つの可能な解決策は、それらのクロックを無関係クロックとして扱うことです。これには、ロジック設計自体の変更とタイミング制約の変更の両方が必要です。それほど難しくないなら、努力する価値があるかもしれません。このトピックの詳細は後で説明します。

それでは、整列していない関連クロック間のクロックドメイン横断の例を見てみましょう。

   wire       pll_clk;

   reg [24:0] result;
   reg [11:0] x, y, x1, y1;

   clk_wiz_0 pll_i
   (.clk_in1(clk),
    .clk_out1(pll_clk));

   always @(posedge clk)
     begin
	x1 <= x;
	y1 <= y;
     end

   always @(posedge pll_clk)
     result <= x1 * y1;

ここに PLL(clk_wiz_0)があることに注意してください。この PLL は @clk を基準クロックとして使用し、その周波数は 250 MHz です。前のページの上部にある例で示したものと同じ PLL です。@pll_clk の周波数は 125 MHz です。

この例の重要な部分は、2 つの関連クロック(@clk と @pll_clk)の間のクロックドメイン横断です。PLL によって生成されるのは @pll_clk だけなので、これらの 2 つのクロックは整列していません。したがって、(@x1 と @y1 から @result への)パスにはクロックスキューが存在します。このクロックスキューにもかかわらず、これらのクロックは依然として関連クロックであり、ツールはタイミング要件を満たそうとします。

@clk を使う唯一の理由が 250 MHz のクロックの必要性であるなら、正しい解決策は PLL でもう 1 つクロックを生成することです。基準クロックと同じ周波数のクロックを生成することは、リソースの無駄ではありません。それどころか、そうすることでツールの労力を大幅に節約できます。例のように @clk を直接使う正当な理由は 1 つだけです。それは、PLL が使用可能なクロックを生成する前に、@clk を使うロジックが動作しなければならない場合です。

Vivado によって生成されたタイミングレポートは次のとおりです。この特定のケースでは、tsetup 要件にのみ問題がありました。

Slack (VIOLATED) :        -1.456ns  (required time - arrival time)
  Source:                 x1_reg[7]/C
                            (rising edge-triggered cell FDRE clocked by clk  {rise@0.000ns fall@2.000ns period=4.000ns})
  Destination:            result_reg/DSP_OUTPUT_INST/ALU_OUT[10]
                            (rising edge-triggered cell DSP_OUTPUT clocked by clk_out1_clk_wiz_0  {rise@0.000ns fall@4.000ns period=8.000ns})
  Path Group:             clk_out1_clk_wiz_0
  Path Type:              Setup (Max at Slow Process Corner)
  Requirement:            4.000ns  (clk_out1_clk_wiz_0 rise@8.000ns - clk rise@4.000ns)
  Data Path Delay:        3.012ns  (logic 2.677ns (88.878%)  route 0.335ns (11.122%))
  Logic Levels:           5  (DSP_A_B_DATA=1 DSP_ALU=1 DSP_M_DATA=1 DSP_MULTIPLIER=1 DSP_PREADD_DATA=1)
  Clock Path Skew:        -2.192ns (DCD - SCD + CPR)
    Destination Clock Delay (DCD):    0.998ns = ( 8.998 - 8.000 )
    Source Clock Delay      (SCD):    3.202ns = ( 7.202 - 4.000 )
    Clock Pessimism Removal (CPR):    0.012ns
  Clock Uncertainty:      0.148ns  ((TSJ^2 + DJ^2)^1/2) / 2 + PE
    Total System Jitter     (TSJ):    0.071ns
    Discrete Jitter          (DJ):    0.103ns
    Phase Error              (PE):    0.086ns
  Clock Net Delay (Source):      1.414ns (routing 0.002ns, distribution 1.412ns)
  Clock Net Delay (Destination): 1.184ns (routing 0.002ns, distribution 1.182ns)
  Clock Domain Crossing:  Inter clock paths are considered valid unless explicitly excluded by timing constraints such as set_clock_groups or set_false_path.

    Location             Delay type                Incr(ns)  Path(ns)    Netlist Resource(s)
  -------------------------------------------------------------------    -------------------
                         (clock clk rise edge)        4.000     4.000 r
    AG12                                              0.000     4.000 r  clk (IN)
                         net (fo=0)                   0.000     4.000    clk_IBUF_inst/I
    AG12                 INBUF (Prop_INBUF_HRIO_PAD_O)
                                                      0.738     4.738 r  clk_IBUF_inst/INBUF_INST/O
                         net (fo=1, routed)           0.105     4.843    clk_IBUF_inst/OUT
    AG12                 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O)
                                                      0.049     4.892 r  clk_IBUF_inst/IBUFCTRL_INST/O
                         net (fo=1, routed)           0.795     5.687    clk_IBUF
    BUFGCE_X1Y2          BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                                      0.101     5.788 r  clk_IBUF_BUFG_inst/O
    X2Y0 (CLOCK_ROOT)    net (fo=62, routed)          1.414     7.202    clk_IBUF_BUFGCE
    SLICE_X52Y45         FDRE                                         r  x1_reg[7]/C
  -------------------------------------------------------------------    -------------------
    SLICE_X52Y45         FDRE (Prop_HFF_SLICEM_C_Q)
                                                      0.138     7.340 f  x1_reg[7]/Q
                         net (fo=1, routed)           0.335     7.675    result_reg/A[7]
    DSP48E2_X8Y18        DSP_A_B_DATA (Prop_DSP_A_B_DATA_DSP48E2_A[7]_A2_DATA[7])
                                                      0.396     8.071 r  result_reg/DSP_A_B_DATA_INST/A2_DATA[7]
                         net (fo=1, routed)           0.000     8.071    result_reg/DSP_A_B_DATA.A2_DATA<7>
    DSP48E2_X8Y18        DSP_PREADD_DATA (Prop_DSP_PREADD_DATA_DSP48E2_A2_DATA[7]_A2A1[7])
                                                      0.182     8.253 r  result_reg/DSP_PREADD_DATA_INST/A2A1[7]
                         net (fo=1, routed)           0.000     8.253    result_reg/DSP_PREADD_DATA.A2A1<7>
    DSP48E2_X8Y18        DSP_MULTIPLIER (Prop_DSP_MULTIPLIER_DSP48E2_A2A1[7]_U[10])
                                                      0.994     9.247 f  result_reg/DSP_MULTIPLIER_INST/U[10]
                         net (fo=1, routed)           0.000     9.247    result_reg/DSP_MULTIPLIER.U<10>
    DSP48E2_X8Y18        DSP_M_DATA (Prop_DSP_M_DATA_DSP48E2_U[10]_U_DATA[10])
                                                      0.164     9.411 r  result_reg/DSP_M_DATA_INST/U_DATA[10]
                         net (fo=1, routed)           0.000     9.411    result_reg/DSP_M_DATA.U_DATA<10>
    DSP48E2_X8Y18        DSP_ALU (Prop_DSP_ALU_DSP48E2_U_DATA[10]_ALU_OUT[10])
                                                      0.803    10.214 r  result_reg/DSP_ALU_INST/ALU_OUT[10]
                         net (fo=1, routed)           0.000    10.214    result_reg/DSP_ALU.ALU_OUT<10>
    DSP48E2_X8Y18        DSP_OUTPUT                                   r  result_reg/DSP_OUTPUT_INST/ALU_OUT[10]
  -------------------------------------------------------------------    -------------------

                         (clock clk_out1_clk_wiz_0 rise edge)
                                                      8.000     8.000 r
    BUFGCE_X1Y2          BUFGCE                       0.000     8.000 r  clk_IBUF_BUFG_inst/O
                         net (fo=62, routed)          1.078     9.078    pll_i/inst/clk_in1
    MMCME3_ADV_X1Y0      MMCME3_ADV (Prop_MMCME3_ADV_CLKIN1_CLKOUT0)
                                                     -1.777     7.301 r  pll_i/inst/mmcme3_adv_inst/CLKOUT0
                         net (fo=1, routed)           0.422     7.723    pll_i/inst/clk_out1_clk_wiz_0
    BUFGCE_X1Y0          BUFGCE (Prop_BUFCE_BUFGCE_I_O)
                                                      0.091     7.814 r  pll_i/inst/clkout1_buf/O
    X2Y0 (CLOCK_ROOT)    net (fo=6, routed)           1.184     8.998    result_reg/CLK
    DSP48E2_X8Y18        DSP_OUTPUT                                   r  result_reg/DSP_OUTPUT_INST/CLK
                         clock pessimism              0.012     9.010
                         clock uncertainty           -0.148     8.862
    DSP48E2_X8Y18        DSP_OUTPUT (Setup_DSP_OUTPUT_DSP48E2_CLK_ALU_OUT[10])
                                                     -0.104     8.758    result_reg/DSP_OUTPUT_INST
  -------------------------------------------------------------------
                         required time                          8.758
                         arrival time                         -10.214
  -------------------------------------------------------------------
                         slack                                 -1.456

このレポートは、ツールがタイミング制約を達成できなかったことを示しています。示されているパスは、@clk の立ち上がりエッジ(4 ns)で始まり、@pll_clk の立ち上がりエッジ(8 ns)で終わります。問題は、入力ピンのクロックが最初のフリップフロップのクロック入力ピンに到達するのにかかる時間です。3.2 ns です。したがって、このクロックエッジの到着時刻は 7.2 ns になります。

しかし、@pll_clk は PLL によって生成されるため、このクロックは @clk の入力ピンに整列しています。したがって、その遅延はわずか 1.0 ns です。@pll_clk の 2 番目のフリップフロップへの到着時刻は、したがって 9.0 ns です。データパスに残された時間は 9.0 − 7.2 = 1.8 ns(クロック不確かさなどによりおおよその値)です。これは、専用の演算ユニットを使ったとしても、算術乗算には十分な時間ではありません。したがって、タイミング要件を満たすことができませんでした。

つまり、この例では、クロックスキューによってクロックが最初のフリップフロップに遅く到着します。その結果、tsetup 要件を満たせなくなっています。

これは @pll_clk の整列を操作することで解決できることに注意してください。たとえば、PLL の基準クロックを、@clk を分配するグローバルクロックバッファの出力にすることができます。また、より良い整列を達成するために PLL の位相シフトを定義することも可能です。ただし、これらは最後の手段としてのみ使うべき解決策です。

まとめ

繰り返しになりますが、これらはタイミングクロージャの問題を解決するのに役立つかもしれないいくつかのアイデアにすぎません。残念ながら、この種の問題の解決には、それ以上のものが要求されることがよくあります。実際、FPGA の分野でタイミングクロージャに何らかの形で関連していないトピックはありません。

前述のとおり、最善の戦略は、最初から注意深く論理設計を書くことです。タイミングクロージャに取り組む最善の方法は、それを避けることです。


ここまでのこの連載ページではタイミングについて説明してきましたが、タイミング制約そのものについてはあまり述べてきませんでした。それはまもなく変わります:次のページから、議論はより技術的になります。

このページは英語から機械翻訳されたものです。不明な点があれば、原文を参照してください。
Copyright © 2021-2026. All rights reserved. (dcc38493)