Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実践的!FPGA開発セミナーvol.17 / FPGA_seminar_17_fixstars_corporation_20221222

fixstars
January 17, 2023

実践的!FPGA開発セミナーvol.17 / FPGA_seminar_17_fixstars_corporation_20221222

2022年12月22日に開催した、「実践的!FPGA開発セミナーvol.17」の当日資料です。

fixstars

January 17, 2023
Tweet

More Decks by fixstars

Other Decks in Programming

Transcript

  1. Copyright© Fixstars Group
    実践的!FPGA開発セミナー
    vol.17
    2022/12/22 18:00~

    View Slide

  2. Copyright© Fixstars Group
    Intel HLS を利用した
    モジュール開発

    View Slide

  3. Copyright© Fixstars Group
    Who I am
    写真
    Ryuji
    NISHIDA
    西田 竜之
    ソリューション第四事業部
    シニアエンジニア

    View Slide

  4. Copyright© Fixstars Group
    Who I am
    写真
    Eisuke
    MOCHIZUKI
    望月 英輔
    ソリューション第四事業部
    シニアエンジニア

    View Slide

  5. Copyright© Fixstars Group
    高位合成
    High-Level Synthesis
    高位合成(HLS) とは
    ● 高位合成(HLS) = C/C++ でFPGA の実装ができる?
    ○ ・・・正しいが、正確ではない
    C/C++ Code Verilog/VHDL Code FPGA Bitstream
    合成/配置配線
    Synthesis/Implement
    ● 高位合成(HLS) とはC/C++ からVerilog/VHDL を生成すること
    ○ HLS だけでFPGA の実装が完了することは稀である
    ○ Fixstars ではHLS はIP やモジュールの開発に使用し、トップレベルのデザインはVerilog や
    IP 結線を行うシステム構築ツール で実装することが多い
    Top Level (Verilog, IP Integrator)
    Module
    by HLS
    Module
    by Verilog
    Module
    by IP Catalog
    Module
    by HLS
    5

    View Slide

  6. Copyright© Fixstars Group
    HLS の原理的にしんどいところ
    ● 「C/C++ からVerilog/VHDL を生成する」
    ○ C/C++ : ソフトウェアを表現するための、逐次処理を記述する言語
    ○ Verilog/VHDL: ハードウェアを表現するための、並列処理を記述する言語
    ○ ・・・別のものを表現するために生まれた両者をつなぐのは原理的にしんどい
    ● しんどいが故に以下のようなことが起こりがち
    ○ 既存のC/C++ コードをそのまま持ってきても高位合成できない
    ■ 最近はこういうことを言う人は減ってきたかな
    ○ 高位合成はできたが、期待した性能に届かない
    ■ 書き方を工夫したり、pragma を活用しないと性能は出ないことが多いです
    ○ ソフトウェアエンジニアでも開発できると思ったのにやっぱりできない
    ■ 高位合成で加速するアクセラレータ開発 (2) ~ 高位合成と C ベース設計 1章 を読むと共感できます
    ● HLS は魔法のツールではない!
    6

    View Slide

  7. Copyright© Fixstars Group
    ではなぜわざわざHLS を使用するのか
    ● モジュール実装のTAT が大きく向上するから
    ○ C/C++ で実装するので、ソフトウェアベースでテストが可能
    ■ ハードウェアベースのテスト(Co-simulation)と比較して非常に短い時間で完了する
    ■ 機能面の抜け漏れや論理的なバグはこの段階で潰せる
    ○ 高位合成時にモジュール本体だけでなくテストもハードウェア化してくれる
    ■ Verilog/VHDL でテストを書き直す必要がない
    ■ ハードウェア化時に仕込まれたバグもここで弾くことができる
    ○ 汎用的なインターフェースのコード実装を省略できる
    ■ ハンドシェイクを行うインターフェースのRTL 実装は、テストを含め意外と面倒
    ● 時間のかかるFPGA 開発で、モジュール実装TAT の向上は非常に助かる
    ○ HLS で機能的には正しいことを(一応)保証してくれるので、性能向上に集中できる
    ○ Fixstars ではどうしても性能がでない場合を除き、ほとんどのモジュール開発でHLS を利用
    7

    View Slide

  8. Copyright© Fixstars Group
    代表的なHLS
    ● Vivado/Vitis HLS: 無償: 2013年~
    ○ AMD Xilinx が自社製品向けに提供しているHLS
    ○ Web 上にたくさん情報があり、Fixstars でもよく使用している
    ● Intel High-Level Synthesis: 無償: 2017年~
    ○ Intel FPGA が自社製品向けに提供しているHLS
    ○ Vivado/Vitis HLS と比較すると情報は少ないが、Fixstars では最近使用する機会が増えている
    ● その他 EDA ベンダ提供の HLS:有償
    ○ Catapult HLS (Siemense)
    ○ Stratus HLS (Cadence)
    ■ etc...
    ○ ASIC 業界での利用が多く、Fixstars での使用経験はほとんどない(はず)
    ● 本日はIntel HLS についてお話します。
    参考: https://en.wikipedia.org/wiki/High-level_synthesis
    8

    View Slide

  9. Copyright© Fixstars Group
    Output :{24, 21, 18, 15, 12, 9, 6, 3}
    Input A :{ 8, 7, 6, 5, 4, 3, 2, 1}
    Input B :{16, 14, 12, 10, 8, 6, 4, 2}
    ● Intel FPGA の開発ツールQuartus Prime に含まれていて無償利用可能
    ○ /path/to/intelFPGA_pro//hls/bin/i++
    ○ i++ はg++ を模していて、ソースコードとオプションを指定すれば高位合成可能
    ■ Vitis HLS のプロジェクトベースで高位合成するスタイルとは異なる
    ● 下記のようなモジュールを実装するときのコードとコマンドを例示
    ○ unsigned int 8 bit x 8 のvector 同士の足し算をするモジュール
    ■ 入出力はAvalon-ST 64 bit 形式
    Intel HLS について
    vecadd
    9

    View Slide

  10. Copyright© Fixstars Group
    Intel HLS 実装例
    モジュール本体
    モジュールのテストコード
    2 つの入力stream からデータ
    をread しa, b に格納
    下記を要素数分繰り返す
    データ内の各要素に対して
    加算を実行し、out に格納
    out に格納したデータを出力
    stream にwrite
    モジュールへのテストデータを生成
    入力データをコンソールに表示
    入力データを入力stream に格納
    モジュールを呼び出し
    出力データを出力streamからread
    出力データをコンソールに表示
    10
    vecadd.cpp
    vecadd_test.cpp

    View Slide

  11. Copyright© Fixstars Group
    Intel HLS 実行例
    11
    $ i++ vecadd.cpp vecadd_test.cpp -march=x86-64
    x86 emualtion: ソフトウェアベースでのテスト
    $ ./a.out
    a = 0, 1, 2, 3, 4, 5, 6, 7
    b = 0, 2, 4, 6, 8, 10, 12, 14
    out = 0, 3, 6, 9, 12, 15, 18, 21
    数秒でビルド完了 -> テストを実行
    1秒未満で実行完了
    実行結果に問題がなければCo-simulation へ ➚
    問題があれば修正、このTAT が短いことが利点
    $ i++ vecadd.cpp vecadd_test.cpp -march=Agilex -ghdl
    1分程度で高位合成完了 -> テストを実行
    $ ./a.out
    a = 0, 1, 2, 3, 4, 5, 6, 7
    b = 0, 2, 4, 6, 8, 10, 12, 14
    out = 0, 3, 6, 9, 12, 15, 18, 21
    1分程度でシミュレーション完了
    実行結果に問題がなければテストは完了
    x86 emulation はOK でもCo-simulation でNG の
    パターンもよくあるので注意
    Co-simulation: ハードウェアベースでのテスト
    モジュールコード テストコード x86 emulation を指定 モジュールコード テストコード Co-simulation 実行の
    ためにデバイスを指定
    テスト時の
    波形を保存

    View Slide

  12. Copyright© Fixstars Group
    Intel HLS のレポート、シミュレーション波形
    12
    $ firefox ./a.prj/reports/report.html
    高位合成レポートはHTML 形式で出力される
    $ vsim ./a.prj/verification/vsim.wlf
    シミュレーション波形は下記コマンドで確認可能
    性能面に問題があればコードを修正 & テスト
    - レイテンシ : レポートのレイテンシサイクル数を確認
    - スループット: レポートのII(Initiation Interval) を確認
    レポートだけでは分からないことは波形で確認
    - モジュール起動までサイクル数
    - モジュールを複数回連続実行したときのII

    View Slide

  13. Copyright© Fixstars Group
    AMD Xilinx Vivado/Vitis HLS との違い
    ● 細かい記述方法の差はあるが、大きくは変わらないと考えてよい
    ○ あえて挙げるとすれば下記となる
    ● 両社とも、自社製品以外でのそれぞれのHLS の利用を許可していないので、
    開発対象デバイス次第でどちらを利用するか決まる
    ○ どちらかに触れたことがあれば、大きな違和感なく開発が行えるはず
    13
    項目 Intel HLS Vivado/Vitis HLS コメント
    高位合成用の
    プロジェクト
    不要 必要 Git 管理するときはプロジェクト不要の方が嬉しいが、
    決定的な差ではない
    標準バス Avalon AXI 共にMM, Stream があり、Quartus, Vivado との連携良好
    性能の最適化 プラグマなしでも、ある程度最適化 プラグマで都度指示 最終的には両者ともプラグマで指示をすることになる
    * プラグマ: 高位合成時の指示のこと 性能チューニング時に多用する

    View Slide

  14. Copyright© Fixstars Group
    小ネタ: 開発時にハマったこと
    ● Stream で入力されるパケットから固定長のHeader を取り除き、
    Body だけを出力するモジュールをIntel HLS で開発
    ● 性能面の要求として、100 Gbps 以上のスループットが求められる
    ○ Stream を512 bit 幅とし、モジュールを250 MHz かつII=1 で動作させようと考えた
    ■ 512 bit * 250 MHz / 1 = 128 Gbps
    ● 簡単そうに見えるが、実は少しむずかしい
    14
    Header Body
    14 Byte N Byte (N ≧ 46)
    Body
    N Byte (N ≧ 46)
    Module X
    by Intel HLS
    * II: Initiation interval,
    II=1 だと、Stream を連続入力して処理できる

    View Slide

  15. Copyright© Fixstars Group
    小ネタ: 開発時にハマったこと
    ● Stream の幅(512 bit=64 Byte) の関係で、Body Size で場合分けが発生する
    ○ 可変長の長さのパケットは、64 Byte 単位で切られて入出力され、
    入力と出力でStream の切れ目が異なることに注意(下図の点線)
    15
    出力0は、入力0,1 が入ってからでないと出力できない
    出力1は、入力2が入ったら出力できる
    出力2は、入力3が入ったら出力できる
    入力
    出力
    0 1 2 3
    0 1 2 3
    入力
    出力
    0 1 2 3
    0 1 2
    出力0は、入力0,1 が入ってからでないと出力できない
    出力1は、入力2が入ったら出力できる
    出力2, 3 は、入力3が入ったときに連続して出力する必要がある
    Pattern A Pattern B
    この実装が大変だった

    View Slide

  16. Copyright© Fixstars Group
    小ネタ: 開発時にハマったこと
    ● 最後の連続出力を記載すると、II=1がどうしても達成できない
    ○ Intel HLS の特性なのか、同一の出力ポートへのwrite が2行あると、II=2 になるようだ
    ● どうしたか? -> 出力ポートを2つに増やした
    ○ 異なるポートへのwrite であれば、2行書いてもII=1 になった
    ○ 後段にMerge module を追加したが、これはHLS でII=1 で問題なく記述することができた
    ● よりスマートな方法があるかもしれないので、情報提供お願いします🙇
    16
    Module X
    by Intel HLS
    入力 通常の出力
    最後の一回専用の出力
    Merge module
    by Intel HLS
    出力

    View Slide

  17. Copyright© Fixstars Group
    まとめ
    ● HLS を利用することで、モジュール実装TAT の向上が見込める
    ● Intel HLS の実装/実行は、お作法さえ理解できれば容易
    ● Vivado/Vitis HLS と比較して、記述方法, 使い方に極端な差は無い
    ● Intel FPGA ユーザーでしたら一度は触ってみてください
    17

    View Slide

  18. Copyright© Fixstars Group
    Lightning Talk!

    View Slide

  19. Copyright© Fixstars Group
    Who I am
    写真
    Yuki
    MATSUDA
    松田 裕貴
    ソリューション第四事業部
    リードエンジニア

    View Slide

  20. Copyright© Fixstars Group
    Vitis HLS 2022.1 で追加され
    た performance pragma を使
    ってみる

    View Slide

  21. Copyright© Fixstars Group
    目標性能 (サイクル数) を指示することで自動で最適化を行ってくれる pragma
    Performance pragma とは
    https://docs.xilinx.com/r/ja-JP/ug1399-vitis-hls/pragma-HLS-performance

    View Slide

  22. Copyright© Fixstars Group
    Performance pragma の使い方
    https://docs.xilinx.com/r/ja-JP/ug1399-vitis-hls/pragma-HLS-performance
    ● 構文: #pragma HLS performance target_ti=N
    ● ドキュメントのコード例で解説
    ○ i ループが 1000 cycle で終わるように制約する
    ○ j ループの unrolling や b の array_partition が自動で適用される

    View Slide

  23. Copyright© Fixstars Group
    実際に使ってみる: vecadd
    ● まずはシンプルに vecadd。入出力のIF は AXI MM
    ● レポート上で Performance Pragma の目標値を達成できたかを確認できる
    ● シンプルな例なのに ti=1024 (II=1) を達成できず
    => AXI MM が 1port しかなく、 a, b の読み出しに 2サイクルかかるため

    View Slide

  24. Copyright© Fixstars Group
    実際に使ってみる: vecadd (cont.)
    ● 明示的に m_axi の読み出しポートを 2個にする => ti=1024 を達成
    ● 流石にインターフェースに対する制約までは自動で書き換えないので、
    この辺りは自分で適切に設定する必要がある模様

    View Slide

  25. Copyright© Fixstars Group
    実際に使ってみる: vecadd (cont.)
    ● 更に target_ti = 512 に減らせるか? (unroll=2 相当)
    ○ pragma の値を変えただけだと失敗 (左)
    ○ ちゃんと入出力のポート幅を増やせば成功 (右)
    ● やはり入出力までは自分で正しく設計する必要あり
    失敗 成功

    View Slide

  26. Copyright© Fixstars Group
    実際に使ってみる: matmul
    ● インターフェース部分までは設計した上で、
    演算ロジックをどこまでチューニングしてくれるかを確認してみる
    ● 入力データを予めローカル SRAM にキャッシュし、
    それを用いて計算を行う
    行列積の計算部分
    ローカル SRAM への copy を含む top 定義

    View Slide

  27. Copyright© Fixstars Group
    実際に使ってみる: matmul (32並列)
    ● (32, 32) x (32, 32) の行列積を 1024 cycle で終わるように制約した場合
    (unroll=32)
    ● => 成功

    View Slide

  28. Copyright© Fixstars Group
    実際に使ってみる: matmul (32並列, cont.)
    ● どんな回路が生成されているのか? => レポートに記載があった
    ● b を cyclic にしているので j ループを展開していそうに見えるが詳細は不明
    https://docs.xilinx.com/r/ja-JP/ug1399-vitis-hls/%E9%85%8D%E5%88%97%E3%81%AE%E5%88%86%E5%89%B2

    View Slide

  29. Copyright© Fixstars Group
    実際に使ってみる: matmul (1024並列)
    ● (32, 32) x (32, 32) の行列積を 32 cycle で終わるように制約した場合
    (unroll=1024)
    ● => これも成功。a, b, c それぞれに array_partition を適用している

    View Slide

  30. Copyright© Fixstars Group
    まとめ
    ● performance プラグマを試してみた
    ● interface 部分は最適化対象外なので、そこは手動で設計が必要
    ● array_partition 等の自動推論部分は優秀で、
    行列積くらいなら良い感じに制約をかけてくれる
    ○ ただし、その制約が最適なのかどうかは確認した方が良さそう
    ● とりあえず performance プラグマを使用してみて、
    良い回路が出ない場合は手動で制約をかけるような形が有用と思われる

    View Slide

  31. Copyright © Fixstars Group
    Thank you!
    お問い合わせ窓口 : [email protected]

    View Slide