実践的!FPGA開発セミナー vol.17 (2022/12/22)

878 Views

December 22, 22

スライド概要

フィックスターズならではの「FPGA」に関する高速化手法、効率的な開発ノウハウ、苦労話などについてお話しいたします。


<講演内容>

1.本講演~Intel HLS を利用したモジュール開発~
Intel HLS は Intel Quartus Prime で無償利用可能な高位合成ツールです。
高位合成が普及している中、Intel FPGA ユーザーであれば適用を検討するべきツールですが、まだ公開事例を見かけることが少ない状況です。
今回のセミナーでは、基本的な使い方や特徴、Xilinx Vivado/Vitis HLS との違い、モジュール開発時のハマりポイントや注意点などをお話します。

2.Lightning Talk!
1、Vitis HLS 2022.1 で追加された performance pragma を使ってみる
2、格安FPGAボード Tang Nano 9Kで試すFPGA Ethernet通信


・当社技術ブログ 記事: https://proc-cpuinfo.fixstars.com/

・フィックスターズグループ/セミナー一覧: https://www.fixstars.com/ja/seminar

・フィックスターズのFPGAシステム開発: https://www.fixstars.com/ja/services/fpga

profile-image

フィックスターズは、コンピュータの性能を最大限に引き出すソフトウェア開発のスペシャリストです。車載、産業機器、金融、医療など、幅広い分野での開発経験があります。また、ディープラーニングや機械学習などの最先端技術にも力を入れています。 並列化や最適化技術を駆使して、マルチコアCPU、GPU、FPGA、量子アニーリングマシンなど、さまざまなハードウェアでソフトウェアを高速化するサービスを提供しています。さらに、長年の経験から培ったハードウェアの知識と最適化ノウハウを活かし、高精度で高性能なアルゴリズムの開発も行っています。       ・開催セミナー一覧:https://www.fixstars.com/ja/seminar   ・技術ブログ :https://proc-cpuinfo.fixstars.com/

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

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

2.

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

3.

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

4.

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

5.

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

6.

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

7.

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

8.

代表的な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 Copyright© Fixstars Group 8

9.
[beta]
Intel HLS について
● Intel FPGA の開発ツールQuartus Prime に含まれていて無償利用可能
○ /path/to/intelFPGA_pro/<version>/hls/bin/i++
○ i++ はg++ を模していて、ソースコードとオプションを指定すれば高位合成可能
■ Vitis HLS のプロジェクトベースで高位合成するスタイルとは異なる

● 下記のようなモジュールを実装するときのコードとコマンドを例示
○ unsigned int 8 bit x 8 のvector 同士の足し算をするモジュール
■ 入出力はAvalon-ST 64 bit 形式
Input A :{ 8, 7, 6, 5, 4, 3, 2, 1}
Input B :{16, 14, 12, 10, 8, 6, 4, 2}

vecadd

Copyright© Fixstars Group

Output :{24, 21, 18, 15, 12, 9, 6, 3}

9

10.

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

11.

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

12.

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

13.

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

14.

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

15.

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

16.

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

17.

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

18.

Lightning Talk! Copyright© Fixstars Group

19.

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

20.

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

21.

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

22.

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

23.

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

24.

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

25.

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

26.

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

27.

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

28.

実際に使ってみる: 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 Copyright© Fixstars Group

29.

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

30.

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

31.

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