動機
ISE のシンセサイザ (synthesizer)(xst)が生成するレポートの下の方に、最大周波数と、最も遅いパスの概要が書かれています。これはなかなか便利な機能で、特に特定のモジュールを最適化したいときには重宝します。Vivado で合成しても、このような数値は出力されません。おそらく Xilinx の人たちは、こうした「最大周波数」が誤解を招く恐れがあると考えたのでしょう。もしそうなら、その理由は次の 2 つとして納得できます。
- そもそも「最大周波数」などというものは本当は存在しません。ツールはタイミング制約 (timing constraints) を気にして、それに合わせて最善を尽くすだけです。要するに、ある周波数を制約として要求しなければ、その周波数は得られないかもしれません。
- 一般的な設計には周波数の異なるクロックがたくさんあります。最も遅いパス (path) は、もともと遅いクロックに属しているかもしれません。
それでも、完全なインプリメンテーションという苦難の道を歩み始める前に、現状を大まかに把握しておくと便利なことがあります。
Vivado での実施方法
何よりもまず、自分の期待に合わせてタイミング制約を設定します。少なくとも、どのクロックが重要で、どのクロックは遅くてもよいかがはっきりするように設定してください。それから設計の合成を行います。
合成が正常に完了したら、合成後のデザインを開きます。左のバーの [Open Synthesized Design] をクリックするか、Tcl コマンドで「open_run synth_1」を実行します。
Tcl ウィンドウで、次のコマンドを実行します。
report_timing_summary -file mytiming.rpt
これで、合成後の完全なタイミングレポートが mytiming.rpt に出力されます。ちなみに「report_timing_summary」だけを実行すると、コンソールに表示されます。
左のバーの [Synthesized Design] の下に [Report Timing Summary] オプションもあります。ただ、GUI からこのレポートを読み取るのは、私は難しいと感じます。
レポートの読み方
ルールその 1:合成レポートはあくまで概算です。配線遅延は見積もりにすぎません。実際のインプリメンテーションでは問題なく成功するのに、合成レポートではタイミング違反と報告されることもあれば、逆に、すべて問題ないと報告されても、本実装では大失敗することもあります(特に FPGA のロジック使用率が 100% 近くになっている場合)。
では実際の手順です。最初に Clock Summary と Intra Clock Table を確認して、Vivado が各クロックにどのような名前を付けたかを把握します。例えば、次のようになります。
------------------------------------------------------------------------------------------------
| Clock Summary
| -------------
------------------------------------------------------------------------------------------------
Clock Waveform(ns) Period(ns) Frequency(MHz)
----- ------------ ---------- --------------
clk_fpga_1 {0.000 5.000} 10.000 100.000
gclk {0.000 4.000} 8.000 125.000
audio_mclk_OBUF {0.000 41.667} 83.333 12.000
clk_fb {0.000 20.000} 40.000 25.000
vga_clk_ins/clk_fb {0.000 20.000} 40.000 25.000
vga_clk_ins/clkout0 {0.000 1.538} 3.077 325.000
vga_clk_ins/clkout1 {0.000 7.692} 15.385 65.000
vga_clk_ins/clkout2 {0.000 7.692} 15.385 65.000
------------------------------------------------------------------------------------------------
| Intra Clock Table
| -----------------
------------------------------------------------------------------------------------------------
Clock WNS(ns) TNS(ns) TNS Failing Endpoints TNS Total Endpoints WHS(ns) THS(ns) THS Failing Endpoints THS Total Endpoints WPWS(ns) TPWS(ns) TPWS Failing Endpoints TPWS Total Endpoints
----- ------- ------- --------------------- ------------------- ------- ------- --------------------- ------------------- -------- -------- ---------------------- --------------------
clk_fpga_1 3.791 0.000 0 12474 0.135 0.000 0 12474 3.750 0.000 0 5021
gclk 6.751 0.000 0 2
audio_mclk_OBUF 76.667 0.000 0 1
clk_fb 12.633 0.000 0 2
vga_clk_ins/clk_fb 38.751 0.000 0 2
vga_clk_ins/clkout0 1.410 0.000 0 10
vga_clk_ins/clkout1 10.747 0.000 0 215 -0.029 -0.229 8 215 6.712 0.000 0 195
vga_clk_ins/clkout2 3.990 0.000 0 415 0.135 0.000 0 415 7.192 0.000 0 211
Clock Summary にリストされるクロック周波数(タイミング制約から派生したもの)を見ても、クロックと名前の対応がよく分からない場合は、Intra Clock Table の各クロックの TNS Total Endpoints の列が手掛かりになります。そして、調べたいクロックの名前が分かったら、その名前をファイル内で検索し、次のようなセクションを探します。
Max Delay Paths -------------------------------------------------------------------------------------- Slack (MET) : 3.791ns (required time - arrival time) Source: xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_offset_limit_1/C (rising edge-triggered cell FDRE clocked by clk_fpga_1 {rise@0.000ns fall@5.000ns period=10.000ns}) Destination: xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_end_offset_0/D (rising edge-triggered cell FDRE clocked by clk_fpga_1 {rise@0.000ns fall@5.000ns period=10.000ns}) Path Group: clk_fpga_1 Path Type: Setup (Max at Slow Process Corner) Requirement: 10.000ns (clk_fpga_1 rise@10.000ns - clk_fpga_1 rise@0.000ns) Data Path Delay: 6.077ns (logic 2.346ns (38.605%) route 3.731ns (61.395%)) Logic Levels: 8 (CARRY4=3 LUT3=1 LUT4=1 LUT6=3) Clock Path Skew: -0.040ns (DCD - SCD + CPR) Destination Clock Delay (DCD): 0.851ns = ( 10.851 - 10.000 ) Source Clock Delay (SCD): 0.901ns Clock Pessimism Removal (CPR): 0.010ns Clock Uncertainty: 0.154ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE Total System Jitter (TSJ): 0.071ns Total Input Jitter (TIJ): 0.300ns Discrete Jitter (DJ): 0.000ns Phase Error (PE): 0.000ns Location Delay type Incr(ns) Path(ns) Netlist Resource(s) ------------------------------------------------------------------- ------------------- (clock clk_fpga_1 rise edge) 0.000 0.000 r PS7 0.000 0.000 r xillybus_ins/system_i/vivado_system_i/processing_system7_0/inst/PS7_i/FCLKCLK[1] net (fo=1, unplaced) 0.000 0.000 xillybus_ins/system_i/vivado_system_i/processing_system7_0/inst/n_707_PS7_i BUFG (Prop_bufg_I_O) 0.101 0.101 r xillybus_ins/system_i/vivado_system_i/processing_system7_0/inst/buffer_fclk_clk_1.FCLK_CLK_1_BUFG/O net (fo=5023, unplaced) 0.800 0.901 xillybus_ins/xillybus_core_ins/bus_clk_w r xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_offset_limit_1/C ------------------------------------------------------------------- ------------------- FDRE (Prop_fdre_C_Q) 0.496 1.397 f xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_offset_limit_1/Q net (fo=5, unplaced) 0.834 2.231 xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_offset_limit[1] LUT4 (Prop_lut4_I0_O) 0.289 2.520 r xillybus_ins/xillybus_core_ins/unitw_1_ins/Mcompar_n0037_lutdi/O net (fo=1, unplaced) 0.000 2.520 xillybus_ins/xillybus_core_ins/unitw_1_ins/Mcompar_n0037_lutdi CARRY4 (Prop_carry4_DI[0]_CO[3]) 0.553 3.073 r xillybus_ins/xillybus_core_ins/unitw_1_ins/Mcompar_n0037_cy[0]_CARRY4/CO[3] net (fo=1, unplaced) 0.000 3.073 xillybus_ins/xillybus_core_ins/unitw_1_ins/Mcompar_n0037_cy[3] CARRY4 (Prop_carry4_CI_CO[3]) 0.114 3.187 r xillybus_ins/xillybus_core_ins/unitw_1_ins/Mcompar_n0037_cy[4]_CARRY4/CO[3] net (fo=3, unplaced) 0.936 4.123 xillybus_ins/xillybus_core_ins/unitw_1_ins/Mcompar_n0037_cy[7] LUT6 (Prop_lut6_I4_O) 0.124 4.247 f xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_wr_request_condition/O net (fo=7, unplaced) 0.480 4.727 xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_wr_request_condition LUT3 (Prop_lut3_I2_O) 0.124 4.851 r xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_flush_condition_unitw_1_wr_request_condition_AND_179_o3_lut/O net (fo=1, unplaced) 0.000 4.851 xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_flush_condition_unitw_1_wr_request_condition_AND_179_o3_lut CARRY4 (Prop_carry4_S[2]_CO[3]) 0.398 5.249 f xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_flush_condition_unitw_1_wr_request_condition_AND_179_o2_cy_CARRY4/CO[3] net (fo=21, unplaced) 0.979 6.228 xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_flush_condition_unitw_1_wr_request_condition_AND_179_o LUT6 (Prop_lut6_I5_O) 0.124 6.352 r xillybus_ins/xillybus_core_ins/unitw_1_ins/_n03401/O net (fo=15, unplaced) 0.502 6.854 xillybus_ins/xillybus_core_ins/unitw_1_ins/_n0340 LUT6 (Prop_lut6_I5_O) 0.124 6.978 r xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_end_offset_0_rstpot/O net (fo=1, unplaced) 0.000 6.978 xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_end_offset_0_rstpot FDRE r xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_end_offset_0/D ------------------------------------------------------------------- ------------------- (clock clk_fpga_1 rise edge) 10.000 10.000 r PS7 0.000 10.000 r xillybus_ins/system_i/vivado_system_i/processing_system7_0/inst/PS7_i/FCLKCLK[1] net (fo=1, unplaced) 0.000 10.000 xillybus_ins/system_i/vivado_system_i/processing_system7_0/inst/n_707_PS7_i BUFG (Prop_bufg_I_O) 0.091 10.091 r xillybus_ins/system_i/vivado_system_i/processing_system7_0/inst/buffer_fclk_clk_1.FCLK_CLK_1_BUFG/O net (fo=5023, unplaced) 0.760 10.851 xillybus_ins/xillybus_core_ins/bus_clk_w r xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_end_offset_0/C clock pessimism 0.010 10.861 clock uncertainty -0.154 10.707 FDRE (Setup_fdre_C_D) 0.062 10.769 xillybus_ins/xillybus_core_ins/unitw_1_ins/unitw_1_end_offset_0 ------------------------------------------------------------------- required time 10.769 arrival time -6.978 ------------------------------------------------------------------- slack 3.791
上記はかなりごちゃごちゃしたテキストですが、重要な要素は赤字で示されています。
結論を出す前に、見ている場所が正しいことを確認してください。
- 見ているのが Max Delay Paths セクションであること。Min Delay Paths セクションはホールドタイム違反を見つけるのに役立ちますが、最大周波数には影響しません。
- 見ているのが正しいクロックのパスであること。上の例では clk_fpga_1 です。Requirement の行には、このクロックに与えた制約(10 ns = 100 MHz)だけでなく、clk_fpga_1 のある立ち上がりエッジから次の立ち上がりエッジまでの計算であることも書かれています。
それが確認できたら、結果を見てみましょう。要求は 10 ns で、スラック (slack) は 3.791 ns(正の値であることに注意)でした。つまり、要求クロック周期をあと 3.791 ns 短くしても成立したはずです。したがって、要求できたクロック周期は 10 - 3.791 = 6.2090 ns、つまり約 161 MHz になります。
以上から、clk_fpga_1 の「最大クロック」への短い答えは 161 MHz です。ただし、この数値は制約を変えると変わる可能性があることを覚えておいてください。
最後に一言。Data Path Delay (データパス遅延) は、この最悪パスがなぜ遅いのか/速いのかを教えてくれます。ロジックにどれだけの遅延があり、見積もり配線遅延にどれだけあったかが分かります。続く詳細な遅延レポートも同様です。より詳しいレポートが必要な場合は、タイミングレポートを取得する際に -nworst オプションを付けると、最悪パスがいくつか列挙されます。これはタイミング問題の解決に役立ちます。