Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Vivado hls勉強会2(レジスタの挿入とpipelineディレクティブ)

3,796 views

Published on

Vivado HLS勉強会資料の2番目で、最初に1番目の資料から御覧下さい。
今回は、ディレクティブを使って、入力、そして出力にレジスタを挿入して、PIPELINEディレクティブを入れてパイプライン化します。
次にPIPELINEディレクティブの応用として、rewind オプションを使ってディスプレイ・コントローラを実装してみます。

Published in: Technology
  • 2016/03/28 バグを修正しました。
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • CのソースコードはFPGAの部屋のブログの”Vivado HLS 勉強会2(レジスタの挿入とPIPELINEディレクティブ)を公開しました”に貼ってあるので、御覧下さい。 http://marsee101.blog19.fc2.com/blog-entry-3335.html
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Vivado hls勉強会2(レジスタの挿入とpipelineディレクティブ)

  1. 1. 1 Vivado HLS勉強会2 (レジスタの挿入と PIPELINEディレクティブ) 小野 雅晃
  2. 2. 2 ●Vivado HLS勉強会1でやったこと ● Vivado HLS勉強会1(基礎編)ではVivado HLSに よるIP作製方法、VivadoのIPIでのそのIPの使用 法について学習した ● 組み合わせ回路の掛け算器を題材にした ● クロックやリセットは使用していない
  3. 3. 3 これから何をするのか?1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する – 新規Solutionを作製
  4. 4. 4 これから何をするのか?2 ● 補足(応用例) – ディスプレイ・コントローラの作製
  5. 5. 5 次をやる前にバックアップしましょう ● これから入力や出力にレジスタを追加する と、ap_clk, ap_rstがHDLに追加され、Vivadoで 作った掛け算器(multi_ex1)プロジェクトがコンパ イルできなくなります ● Vivado HLSのプロジェクトをバックアップしたい方 はZIP圧縮するか、Vivado HLSのプロジェクト (multi_apuint)ごと、どこかのフォルダにコピーして おいて下さい(バックアップしなくても、すぐに再生 成できます)
  6. 6. 6 注意点 ● 元はVivado HLS 2014.4で作製した資料を修正が 必要なところだけVivado HLS 2015.4に修正して あります ● よって、Vivado HLSのウインドウにOpen Wave viewer…が無い画面がありますがご了承下さい
  7. 7. 7 これから何をするのか?1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する – 新規Solutionを作製
  8. 8. 8 掛け算器の出力にFFを挿入した ブロック図 * multi_in0multi_in0 multi_in1 multi_out 8 ビット 8 ビット 16 ビット FF 組み合わせ回路
  9. 9. 9 掛け算器の出力にレジスタを挿入 ● 左のExplorerのSourceを開いて、multi_apuint.cppをダブ ルクリックする ● 右のDirectiveタブをクリックして、multi_outの下のディレク ティブを右クリックし、右クリックメニューからModify Directiveを選択する
  10. 10. 10 ap_vldとregister ● mode(optional)をap_vld ● register(optional)にチェックを 入れる ● OKボタンをクリックする
  11. 11. 11 ap_ctrl_noneからap_ctrl_hsに戻す ● ap_ctrl_noneではレジスタを挿入するとC/RTLコシ ミュレーションができない ● ap_ctrl_hsに戻す ● せっかくなので、明示的に宣言してみよう ● ap_ctrl_noneでC/RTLコシミュレーションが可能な 場合 – 組み合わせ回路 – パイプライン回路でインターバルが1の場合 – array streamやhls_streamまたはAXI4-Streamの場合
  12. 12. 12 returnポートをap_ctrl_hsへ変更 ● 右のDirctiveウインドウでmulti_apuintの下のディレク ティブを右クリックし、右クリックメニューからModify Directiveを選択する
  13. 13. 13 ap_ctrl_hsへ変更 ● mode(optional)を ap_ctrl_noneからap_ctrl_hs に変更する ● OKボタンをクリックする
  14. 14. 14 変更したディレクティブをセーブ ● セーブアイコンをクリックし、変更したディレクティブをセー ブする ● セーブ後の様子を示す
  15. 15. 15 Cコードの合成 ● C Synthesisボタンをクリックして、Cソースコードの合成を行った ● TimingのSummaryでClockのTarget周期が10nsのところ、6.38nsなの で問題無い ● 成功
  16. 16. 16 合成結果 ● Latencyは1、Interval は2 ● 出力にレジスタを挿入 する前はLatencyは 0、Intervalは1 ● DSP48EとFFとLUTを 使用している ● 出力にレジスタを挿入 する前はDSP48Eの み使用していた
  17. 17. 17 HDLコードの確認 ● solution1 →syn→ve rilogまたは VHDLフォ ルダに生成 されたHDL ファイルを 観察する ● ap_clkと ap_rstが増 えている
  18. 18. 18 Analysis表示への切替 ● 右上のAnalysisボタンをクリックするとAnalysis表 示になる
  19. 19. 19 Analysis表示(Performanceタブ) ● Performanceタブ表示(2ステート) ● 下のResourceタブをクリックするとResource表示となる
  20. 20. 20 Analysis表示(Resourceタブ) ● Resoureタブを選択した状態、すべて展開済み ● C0ステート(read,*の掛け算, Write)、C1ステート(Write)
  21. 21. 21 これから何をするのか?1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する – 新規Solutionを作製
  22. 22. 22 multi_apuint_tb.cppを変更 ● 演算の出力タイミングを確認するために multi_apuint_tb.cppを変更した
  23. 23. 23 multi_apuint_tb.cpp #include <string.h> #include <ap_int.h> void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1, ap_uint<16> *multi_out); int main(){ using namespace std; ap_uint<8> multi_in0; ap_uint<8> multi_in1; ap_uint<16> multi_out; for (multi_in0=0, multi_in1=1; multi_in0<10; multi_in0++, multi_in1++){ multi_apuint(multi_in0, multi_in1, &multi_out); cout << "multi_out = " << multi_out << endl; if (multi_out != (multi_in0 * multi_in1)) return(1); } return(0); }
  24. 24. 24 C/RTLコシミュレーション ● Run C/RTL Cosimulationボタンをクリックする ● CやC++で書かれたテストベンチのデータをHDLシミュ レータに入力してシミュレーションを行う
  25. 25. 25 Warningダイアログ ● Warningダイアログが表示された ● Re-synthesize and continueボタンをクリックする
  26. 26. 26 Co-simulation Dialog ● 高位合成を行った ● Dump Trace がall に設 定されていることを確認 する(none, port, allの 設定が可能) ● allにすると、すべての 信号波形が記録される ● OKボタンをクリックする とC/RTLコシミュレー ションが始まる
  27. 27. 27 C/RTLコシミュレーション ● C/RTLコシミュレーションが終了した ● LatencyとIntervalのmin, avgは1クロック、maxは2クロック だった
  28. 28. 28 Open Wave viewer...ボタンをクリック ● Open Wave viewer...ボタンをクリックする ● Vivado が立ち上がる
  29. 29. 29 Vivadoが立ち上がった
  30. 30. 30 Waveformウインドウを表示 ● WindowメニューからWaveformを選択する
  31. 31. 31 Vivadoによる シミュレーション波形表示
  32. 32. 32 Waveformウインドウ1 ● Zoom Fitアイコンをクリックして、波形全体を表示 ● Nameペインで右クリックメニューからSelect Allを選択
  33. 33. 33 Waveformウインドウ2 ● 選択部分を右クリックし、右クリックメニューから Radix -> Unsigned Decimal を選択
  34. 34. 34 Waveformウインドウ3 ● 掛け算に2クロック必要なことがわかる ● 2クロックに1回multi_out_V_ap_vldがアサートされる
  35. 35. 35 Vivado 2015.4を終了 ● FileメニューからExitを選択するか、右上の”閉じ る”ボタンをクリックして、Vivadoを終了する
  36. 36. 36 これから何をするのか?1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する – 新規Solutionを作製
  37. 37. 37 掛け算器の入力と出力にFFを 挿入したブロック図 * multi_in0multi_in0 multi_in1 multi_out 8 ビット 8 ビット 16 ビット FF FF FF 組み合わせ回路
  38. 38. 38 multi_in0をレジスタ入力にする ● multi_apuint.cppを表示する ● multi_in0を右クリックし、右クリックメニューからInsert Directive...を選択する
  39. 39. 39 multi_in0をap_hsとregisterに設定 ● DirectiveをINTERFACEに ● DestinationをSource Fileに ● Optionsのmodeをap_hsに ● Optionsのregisterにチェック を入れる ● OKボタンをクリックする
  40. 40. 40 multi_in1もap_hsとregisterに設定 ● multi_in1もmulti_in0と同様に設定する – DirectiveをINTERFACEに – DestinationをSource Fileに – Optionsのmodeをap_hsに – Optionsのregisterにチェックを入れる ● 設定後、セーブする
  41. 41. 41 セーブ終了後のVivado HLSの画面
  42. 42. 42 Cコードの合成と結果 ● C Synthesisボタンをクリックして、Cソースコードの合成を 行った ● 図には結果を示す
  43. 43. 43 Cコードの合成結果2 ● Latencyが2、Intervalが 3となった ● DSP48Eを1個、FFを38 個、LUTを2個使用する
  44. 44. 44 Analysis表示(Performanceタブ) ● 右上のAnalysisボタンをクリックしAnalysis表示にする ● 3クロック必要とするのがわかる ● 下のResourceタブをクリックし、Resource表示にする
  45. 45. 45 Analysis表示(Resourceタブ) ● +ボタンをクリックしてすべて展開する ● readが2クロックかかるようになった(以前は1クロック) ● Synthesisボタンをクリックして画面を戻す
  46. 46. 46 これから何をするのか?1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する – 新規Solutionを作製
  47. 47. 47 C/RTLコシミュレーション ● わざと文字だけでやることを指定するので、自分で やってみよう ● Run C/RTL Cosimulationボタンをクリックする ● Co-simulation Dialog – Dump Trace が all に設定されていることを確認する
  48. 48. 48 C/RTLコシミュレーション結果 ● LatencyとIntervalのmin, avgは2クロック、maxは 3クロックだった
  49. 49. 49 Vivadoを起動して波形を確認1 ● Vivado HLS 2015.4のOpen Wave viewer…ボタ ンをクリックする ● Vivado 2015.4が立ち上がる ● WindowメニューからWaveformを選択する
  50. 50. 50 Vivadoを起動して波形を確認2 ● Waveformウインドウをフロートして拡大する か、Vivadoウインドウを拡大して波形を見やすくす る ● Nameペインで右クリックし、右クリックメニューから Select Allを選択 ● 選択部分を右クリックし、右クリックメニューから Radix -> Unsigned Decimal を選択 ● これで10進数で表示される
  51. 51. 51 Vivadoを起動して波形を確認3 ● 掛け算に3クロックかかっている ● multi_in?_ap_vldが入力され、すぐにap_ackが帰る ● 2クロック後にap_done, multi_out_V_ap_vldがアサートされる ● 一番下のap_CS_fsmがステートを表している
  52. 52. 52 これから何をするのか?1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する – 新規Solutionを作製
  53. 53. 53 逐次処理 a, b, d 入力 c = a * b e = c * d e 出力 a, b, d 入力 c = a * b e = c * d e 出力 c = a * b; e = c * d; (演算) 回路ブロック図 処理タイミング レジスタ 掛け算器 * a,b,d入力 a b d M U X M U X レジスタ e 出力 レジスタ
  54. 54. 54 パイプライン処理 レジスタ レジスタ掛け算器 * レジスタ掛け算器 * a 出力 入力 c = a * b; 出力 レジスタ b d e = c * d; c = a * b; e = c * d; (演算) 回路ブロック図 a, b, d 入力 c = a * b e = c * d e 出力 a, b, d 入力 c = a * b e = c * d e 出力 a, b, d 入力 c = a * b e = c * d e 出力 a, b, d 入力 c = a * b e = c * d e 出力 処理タイミング レジスタ
  55. 55. 55 現在の掛け算回路 ● ap_CS_fsmが1、2、4と遷移する ● ap_CS_fsmが1の時は入力用レジスタにラッチ ● 2の時に掛け算 ● 4の時に答えを出力 入力用レジスタ 入力用レジスタ * multi_in0 multi_in1 出力用レジスタ multi_out ap_CS_fsm 1 ap_CS_fsm 2 ap_CS_fsm 4
  56. 56. 56 PIPELINEディレクティブ ● PIPELINEディレクティブ – ループまたは関数内での演算を同時処理でき る よ う に し て開始間隔を削減し ます ● 入力 * 出力 入力 * 出力 入力 * 出力 入力用レジスタ 入力用レジスタ * multi_in0 multi_in1 出力用レジスタ multi_out ap_CS_fsm 1
  57. 57. 57 Vivado HLSで PIPELINEディレクティブを挿入 ● 右のウインドウのDirectiveタブをクリックし、Insert Directive...を選択する
  58. 58. 58 PIPELINEディレクティブの選択 ● DirectiveでPIPELINEを選択 する ● DestinationでSource Fileの ラジオボタンをクリックする ● OKボタンをクリックする
  59. 59. 59 ファイルをセーブ ● PIPELINEディレクティブが挿入された ● ファイルをセーブした
  60. 60. 60 Cコードの合成結果1 ● C Synthesisボタンをクリックして、Cソースコードの合成を行った ● TimingのSummaryでClockのTarget周期が10nsのとこ ろ、6.38nsなので問題無い
  61. 61. 61 Cコードの合成結果2 ● Latencyは2、Intervalは1 になっている ● Intervalが1なので、1ク ロックごとに入力データを 入れることができる ● 1クロックごとにパイプラ インされている
  62. 62. 62 Analysis表示 ● 上がResourceタブの表示、下がPerformanceタブの表示である ● Analysis表示はPIPELINEディレクティブが付加されていない場 合と同じである
  63. 63. 63 これから何をするのか?1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する – 新規Solutionを作製
  64. 64. 64 C/RTLコシミュレーション ● 右上のSynthesisボタンをクリックして表示を戻す ● Run C/RTL Cosimulationボタンをクリックし、HDL ベースでのシミュレーションを行う
  65. 65. 65 Co-simulation Dialog ● Dump Trace がall に設 定されていることを確認 する ● allにすると、すべての 信号波形が記録される (portもある) ● OKボタンをクリックする とC/RTLコシミュレー ションが始まる
  66. 66. 66 C/RTLコシミュレーション結果 ● Latencyは2、Intervalは1だった ● Intervalが1なので、1クロックごとにデータを入力することが できる(パイプライン処理)
  67. 67. 67 Vivadoを起動して波形を確認1 ● Vivado HLS 2015.4のOpen Wave viewer…ボタ ンをクリックする ● Vivado 2015.4が立ち上がる ● WindowメニューからWaveformを選択する
  68. 68. 68 Vivadoを起動して波形を確認2 ● Waveformウインドウをフロートして拡大する か、Vivado全体のウインドウを拡大して波形を見 やすくする ● Nameペインで右クリックし、右クリックメニューから Select Allを選択 ● 選択部分を右クリックし、右クリックメニューから Radix -> Unsigned Decimal を選択 ● これで10進数で表示される
  69. 69. 69 Vivadoを起動して波形を確認3 ● multi_in0_V_ap_vld(in1も)がアサートされてから2クロック後に multi_out_V_ap_vldがアサートされている ● その後は2つとも続けてアサートされている ● インターバル1クロックのパイプライン処理が行われている
  70. 70. 70 これから何をするのか?1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する – 新規Solutionを作製
  71. 71. 71 Solution ● 現在はSolution1ですべて賄っているが、複数の Solutionを生成することもできる ● ProjectメニューからNew Solution...を選択すると 新しいSolutionを作製できる ● 異なるクロック周期を変更したりや異なるFPGAに ついて、元の合成結果などを変更すること無しに、 試すことができる
  72. 72. 72 New Solution ● ProjectメニューからNew Solution...を選択する
  73. 73. 73 Solution Wizard ● Clock Period、Partなどを変更できる ● Clock Periodを10 nsから2.5 nsに変更した ● Finishボタンをクリックする(Finishボタンが押せない場合はPart をもう一度選択してください)
  74. 74. 74 Solution2 ● solution2ができて、フォーカスされた
  75. 75. 75 Cコードの合成と結果 ● Run C Synthesisボタンをクリックして、Cソースコードの合成を行った ● Targetの2.50 nsに対して、Estimatedの2.15 nsで合成 ● 465MHzで動作
  76. 76. 76 合成結果 ● Latencyが2から5へ ● Intervalは1で変更なし、 つまり毎クロックごとに データ入力可 ● FFは38から41に増えた
  77. 77. 77 Analysis表示 ● Analysisボタンをクリックして、Analysis表示へ変更 ● multi_apuint_mul_8ns_8ns_16_4_U0で複数クロックで 掛け算を実行
  78. 78. 78 これから何をするのか?2 ● 補足(応用例) – ディスプレイ・コントローラの作製
  79. 79. 79 ディスプレイ・コントローラの 出力画像 ● ディスプレイに パターンを表示 – 左上が赤 – 左下が青 – 右上が緑 – 右下が白
  80. 80. 80 ディスプレイ・コントローラの仕様 ● 640 x 480 ピクセルのVGA解像度 ● ピクセルクロックは 40 MHz (周期は 25 ns) ● 水平信号規格 – 画像表示領域 800 クロック – 水平フロントポーチ 40 クロック – 水平同期信号 128 クロック – 水平バックポーチ 88 クロック ● 垂直信号規格 – 画像表示領域 600 ライン – 垂直フロントポーチ 1 ライン – 垂直同期信号 4 ライン – 垂直バックポーチ 23 ライン
  81. 81. 81 Vivado HLS 2015.4の起動と 新規プロジェクト作製 ● Vivado HLS 2015.4を起動する ● Create New Projectをクリックして、新規プロジェクトを作製する
  82. 82. 82 プロジェクト作成パスと プロジェクト名の指定 ● Locationに適当なフォルダを指定する(ここでは、V_HLS_study_meetingを指 定した) ● Project nameにdisplay_contを入力する ● Next >ボタンをクリックする
  83. 83. 83 Add/Remove C-based source files ● デフォルト状態で、Next >ボタンをクリックする
  84. 84. 84 Add/Remove C-based testbench files ● デフォルト状態で、Next >ボタンをクリックする
  85. 85. 85 Solution Configuration 1 ● solution1の設定を行う ● Clock Periodは10(ns)なので、そのままとする ● FPGAの種類を選択するためにPart Selectionの…ボタンをクリックする
  86. 86. 86 Device Selection Dialog ● Filterを上図のように設定する ● xc7z010clg400-1を選択して、OKボタンをクリックする
  87. 87. 87 Solution Configuration 2 ● Part SelectionのPartにxc7z010clg400-1が設定された ● Finishボタンをクリックする
  88. 88. 88 Vivado HLS起動 ● Vivado HLSが起動した
  89. 89. 89 New Source ● ProjectメニューからNew Source…を選択して、新 しいC++ファイルを作製する
  90. 90. 90 c++ソースファイルの生成 ● ファイル名にdisplay_cont.cppと入力する ● 保存ボタンをクリックする
  91. 91. 91 display_cont.cpp ● C++コードを入力し、セーブアイコンをクリックする
  92. 92. 92 display_cont.cpp (1/2) // display_cont.cpp // 2015/06/03 by marsee // // 画面を4分割した第1象限は赤、第2象限は緑、第3象限は青、第4象限は白を表示する // #include <stdio.h> #include <string.h> #include <ap_int.h> // SVGA 解像度 #define H_ACTIVE_VIDEO 800 #define H_FRONT_PORCH 40 #define H_SYNC_PULSE 128 #define H_BACK_PORCH 88 #define H_SUM (H_ACTIVE_VIDEO + H_FRONT_PORCH + H_SYNC_PULSE + H_BACK_PORCH) #define V_ACTIVE_VIDEO 600 #define V_FRONT_PORCH 1 #define V_SYNC_PULSE 4 #define V_BACK_PORCH 23 #define V_SUM (V_ACTIVE_VIDEO + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH) void display_cont_sub(ap_uint<8> *red, ap_uint<8> *green, ap_uint<8> *blue, ap_uint<1> *display_enable, ap_uint<1> *hsyncx, ap_uint<1> *vsyncx){ #pragma HLS INTERFACE ap_none register port=red #pragma HLS INTERFACE ap_none register port=green #pragma HLS INTERFACE ap_none register port=blue #pragma HLS INTERFACE ap_none register port=display_enable #pragma HLS INTERFACE ap_none register port=hsyncx #pragma HLS INTERFACE ap_none register port=vsyncx #pragma HLS INTERFACE ap_ctrl_none port=return
  93. 93. 93 display_cont.cpp (2/2) ap_uint<16> h_count, v_count; for (v_count=0; v_count<V_SUM; v_count++){ for (h_count=0; h_count<H_SUM; h_count++){ #pragma HLS PIPELINE II=1 rewind if (h_count > (H_ACTIVE_VIDEO +H_FRONT_PORCH) && h_count < (H_ACTIVE_VIDEO + H_FRONT_PORCH + H_SYNC_PULSE)) *hsyncx = 0; else *hsyncx = 1; if (v_count > (V_ACTIVE_VIDEO + V_FRONT_PORCH) && v_count < (V_ACTIVE_VIDEO + V_FRONT_PORCH + V_SYNC_PULSE)) *vsyncx = 0; else *vsyncx = 1; if (h_count < H_ACTIVE_VIDEO && v_count < V_ACTIVE_VIDEO) *display_enable = 1; else *display_enable = 0; if (v_count < V_ACTIVE_VIDEO/2){ if (h_count < H_ACTIVE_VIDEO/2){ *red=0xff; *green=0; *blue=0; } else if (h_count < H_ACTIVE_VIDEO){ *red=0; *green=0xff; *blue=0; } else { *red=0; *green=0; *blue=0; } } else if (v_count < V_ACTIVE_VIDEO){ if (h_count < H_ACTIVE_VIDEO/2){ *red=0; *green=0; *blue=0xff; } else if (h_count < H_ACTIVE_VIDEO){ *red=0xff; *green=0xff; *blue=0xff; } else { *red=0; *green=0; *blue=0; } } else { *red=0; *green=0; *blue=0; } } } }
  94. 94. 94 PIPELINEディレクティブの rewindオプション ● rewindオプションはループが終了したときに関数 の初期化をせずにループを再度実行する ● 1フレーム終了して、もう一度forループに戻るに数 クロック必要とするが、ループに戻るので、その数 クロック分がキャンセルできる ● ディスプレイ・コントローラでは、1フレーム終了して から数クロック余計にかかってフレームが伸びると 画面がゆがむ可能性があった ● rewindオプションを付けると防げる
  95. 95. 95 PIPELINEディレクティブの rewindオプションがない場合 ● フレームの最後で26.4usのはずが26.475usになっている ● 3クロック多くなった
  96. 96. 96 PIPELINEディレクティブの rewindオプションを付けた場合 ● フレームの最後でも26.4us
  97. 97. 97 テストベンチファイルの生成 ● ProjectメニューからAdd Test Bench...を選択する
  98. 98. 98 disp_cont_tb.cpp ● ファイル名にdisplay_cont_tb.cppと入力する ● 保存ボタンをクリックする
  99. 99. 99 テストベンチを保存 ● テストベンチのC++コードを入力し、セーブアイコン をクリックした
  100. 100. 100 display_cont_tb.cpp // // display_cont_tb.cpp // 2015/06/03 by marsee // #include <stdio.h> #include <string.h> #include <ap_int.h> void display_cont_sub(ap_uint<8> *red, ap_uint<8> *green, ap_uint<8> *blue, ap_uint<1> *display_enable, ap_uint<1> *hsyncx, ap_uint<1> *vsyncx); int main(){ ap_uint<8> redb, *red; ap_uint<8> greenb, *green; ap_uint<8> blueb, *blue; ap_uint<1> deb, *display_enable; ap_uint<1> hb, *hsyncx; ap_uint<1> vb, *vsyncx; red = &redb; green = &greenb; blue = &blueb; display_enable = &deb; hsyncx = &hb; vsyncx = &vb; display_cont_sub(red, green, blue, display_enable, hsyncx, vsyncx); return 0; }
  101. 101. 101 Top Functionの指定1 ● Cコードを合成する前に、Top Functionを指定する。 ● これがCコードの合成の最上位関数になる。 ● ProjectメニューからProject Settings...を選択する
  102. 102. 102 Top Functionの指定2 ● 左のウインドウで、Synthesisを選択する ● Top Functionの右のBrows...ボタンをクリックする
  103. 103. 103 Top Functionの指定3 ● display_cont.cppのdisplay_cont_subを選択する ● OKボタンをクリックする
  104. 104. 104 Top Functionの指定4 ● Top Functionにdisplay_cont_subが入った ● OKボタンをクリックする
  105. 105. 105 Solution Settings ● SolutionメニューからSolution Settings...を選択す る ● クロック周期を40MHz(25 ns)に設定する – SVGA(800 x 600)のピクセルクロック
  106. 106. 106 Solution Settingsダイアログ ● Synthesisをクリックし、Periodに25を設定する
  107. 107. 107 Cコードの合成と結果 ● Run C Synthesisボタンをクリックして、Cソースコードの 合成を行う ● 図には結果を示す
  108. 108. 108 Cコードの合成結果2 ● Latencyがmin = 663168, max = 663169 で、Intervalが 663168 になった ● Intervalは、水平ピクセ ル x 垂直ラインの総ピク セル数は、 (800+40+128+88)*(600 +1+4+23) = 663168 ピ クセルと一致している
  109. 109. 109 Analysis解析 ● AnalysisボタンをクリックしてAnalysis解析結果を 見る ● C1ステートに処理が集まっていることがわかる ● 常にC1ステートに留まる
  110. 110. 110 C/RTLコシミュレーション ● Run C/RTL Cosimulationボタンをクリックし、HDLベースで のシミュレーションを行う ● Co-simulation Dialogが表示される ● Dump Trace を none から all に設定を変更する ● OKボタンをクリックするとC/RTLコシミュレーションが始まる ● 注:コードでは、INTERFACEディレクティブでブロックレベル のインタフェース(return)のプロトコルをap_ctrl_hsに設定し ています。これはC/RTLコシミュレーションを行うためです ● 注:ハードウェア化する場合には、ap_ctrl_noneに設定を変 更する必要があります
  111. 111. 111 C/RTLコシミュレーション結果 ● Latencyは663169 ● Intervalは0
  112. 112. 112 Vivadoを起動して波形を確認1 ● Vivado HLS 2015.4のOpen Wave viewer…ボタ ンをクリックする ● Vivado 2015.4が立ち上がる ● WindowメニューからWaveformを選択する
  113. 113. 113 Vivadoを起動して波形を確認2 ● Waveformウインドウをフロートして拡大する か、Vivadoウインドウを拡大して波形を見やすくす る ● Nameペインで右クリックし、右クリックメニューから Select Allを選択 ● 選択部分を右クリックし、右クリックメニューから Radix -> Unsigned Decimal を選択 ● これで10進数で表示される
  114. 114. 114 Vivadoを起動して波形を確認3 ● 通常のディスプレイ・コントローラと同じ信号
  115. 115. 115 実機を使用した確認 ● 実機を使用した確認は勉強会ではやりません ● 実機でのテスト方法は以下のFPGAの部屋のブロ グを参照下さい – http://marsee101.blog19.fc2.com/blog-entry-3174.ht ml – http://marsee101.blog19.fc2.com/blog-entry-3175.ht ml ● display_cont_subのap_ctrl_hsをap_ctrl_noneに 戻して、合成を行ってください
  116. 116. 116 まとめ1 ● 掛け算回路の出力にレジスタを挿入する – ディレクティブを変更し、高位合成 ● INTERFACEディレクティブregisterオプション – C/RTLコシミュレーションを行い波形を観察する ● 掛け算回路の入力にレジスタを挿入する – ディレクティブを変更し、高位合成 ● INTERFACEディレクティブregisterオプション – C/RTLコシミュレーションを行い波形を観察する ● PIPELINEディレクティブを挿入する – ディレクティブを変更し、高位合成 – C/RTLコシミュレーションを行い波形を観察する
  117. 117. 117 まとめ2 ● 補足(応用例) – ディスプレイ・コントローラの作製 ● PIPELINEディレクティブのrewindオプション ● for () ループが続く場合に初期化のステートに行かない ● ディスプレイのタイミングが狂わない
  118. 118. 118 ディレクティブをディレクティブ・ファイル に保存 ● 今まではディレクティ ブをソースコードに pragmaとして入れて いたが、ディレクティ ブ・ファイルにする方 法もある ● Vivado HLS Directive Editorの Destinationで Directive Fileを選択 する
  119. 119. 119 ディレクティブをディレクティブ・ファイル に保存するメリットとデメリット ● メリット – 新しいSolutionを作った時にディレクティブも変更できる ● デメリット – ソースコードのファイルだけではなくディレクティブ・ファ イルも必要になる
  120. 120. 120 ディレクティブをディレクティブ・ファイル に保存する例 ● Solution1 - ディレクティブはなし
  121. 121. 121 ディレクティブをディレクティブ・ファイル に保存する例 ● Solution2 - ディレクティブあり
  122. 122. 122 ディレクティブ・ファイル ● solution_フォルダのdirective.tclファイル
  123. 123. 123 directive.tclの内容 ############################################################ ## This file is generated automatically by Vivado HLS. ## Please DO NOT edit it. ## Copyright (C) 2015 Xilinx Inc. All rights reserved. ############################################################ set_directive_interface -mode ap_none "multi_apuint" multi_out
  124. 124. 124 Solutionの切替方法 ● Vivado HLSの左端のExplorerのsolutionを右ク リックして、Set Active Solutionを選択する
  125. 125. 125 参考文献 ● Vivado Design Suite ユーザー ガイド 高位合成 UG902 (v2014.3) 2014 年 10 月 1 日 – http://japan.xilinx.com/support/documentation/sw_m anuals_j/xilinx2014_4/ug902-vivado-high-level-synt hesis.pdf ● Vivado Design Suite ユーザー ガイド 高位合成 UG902 (v2015.3) 2015 年 9 月 30 日 – http://japan.xilinx.com/support/documentation/sw_m anuals_j/xilinx2015_3/ug902-vivado-high-level-synt hesis.pdf –

×