ハードウェア エミュレーション中に 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 カーネル間のトラフィックを確認できます。
関数モデルを使用した 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 を参照してください。
関数モデルの制限
- 関数モードは Windows OS ではサポートされません。
- HLS の制限は、現状のままで適用されます。たとえば、HLS はダブル ポインターをサポートしていないので、関数モデルはそれを識別しません。
- 単一のカーネル
ap_start
でホストから複数のデータを反復して動作する HLS デザイン (たとえば、ap_ctrl_chain
) は、カーネル コードから再起動がトリガーされると動作しない場合があります。メールボックスは正常に動作します。 - FPGA 用のアプリケーション バイナリ インターフェイス (ABI) は、Functional Mode x86 ABI では変更できません。ABI が使用されるほとんどの最適化では、関数コンパイラで無効にする必要があります。
-
型変換/手続き型間の使用による DDR 解析の制限は、次のとおりです。
-
スカラーからの 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]; } }
-
手続き型のコンテキストにまたがる 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]; } }
-
- バイナリでインプリメントされ、DDR メモリ アクセスを消費する HLS 機能はサポートされておらず、関数の書き換えが必要です。
- 関数モデルでは、バースト トランザクションは自動的に検出されません。
関数型モデルを扱うためのコーディング ガイドライン: 複数回実行され、スタティック値が各反復で 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;
...
}