HLS カーネルの関数モデルの使用 - 2023.2 日本語

Vitis 統合ソフトウェア プラットフォームの資料: アプリケーション アクセラレーション開発 (UG1393)

Document ID
UG1393
Release Date
2023-12-13
Version
2023.2 日本語

ハードウェア エミュレーション中に AMD Vitis™ HLS カーネルの関数モデルを使用するのは、関数モードでカーネルをコンパイルできる高度なユース ケースで、C コードを囲む SystemC ラッパーを使用して XO を生成できます。IP は、HLS コンパイラによって生成されたかどうかに関係なく、allowed_sim_models プロパティで示されるように、TLM や RTL など、複数のタイプのシミュレーション モデルを持つことができます。ただし、IP は、これらのモデルのどれが selected_sim_model プロパティによって定義される現在のモデルであるかを示す必要があります。ここで説明する方法では、HLS コンパイラが出力 IP または XO を生成する際に、どのタイプのシム モデルを選択するかを指定できます。

ハードウェア エミュレーションの主なターゲットは、カーネル アクティビティの詳細なサイクル精度のビューを持つハードウェア カーネルのデバッグです。関数 (TLM) モデルは、対象のカーネルを RTL コードとしてではなく、関数モードでコンパイルすることにより、エミュレーションを高速化します。RTL がまだない場合は早期モデルとして使用できます。これにより、C から RTL へのフル合成を必要としないため、カーネルのコンパイル時間が短縮されるほか、RTL シミュレーションの代わりに C コードがシミュレーションされるため、実行時間も短縮されます。また、ハードウェア エミュレーションで C および RTL カーネルを組み合わせて、RTL ブロックのデバッグを速くすることもできます。

関数モード機能では、AXI4-Stream インターフェイス (axis) と AXI4 メモリ マップド インターフェイス (m_axi) の両方のモデリング、および AXI4-Lite (s_axilite) インターフェイスのレジスタの読み出しと書き込のモデリングがサポートされます。ただし、このアプローチを使用すると、サイクル精度のモデルとは異なり、カーネルはレイテンシ情報なしで純粋に機能します。

ユーザー HLS 関数は、TLM インターフェイスを備えた SystemC モジュールにラップされ、生成されたコードから IP が作成されます。これにより、IP インテグレーターで使用可能な HW_EMU 互換の XO が生成でき、ハードウェア エミュレーション フローで v++ リンク デザインを合わせるために使用できます。これにより、ラッパー IP がほかの RTL および SystemC モデルと通信することもできます。このため、関数モードでコンパイルされた HLS C/C++ カーネルはシミュレーション中に TLM トランザクションを持つので、ユーザーがメモリ モデル (例: DDR メモリ) と TLM カーネル間のトラフィックを確認できます。

ヒント: 関数モデルは、カーネルの C シミュレーションを実行する C コードを使用します。カーネルは、サイクル精度のモデルとは異なり、レイテンシ情報なしで純粋に機能します。ただし、ハードウェア エミュレーション中は、境界トランザクションを TLM インターフェイスを使用して確認できます。

関数モデルを使用した XO 生成

重要: v++ -c --mode hls コマンドは、次で説明する関数シミュレーション モデルをサポートしません。TLM モデルを関数シミュレーションに使用するために IP またはカーネルを生成するには、v++ -c -t=hw_emu を使用する必要があります。

v++ -c -t=hw_emu コンパイル段階では、ハードウェア エミュレーション (hw_emu) の XO ファイルの作成中に、PL カーネルの関数シミュレーション モデルを有効にするオプションを指定すると、C コードで SystemC ラッパーを使用して XO が生成されます。--advanced オプション で説明するように、コンパイル時に --advanced.param compiler.emulationMode=func オプションを指定する必要があります。

このデフォルト設定は compiler.emulationMode=rtl です。XO をビルドする際に、--advanced.param compiler.emulationMode=rtl を使用してデフォルト値を指定することで、特定の XO の RTL モデルと TLM モデルを簡単に切り替えることができます。また、--advanced_param コマンドを削除してデフォルト値を復元し、関数シミュレーション用にビルドする際に追加し直すこともできます。どちらの場合でも、モデルを RTL から TLM に変更したり戻したりする場合は、v++ -c -t=hw_emu コマンドを使用して XO を再コンパイルする必要があります。

生成された関数シミュレーションの XO は、通常の XO のように v++ --link コマンドを使用するとリンクされます。例として、GitHub の mm_stream_func_mode を参照してください。

関数モデルの制限

  1. 関数モードは Windows OS ではサポートされません。
  2. HLS の制限は、現状のままで適用されます。たとえば、HLS はダブル ポインターをサポートしていないので、関数モデルはそれを識別しません。
  3. 単一のカーネル ap_start でホストから複数のデータを反復して動作する HLS デザイン (たとえば、 ap_ctrl_chain) は、カーネル コードから再起動がトリガーされると動作しない場合があります。メールボックスは正常に動作します。
  4. FPGA 用のアプリケーション バイナリ インターフェイス (ABI) は、Functional Mode x86 ABI では変更できません。ABI が使用されるほとんどの最適化では、関数コンパイラで無効にする必要があります。
  5. 型変換/手続き型間の使用による DDR 解析の制限は、次のとおりです。

    1. スカラーからの DDR メモリ ポインターの型変換は機能しません。
      kernel void vadd(size_t a_s,size_t b_s,size_t c){
       int* a = (size_t)a;
       int* b = (size_t)b;
       int* c = (size_t)c;
       for(int i=0; i < 64; i++){
       c[i] = a[i] + b[i]; 
       } 
      }
    2. 手続き型のコンテキストにまたがる DDR メモリ ポインターのキャッシュは機能しません。
      class Cache{
      int* local;
      Cache(int *a) : local(a){}
      int read(){}
      void write(int x){}
      };
      kernel void vadd(int *a,int *b, int *c){
       Cache ca(a);
       for(int i=0; i < 64; i++){
       c[i] = ca.read() + b[i]; 
       } 
      }
  6. バイナリでインプリメントされ、DDR メモリ アクセスを消費する HLS 機能はサポートされておらず、関数の書き換えが必要です。
  7. 関数モデルでは、バースト トランザクションは自動的に検出されません。

関数型モデルを扱うためのコーディング ガイドライン: 複数回実行され、スタティック値が各反復で 0 にリセットされるカーネル演算ユニットでは、カーネル関数のエントリですべてのスタティック変数を初期化する必要があります。次の例は、エラーを返すコードを示しており、推奨される方法も示しています。

// User code that errors out 
static int i = 0;
void hls_kernel_logic(...) {
 ...
}
// Recommended 
static int i = 0;
void hls_kernel_logic(...) {
 i = 0;
 ...
}