このページは、 timingに関する一連のページに属しています。前のページでは、いくつかの基本トピックについて説明しました: timing 計算の背後にある理論と clock period timing constraint。いくつかの timing reports も示され、説明されました。ここで、この知識の重要な目的の 1 つである timing 問題の解決について説明します。
序章
FPGA ツールの最大の課題は、 timing constraintsの要件を満たすことです。これはうまくいけば成功しますが、失敗することもあります。そして、それが失敗した場合、なぜ失敗したのかを突き止め、それを修正する義務を負うのは私たち人間です.このタスクには次の名前があります。 これをTiming Closureと呼びます。そして、それは簡単な仕事ではありません。
timing closure はなぜ難しいのですか?問題は、ツールには、 FPGAのリソースを最適な方法で使用しようとする place and route アルゴリズムがあることです。通常、このアルゴリズムは、 logic elements を FPGA に配置することから始めます。次に、反復プロセスが開始されます。 ツールはすべての pathsを調べ、 timing constraintsを満たしていない paths を見つけます。これらの障害を修正するために、これらの pathsに対して修正措置が講じられます。最も顕著なのは、 logic elements を FPGA上の別の位置に移動し、 routing を調整することです。より高度な修正措置については、各 FPGA tool に独自の方法があります。
すべての paths が timing constraintsに達すると、 implementation は終了したとみなされます。ただし、ツールがこの目標に到達できず、結果として試行を断念したために implementation が終了することもあります。この状況では、ツールが努力を止めたときに達成したものが得られます。この結果は必ずしも最適ではありません。 implementation には改善された可能性のある paths があるかもしれませんが、ツールは他の何かを修正するのに忙しかったです。そしてそれが失敗すると、ツールは他の問題を修正しようとせずにあきらめました。ツールが言っていたようです: 「 implementation が故障するのであれば、時間をかけて修正しても意味がありません」.
FPGA designers としての私たちの仕事は、この準最適な結果を見て、 timing constraints の目標が達成されなかった理由を見つけることです。
アルゴリズムは時間の経過とともに改善されます。 timing constraintsを達成できない一般的な理由がある場合、ソフトウェアの次のバージョンには、その状況に対する特定の解決策があります。そのため、ツールが失敗する場合、通常は正当な理由があります。
そこで、ツールが達成したことを見て、次のことを自問します。 ツールが失敗したのはなぜですか?不可能なことを要求しましたか?さらに重要なことに、私たちは不必要なことを要求しましたか?おそらく、ツールの失敗の原因となった障害は、私たちが必要とさえしていないものです。それとも、最適化アルゴリズムがうまく機能しなかったのでしょうか?時にはそれは単に不運の問題です: logic elements の最初の配置が非常に悪く、その後のパフォーマンス改善の試みは失敗する運命にあります。
問題が何であれ、失敗の理由を見つけることは、犯罪現場を調査する探偵に似ています。 事実は目の前にありますが、その理由はしばしば隠されています。これらの事実のほとんどは timing reportsで見つけることができますが、手がかりは簡単にはわかりません。常に尋ねなければならない質問は、 timing reportのどこが悪いのか、異常なのか、異常なのかということです。犯罪者を見つけようとする探偵のように、目標は問題につながる詳細を見つけることです。
しかし、何が異常かを見つけるには、何が正常かを知らなければなりません。 たとえば、特定の fan-outを搭載した net に対して、通常の delay とは何ですか?ある logic functionを実装するために、 logic levels はいくつが正常ですか?この種の質問に対する答えは、 FPGA ごとに異なります。したがって、すべてが順調であっても、 timing reportsを読んで理解することで経験を積む必要があります。 timing report が問題を示している場所を見つけるには、すべてが正常なときに timing report がどのように見えるかを知ることができなければなりません。なぜ前のページで詳細に踏み込んだのか不思議に思われるかもしれませんが、それが理由の 1 つです。
Critical Path
ツールが timing constraintsを達成できない場合、 slackが負の path が少なくとも 1 つあることを意味します。最も負の slack を持つ path は Critical Pathと呼ばれます。この名前は、 timing closureの通常の戦略を反映しています。 timing の問題を解決するには、 Critical Path に注目することがよくあります。しかし、この戦略も時間の無駄になる可能性があることを以下に示します。
timing constraints が達成されると、 Critical Path は最小の slackを備えた path になります。ツールは正の slackで paths を改善しようとしないため、この path はしばしば興味深いものではありません。したがって、最悪の path が正の slackを持っている場合、この path が最悪の path であることが判明したのは偶然の一致である可能性があります。
しかし、 slack が正でほぼゼロ (つまり、 0.2 ns未満) である場合、この path で timing constraintsを達成するのは困難であったことを示している可能性があります。 この種の Critical paths は、これらの paths が将来問題を引き起こす可能性があるという警告と見なすことができます (特に、 FPGA がさらに多くの logicで満たされ、ツールの努力が他の pathsに向けられる場合)。
timing report には通常、 clockごとに限られた数の critical paths が含まれています。ほとんどの FPGA ツールのデフォルトでは、 slack が正の場合 (つまり、 timing constraints が達成された場合) でも、いくつかの critical paths が表示されます。これが推奨設定です。
critical pathの例
Critical Pathの分析例から始めましょう。この例では、 Verilog コードは次のようになります。
reg [24:0] calc, result;
reg [11:0] x, y, z;
always @(posedge clk)
begin
calc <= x * y + z;
result <= calc;
end
この例では、 @clkの周波数は 250 MHzであり、この clockを生成するために PLL は使用されません。また、 @x、 @y 、および @z は、 @clkと同期している registers であるとします。これらの registers に値を割り当てる Verilog コードは、無関係であるため、表示されません。
Vivadoでこのコードを試行した場合、 timing constraints は達成されませんでした。 timing report では、これは Critical Pathでした。
Slack (VIOLATED) : -0.239ns (required time - arrival time) Source: x_reg[1]__0_replica_2/C (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns}) Destination: calc_reg[23]/D (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns}) Path Group: clk Path Type: Setup (Max at Slow Process Corner) Requirement: 4.000ns (clk rise@4.000ns - clk rise@0.000ns) Data Path Delay: 4.180ns (logic 1.642ns (39.282%) route 2.538ns (60.718%)) Logic Levels: 7 (CARRY8=4 LUT3=1 LUT4=1 LUT6=1) Clock Path Skew: -0.087ns (DCD - SCD + CPR) Destination Clock Delay (DCD): 3.176ns = ( 7.176 - 4.000 ) Source Clock Delay (SCD): 3.864ns Clock Pessimism Removal (CPR): 0.601ns Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE Total System Jitter (TSJ): 0.071ns Total Input Jitter (TIJ): 0.000ns Discrete Jitter (DJ): 0.000ns Phase Error (PE): 0.000ns Clock Net Delay (Source): 2.032ns (routing 0.396ns, distribution 1.636ns) Clock Net Delay (Destination): 1.748ns (routing 0.365ns, distribution 1.383ns) Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r AG12 0.000 0.000 r clk (IN) net (fo=0) 0.000 0.000 clk_IBUF_inst/I AG12 INBUF (Prop_INBUF_HRIO_PAD_O) 0.738 0.738 r clk_IBUF_inst/INBUF_INST/O net (fo=1, routed) 0.105 0.843 clk_IBUF_inst/OUT AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O) 0.049 0.892 r clk_IBUF_inst/IBUFCTRL_INST/O net (fo=1, routed) 0.839 1.731 clk_IBUF BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O) 0.101 1.832 r clk_IBUF_BUFG_inst/O X2Y0 (CLOCK_ROOT) net (fo=106, routed) 2.032 3.864 clk_IBUF_BUFG SLICE_X54Y54 FDRE r x_reg[1]__0_replica_2/C ------------------------------------------------------------------- ------------------- SLICE_X54Y54 FDRE (Prop_HFF2_SLICEL_C_Q) 0.137 4.001 r x_reg[1]__0_replica_2/Q net (fo=21, routed) 0.371 4.372 x[1]_repN_2 SLICE_X56Y53 LUT6 (Prop_E6LUT_SLICEL_I1_O) 0.219 4.591 r calc[23]_i_101/O net (fo=2, routed) 0.550 5.141 calc[23]_i_101_n_0 SLICE_X54Y57 CARRY8 (Prop_CARRY8_SLICEL_DI[5]_CO[7]) 0.228 5.369 r calc_reg[23]_i_30/CO[7] net (fo=1, routed) 0.030 5.399 calc_reg[23]_i_30_n_0 SLICE_X54Y58 CARRY8 (Prop_CARRY8_SLICEL_CI_O[1]) 0.163 5.562 r calc_reg[23]_i_22/O[1] net (fo=3, routed) 0.351 5.913 calc_reg[23]_i_22_n_14 SLICE_X56Y57 LUT3 (Prop_C6LUT_SLICEL_I1_O) 0.146 6.059 r calc[23]_i_26/O net (fo=3, routed) 0.240 6.299 calc[23]_i_26_n_0 SLICE_X55Y58 LUT4 (Prop_A6LUT_SLICEM_I0_O) 0.089 6.388 r calc[23]_i_7/O net (fo=1, routed) 0.407 6.795 calc[23]_i_7_n_0 SLICE_X53Y57 CARRY8 (Prop_CARRY8_SLICEM_DI[2]_O[4]) 0.308 7.103 r calc_reg[23]_i_2/O[4] net (fo=1, routed) 0.538 7.641 P[20] SLICE_X54Y56 CARRY8 (Prop_CARRY8_SLICEL_S[4]_O[7]) 0.352 7.993 r calc_reg[23]_i_1/O[7] net (fo=1, routed) 0.051 8.044 P0_out[23] SLICE_X54Y56 FDRE r calc_reg[23]/D ------------------------------------------------------------------- ------------------- (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.515 4.515 r clk_IBUF_inst/INBUF_INST/O net (fo=1, routed) 0.066 4.581 clk_IBUF_inst/OUT AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O) 0.034 4.615 r clk_IBUF_inst/IBUFCTRL_INST/O net (fo=1, routed) 0.722 5.337 clk_IBUF BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O) 0.091 5.428 r clk_IBUF_BUFG_inst/O X2Y0 (CLOCK_ROOT) net (fo=106, routed) 1.748 7.176 clk_IBUF_BUFG SLICE_X54Y56 FDRE r calc_reg[23]/C clock pessimism 0.601 7.777 clock uncertainty -0.035 7.741 SLICE_X54Y56 FDRE (Setup_HFF_SLICEL_C_D) 0.063 7.804 calc_reg[23] ------------------------------------------------------------------- required time 7.804 arrival time -8.044 ------------------------------------------------------------------- slack -0.239
この path の slack は –0.239 nsだったので、 timing constraintsを満たすには少し失敗です。まず調べるのは、この pathの始まりと終わりです。 レポートの headerの「Source」と「Destination」を調べると、 x_reg と calc_regが見つかります。したがって、問題の原因は明らかにこの部分です。
calc <= x * y + z;
これは、 Verilog コードで唯一の意味のある操作であるため、驚くべきことではありません。実際のシナリオでは、 logic のどの部分が問題を引き起こしたのかは明らかではありません。
timing report からも明らかなように、多数の logic levelsが存在します。 7. combinatorial path は長すぎます。言い換えれば、 @clkの 2 つの clock edges の間で行うべきことが多すぎます。
しかし、失敗の実際の理由は何でしょうか? delayのうち 61% は routing によるものかもしれません。経験則として、 routing delay は通常、 delay全体のうち 40% であるという点を思い出してください。したがって、パフォーマンスを向上させるために、 FPGA ツールを使ってみてはいかがでしょうか? ただし、ツールは通常、 pathの timing constraints を達成しようとする試みをあきらめる前に懸命に作業するため、これが成功する解決策となる可能性は低いです。
@x と @calc の間で logic function を変更しようとしても、同様に無駄です。 掛け算は必須なので、もっと単純なものを代用するわけにはいきません。
次のページでは、このような問題を解決するための他の可能なアプローチを紹介します。しかし、この場合、テクニックのリストを調べても役に立ちません。この単純な例は、時には探偵のように考える必要があることを示しています。
あなたの脳に代わるものはありません
timing report を読む際に最初に尋ねる質問は、何が異常なのかということです。この例では、答えは、 combinatorial path が slicesのみで構成されているということです。 実質的にすべての FPGAs には、乗算が要求されたときに使用される算術ユニット (DSPs、 ALUs、名前はさまざま) が指定されています。実際、 multiply and add は、そのような指定された logicの中で最も一般的な機能です。したがって、ほとんどの場合、最も簡単な解決策は、ツールが指定された演算ユニットを使用するようにすることです。このソリューションの timing report は、このページの下部に示されています。
しかし、私たちが問うべき本当の問題は、指定された算術ユニットの代わりに slices が使用された理由です。最も一般的な理由は、 FPGAの使用可能なすべての算術ユニットが、 designの他の部分によって既に使用されていることです。この場合、必要な変更は critical path とはまったく関係がない可能性があります。 designから logic をいくらか取り除いて、いくつかの算術ユニットを解放する必要があるかもしれません。別の可能性として、 designのさまざまなパーツ間でこれらの算術ユニットを異なる方法で割り当てるようにツールに指示することもできます。
この例では、算術単位の代わりに slices を使用しました。 私は意図的に算術ユニットの使用をオフにしました( Vivadoの synthesizer parametersの1つを使用)。 私は max_dsp をゼロに設定しました)。しかし、これによってこの例が不自然になるわけではありません。 FPGA toolsで間違った parameters が使用され、まさにこのような状況になることがあります。実際、 designのどこか他の場所で演算ユニットがより必要になるため、意図的に演算ユニットを使用しないことが正しい場合もあります。
したがって、簡単な解決策は、指定された算術単位を使用することでした。しかし、 slicesを使用しなければならない場合はどうでしょうか?繰り返しますが、解決策は間接的です。問題のある部分は次のとおりだったことを思い出してください。
calc <= x * y + z;
ただし、これは直後に来ることに注意してください。
result <= calc;
@calc がこの行でのみ使用され、他の場所では使用されない場合、計算を 2 つの段階に分けることができます。この手法は、 pipeliningと呼ばれることがよくあります。したがって、 Verilog コードは次のように変更されます。
reg [24:0] calc, result;
reg [11:0] x, y, z, z_d;
always @(posedge clk)
begin
z_d <= z;
calc <= x * y;
result <= calc + z_d;
end
このソリューションでは、 @calc には乗算の結果のみが与えられます。 @z の値は、次のステージでのみ @calc に追加されます。より正確には、プラス操作は @calc と @z_dの間にあります。これは、この操作が clock cycle の 1 つ後に発生するためです。したがって、 @result の値は以前とまったく同じです。
@result は元の Verilog コードの @calc の遅延コピーにすぎないため、この方法で問題を解決するのは簡単でした。実生活では、通常、これほど幸運ではありません。
critical path には @calc と @xのみが含まれていることに注意してください。 @z は、 pathでさえ言及されていませんでした。したがって、この操作の目的は、算術演算の負担を軽減することです。より正確には、 logic levelsの数を減らすことです。
最適化アルゴリズムの実行後、 critical path が最悪の path であることを思い出してください。このアルゴリズムは、問題の理由を尋ねません。むしろ、負の slackを持つ paths を改善しようとします。したがって、問題の解決には @zの操作が必要ですが、 @z に関連する path は critical pathではありませんでした。これは単なる偶然ですが、これはよく起こります。
このソリューションの timing report と critical path もこのページの下部に示されています。 logic levels の数が 7 から 6に削減されたことがわかります。その結果、 data path delay は 0.715 nsだけ削減され、 timing constraintsを満たすのに十分でした。
この例から学べる教訓は、 critical path が必ずしも問題の直接的な原因ではないということです。この path が失敗した理由を尋ねるのは正しいですが、解決策は別の場所にある可能性があります。各 FPGA ツールには、問題の根本原因を見つけるのに役立つ情報を提供する独自のユーティリティがあることに注意してください。これらのユーティリティを調査し、それらのドキュメントを読むことは時間の価値があります。
問題を後で解決するのではなく、早期に回避する
logic design が最初から正しく行われていれば、 timing closure での作業の多くを回避できます。これには、 logic design がソフトウェアではないという事実を継続的に認識する必要があります。 Verilog コードの目的は、 simulation中に正しい結果を生成することではありません。本当に重要なのは、 Verilog コードから synthesizer によって生成された出力です。
優れた logic design は、 logic がその目的をどのように達成するのが最善かを考えることから始まります。これには、 timingに関連する潜在的な障害の特定が含まれます。
経験の浅い FPGA designers は、試行錯誤によって Verilog コードを開発することがよくあります。 simulation は、 logic が期待どおりに動作するかどうかを確認するために使用され、 simulation の出力が正しくなるまで徐々に修正が行われます。その結果、ハードウェアでは使用できない logic になる可能性があります。 timing constraintsを実現するには、 Verilog コードを完全に書き直す必要があります。
Verilog コードが生成する combinatorial paths について事前に考えることが重要です。各 registerを見て、 combinatorial path を最後までたどるという考え方です。 combinatorial path は常に register で始まり、 registerで終わることを思い出してください。
この例を見てみましょう:
reg [15:0] a, b;
wire [16:0] x, y;
reg [33:0] z;
assign x = a + 2;
assign y = b + 3;
always @(posedge clk)
z <= x * y;
@aについて: この register が変化すると、 combinatorial path は最初の段階として @x に到達します。しかし、 @x は registerではありません。 @x は continuous assignmentによって更新されます。したがって、 path は @zに続きます。したがって、 logic はこの combinatorial pathで 2 つの重要な操作を実行します。 算術加算と算術乗算。これは多すぎますか? pipeliningのおかげで、これを 2 つの clock cyclesに分割する必要はありますか?それは、 clock frequency と、どの FPGA が使用されているかによって異なります。
もう 1 つの重要な要素は、 combinatorial paths を短くすることがどれほど難しいかということです。長い combinatorial path が避けられない場合もあります。ただし、 pathの timing を改善するのが簡単な場合は、 designにもっと悪い paths がある場合でもそれを行います。 designに問題のある paths がいくつかある場合、ツールはこれらの pathsに集中して取り組むことで、 timing constraints を達成できる場合が多くあります。他の pathsの timing requirements を満たすのが簡単な場合、これは非常に役立ちます。
したがって、 timing constraintsを実現する design を取得するために、何が許可され、何が許可されないかについてのルールはありません。この分野で正しい決定を下すには、 FPGA design の経験が必要です。特定の FPGA ツールの経験も重要です。常に正しい唯一のルールは次のとおりです。 Verilog コードの単純な変更によって timing を改善できる場合は、それを実行してください。怠け者ではなく、最初からこの変更を行ってください。常に timing を念頭に置いてください。
高速な logic を書く
すでに述べたように、目標は registers間の短い combinatorial paths を達成することです。 registers の次の値を計算する logic functions は単純なはずです。つまり、これらの logic functionsを実装するには少数の logic levels が必要です。
FPGA designers としての私たちの仕事は、 Verilog コードを見て、 logic functions がどれほど複雑になるかを評価することです。これには、 synthesizer が Verilog を logic elements (LUTs およびその他の logic primitives) に変換する方法に関する知識が必要です。この知識は、 timing reportsを分析することによって部分的に得られる経験を通じて得られます。さらに難しいことに、この変換は FPGA ごとに異なります。したがって、高速な logicを実現する Verilog コードを作成するのは簡単なことではありません。
FPGA の初心者である場合は、時間をかけて implementation の結果を見て学習することをお勧めします。 timing report は、 logic design が単純な logic elementsに分割される方法の例を示しています。 FPGA ツールは、低レベルの logic elementsを表示するための他のユーティリティも提供します。
さらに、役立つ簡単なルールがいくつかあります。
- Pipelining: registersを惜しみなく使用してください。可能であれば、 logicのタスクを小さな部分に分割し、各ステップの後に register を挿入します。 FPGAs には多くの flip-flops があるため (多くの場合、各 LUTの横に 1 つの flip-flop があります)、 registers を挿入しても FPGAの使用率は上がりません。 pipelining を避ける唯一の理由は、 design が複雑になりすぎる場合です。
- if-then-else を使用する場合は、多くの "else" 句を連鎖させないようにします。代わりに "case" ステートメントを使用できる場合、通常はその方が適切です。 「else」句では、多くの場合、この句より前のすべてが falseであることを保証する logic function が必要です。したがって、複数の「else」句には複数の logic levelsが必要になる場合があります。
- 不要な resetsは避けてください。特に、 synchronous reset は logic functionに若干の複雑さを追加します。どちらのタイプの resets も、多くの logic elementsに到達しなければならない signals であるため、 routingの難しさを増しています。このトピックについては、別の一連のページがあります。
- 巨大な state machinesを作成しないでください。何台の states が OK であるかに厳密な制限はありません。ただし、 states の数が 20を超える場合は、 designの再構築を検討する必要があります。また、 synthesizer が大きな state machines に対して one-hot encoding を使用することを確認してください (デフォルトでは、ほとんどの synthesizers が使用します)。これは、高速な logicの生成に役立ちます。
- 通常、 RAM の後に register を追加する方が適切です。暗黙的に作成された RAM の例を見てみましょう。
reg [7:0] array[0:127]; reg [7:0] val; reg [6:0] addr; always @(posedge clk) val <= array[addr];
この Verilog コードは正しいですが、 @val は RAMの synchronous output であることに注意してください。したがって、 rising clock edgeがある場合は RAM の操作が開始され、 array からの値が取得された場合にのみ @val が更新されます。したがって、 @val には比較的大きな clock-to-output delay があります ( flip-flopと比較して)。したがって、 @valで始まる paths には固有の欠点があります。これは、追加の registerを追加することで修正できます。
reg [7:0] array[0:127]; reg [7:0] val_d, mem_out; reg [6:0] addr; always @(posedge clk) begin mem_out <= array[addr]; val_d <= mem_out; end
これは機能的に同等ではないことに注意してください。 @mem_out は RAM の output です。この output が @val_dにコピーされたのは、後の clock の 1 つだけであるため、 @valの正確な代替品ではありません。しかし、 @val_d は実際の registerであり、 clock-to-output delayは低くなっています。多くの FPGAsでは、この余分な register は block RAMsの一部であるため、 flip-flopsの無駄はありません。 flip-flopsを無駄にする心配はありませんと言いましたか?
残念ながら、このような register を追加すると、 design がかなり複雑になることがよくあります。このような場合、この余分な registerを追加するのではなく、 combinatorial path から @val を短く保つようにしてください。
2 つの余分な timing reports
上記の「あなたの脳に代わるものはありません」というセクションで、2つの timing reports を約束しました。それらは長く、完全に関連性がないため、言及されている場所ではなく、ここに配置しました。
これら 2 つの timing reports のそれぞれが、関連するシナリオの critical path であることに注意してください。したがって、 path は、上記の path と同じ registers で開始および終了しません。
最初の timing report は、最初の Verilog コード例に関連しています。上記の timing report とは異なり、ツールは指定された演算単位を使用できました。その結果、 timing constraints は簡単に実現できました。
この timing report は、 Kintex Ultrascale FPGA用に生成されました。この FPGAsファミリでは、専用演算装置を DSP48E2と呼びます。 path は同じ DSP48E2 ユニットで開始および終了することに注意してください。したがって、 logic delay は 100%です。
Slack (MET) : 1.406ns (required time - arrival time) Source: calc_reg/DSP_A_B_DATA_INST/CLK (rising edge-triggered cell DSP_A_B_DATA clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns}) Destination: calc_reg/DSP_OUTPUT_INST/ALU_OUT[10] (rising edge-triggered cell DSP_OUTPUT clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns}) Path Group: clk Path Type: Setup (Max at Slow Process Corner) Requirement: 4.000ns (clk rise@4.000ns - clk rise@0.000ns) Data Path Delay: 2.445ns (logic 2.445ns (100.000%) route 0.000ns (0.000%)) Logic Levels: 4 (DSP_ALU=1 DSP_M_DATA=1 DSP_MULTIPLIER=1 DSP_PREADD_DATA=1) Clock Path Skew: -0.010ns (DCD - SCD + CPR) Destination Clock Delay (DCD): 3.392ns = ( 7.392 - 4.000 ) Source Clock Delay (SCD): 4.096ns Clock Pessimism Removal (CPR): 0.694ns Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE Total System Jitter (TSJ): 0.071ns Total Input Jitter (TIJ): 0.000ns Discrete Jitter (DJ): 0.000ns Phase Error (PE): 0.000ns Clock Net Delay (Source): 2.264ns (routing 0.756ns, distribution 1.508ns) Clock Net Delay (Destination): 1.964ns (routing 0.696ns, distribution 1.268ns) Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r AG12 0.000 0.000 r clk (IN) net (fo=0) 0.000 0.000 clk_IBUF_inst/I AG12 INBUF (Prop_INBUF_HRIO_PAD_O) 0.738 0.738 r clk_IBUF_inst/INBUF_INST/O net (fo=1, routed) 0.105 0.843 clk_IBUF_inst/OUT AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O) 0.049 0.892 r clk_IBUF_inst/IBUFCTRL_INST/O net (fo=1, routed) 0.839 1.731 clk_IBUF BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O) 0.101 1.832 r clk_IBUF_BUFG_inst/O X2Y1 (CLOCK_ROOT) net (fo=80, routed) 2.264 4.096 calc_reg/CLK DSP48E2_X11Y34 DSP_A_B_DATA r calc_reg/DSP_A_B_DATA_INST/CLK ------------------------------------------------------------------- ------------------- DSP48E2_X11Y34 DSP_A_B_DATA (Prop_DSP_A_B_DATA_DSP48E2_CLK_A2_DATA[9]) 0.302 4.398 r calc_reg/DSP_A_B_DATA_INST/A2_DATA[9] net (fo=1, routed) 0.000 4.398 calc_reg/DSP_A_B_DATA.A2_DATA<9> DSP48E2_X11Y34 DSP_PREADD_DATA (Prop_DSP_PREADD_DATA_DSP48E2_A2_DATA[9]_A2A1[9]) 0.182 4.580 r calc_reg/DSP_PREADD_DATA_INST/A2A1[9] net (fo=1, routed) 0.000 4.580 calc_reg/DSP_PREADD_DATA.A2A1<9> DSP48E2_X11Y34 DSP_MULTIPLIER (Prop_DSP_MULTIPLIER_DSP48E2_A2A1[9]_U[10]) 0.994 5.574 f calc_reg/DSP_MULTIPLIER_INST/U[10] net (fo=1, routed) 0.000 5.574 calc_reg/DSP_MULTIPLIER.U<10> DSP48E2_X11Y34 DSP_M_DATA (Prop_DSP_M_DATA_DSP48E2_U[10]_U_DATA[10]) 0.164 5.738 r calc_reg/DSP_M_DATA_INST/U_DATA[10] net (fo=1, routed) 0.000 5.738 calc_reg/DSP_M_DATA.U_DATA<10> DSP48E2_X11Y34 DSP_ALU (Prop_DSP_ALU_DSP48E2_U_DATA[10]_ALU_OUT[10]) 0.803 6.541 r calc_reg/DSP_ALU_INST/ALU_OUT[10] net (fo=1, routed) 0.000 6.541 calc_reg/DSP_ALU.ALU_OUT<10> DSP48E2_X11Y34 DSP_OUTPUT r calc_reg/DSP_OUTPUT_INST/ALU_OUT[10] ------------------------------------------------------------------- ------------------- (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.515 4.515 r clk_IBUF_inst/INBUF_INST/O net (fo=1, routed) 0.066 4.581 clk_IBUF_inst/OUT AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O) 0.034 4.615 r clk_IBUF_inst/IBUFCTRL_INST/O net (fo=1, routed) 0.722 5.337 clk_IBUF BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O) 0.091 5.428 r clk_IBUF_BUFG_inst/O X2Y1 (CLOCK_ROOT) net (fo=80, routed) 1.964 7.392 calc_reg/CLK DSP48E2_X11Y34 DSP_OUTPUT r calc_reg/DSP_OUTPUT_INST/CLK clock pessimism 0.694 8.086 clock uncertainty -0.035 8.050 DSP48E2_X11Y34 DSP_OUTPUT (Setup_DSP_OUTPUT_DSP48E2_CLK_ALU_OUT[10]) -0.104 7.946 calc_reg/DSP_OUTPUT_INST ------------------------------------------------------------------- required time 7.946 arrival time -6.541 ------------------------------------------------------------------- slack 1.406
2 番目の timing report は、 Verilog コードの 2 番目の例に関連しています。この例では、 pipeliningによって状況が改善されています。
Slack (MET) : 0.433ns (required time - arrival time) Source: y_reg[1]__0/C (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns}) Destination: calc_reg[23]/D (rising edge-triggered cell FDRE clocked by clk {rise@0.000ns fall@2.000ns period=4.000ns}) Path Group: clk Path Type: Setup (Max at Slow Process Corner) Requirement: 4.000ns (clk rise@4.000ns - clk rise@0.000ns) Data Path Delay: 3.465ns (logic 1.653ns (47.706%) route 1.812ns (52.294%)) Logic Levels: 6 (CARRY8=4 LUT4=2) Clock Path Skew: -0.129ns (DCD - SCD + CPR) Destination Clock Delay (DCD): 3.373ns = ( 7.373 - 4.000 ) Source Clock Delay (SCD): 4.040ns Clock Pessimism Removal (CPR): 0.538ns Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE Total System Jitter (TSJ): 0.071ns Total Input Jitter (TIJ): 0.000ns Discrete Jitter (DJ): 0.000ns Phase Error (PE): 0.000ns Clock Net Delay (Source): 2.208ns (routing 0.756ns, distribution 1.452ns) Clock Net Delay (Destination): 1.945ns (routing 0.696ns, distribution 1.249ns) Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk rise edge) 0.000 0.000 r AG12 0.000 0.000 r clk (IN) net (fo=0) 0.000 0.000 clk_IBUF_inst/I AG12 INBUF (Prop_INBUF_HRIO_PAD_O) 0.738 0.738 r clk_IBUF_inst/INBUF_INST/O net (fo=1, routed) 0.105 0.843 clk_IBUF_inst/OUT AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O) 0.049 0.892 r clk_IBUF_inst/IBUFCTRL_INST/O net (fo=1, routed) 0.839 1.731 clk_IBUF BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O) 0.101 1.832 r clk_IBUF_BUFG_inst/O X2Y1 (CLOCK_ROOT) net (fo=121, routed) 2.208 4.040 clk_IBUF_BUFG SLICE_X54Y88 FDRE r y_reg[1]__0/C ------------------------------------------------------------------- ------------------- SLICE_X54Y88 FDRE (Prop_EFF2_SLICEL_C_Q) 0.138 4.178 r y_reg[1]__0/Q net (fo=25, routed) 0.505 4.683 y[1] SLICE_X53Y91 LUT4 (Prop_B6LUT_SLICEM_I0_O) 0.150 4.833 r calc[7]_i_28/O net (fo=1, routed) 0.344 5.177 calc[7]_i_28_n_0 SLICE_X53Y89 CARRY8 (Prop_CARRY8_SLICEM_DI[2]_CO[7]) 0.424 5.601 r calc_reg[7]_i_9/CO[7] net (fo=1, routed) 0.043 5.644 calc_reg[7]_i_9_n_0 SLICE_X53Y90 CARRY8 (Prop_CARRY8_SLICEM_CI_O[0]) 0.122 5.766 r calc_reg[23]_i_30/O[0] net (fo=3, routed) 0.402 6.168 calc_reg[23]_i_30_n_15 SLICE_X51Y88 LUT4 (Prop_C5LUT_SLICEL_I0_O) 0.169 6.337 r calc[15]_i_8/O net (fo=1, routed) 0.437 6.774 calc[15]_i_8_n_0 SLICE_X51Y92 CARRY8 (Prop_CARRY8_SLICEL_DI[1]_CO[7]) 0.422 7.196 r calc_reg[15]_i_1/CO[7] net (fo=1, routed) 0.030 7.226 calc_reg[15]_i_1_n_0 SLICE_X51Y93 CARRY8 (Prop_CARRY8_SLICEL_CI_O[7]) 0.228 7.454 r calc_reg[23]_i_1/O[7] net (fo=1, routed) 0.051 7.505 calc_reg[23]_i_1_n_8 SLICE_X51Y93 FDRE r calc_reg[23]/D ------------------------------------------------------------------- ------------------- (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.515 4.515 r clk_IBUF_inst/INBUF_INST/O net (fo=1, routed) 0.066 4.581 clk_IBUF_inst/OUT AG12 IBUFCTRL (Prop_IBUFCTRL_HRIO_I_O) 0.034 4.615 r clk_IBUF_inst/IBUFCTRL_INST/O net (fo=1, routed) 0.722 5.337 clk_IBUF BUFGCE_X1Y0 BUFGCE (Prop_BUFCE_BUFGCE_I_O) 0.091 5.428 r clk_IBUF_BUFG_inst/O X2Y1 (CLOCK_ROOT) net (fo=121, routed) 1.945 7.373 clk_IBUF_BUFG SLICE_X51Y93 FDRE r calc_reg[23]/C clock pessimism 0.538 7.910 clock uncertainty -0.035 7.875 SLICE_X51Y93 FDRE (Setup_HFF_SLICEL_C_D) 0.063 7.938 calc_reg[23] ------------------------------------------------------------------- required time 7.938 arrival time -7.505 ------------------------------------------------------------------- slack 0.433
違いは、指定された算術ユニットが使用されたときほど劇的ではありません。それでも、 timing constraintを達成するには十分です。
これで、 timing closureに関する一般的な説明を終了します。次のページでは、このトピックに関するいくつかの実用的な戦略を提案します。