AXI4 バースト ビヘイビアーを制御するオプション - 2023.2 日本語

Vitis 高位合成ユーザー ガイド (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 日本語

最適な AXI4 インターフェイスとは、バスへのアクセス待機中にデザインが停止せず、バス アクセスが承認された後の読み出し/書き込み待機中にバスが停止しないようなインターフェイスです。次に示すように、システム パフォーマンスおよびバースト転送に影響を与える要素は多くあります。

  • レイテンシ
  • ポート幅
  • 複数ポート
  • 指定したバースト長
  • 未処理の読み出し/書き込み数

レイテンシ

読み出しレイテンシは、バースト読み出し要求をカーネルがバースト内の最初の読み出し要求からデータを受信するまでにかかる時間として定義されます。同様に、書き込みレイテンシとは、バーストの最後の書き込みデータが送信されてから、書き込み応答がカーネルで受信されるまでの時間です。これらのレイテンシは、DDR メモリ アクセスの密集などのシステム特性に依存するため、確定的ではありません。HLS コンパイラは合成中のメモリの読み出し/書き込みレイテンシを正確に決定できないので、デフォルト レイテンシの 64 カーネル サイクルを使用して、次のように要求と動作をスケジュールします。

  • 読み出し/書き込み要求をスケジュールし、データを待機します。同時に、ストリームや計算など、メモリに依存しない操作を実行します。
  • 新しい読み出し/書き込み要求をスケジュールするまで待ちます。
ヒント: デフォルトのツール レイテンシは、LATENCY プラグマまたは指示子を使用して変更できます。特定のインターフェイスのデフォルトの待ち時間は、INTERFACE プラグマまたは指示子の latency オプションを使って変更できます。

システムに存在するさまざまなレイテンシを理解しやすくするため、次の図に HLS カーネルが DDR メモリにバーストを送信すると何が起こるかを示します。

図 1. バースト トランザクションの図

読み出しまたは書き込み要求があると、その要求は複数の特殊なヘルパー モジュールを介して DDR メモリに送信されます。まず、m_axi アダプターが HLS カーネルにより作成された要求のバッファーとして動作します。アダプターは、大きなバーストを小さくカットするロジックを含みます。これは、チャネルを占有しないようにするため、または要求が 4 KB の境界を越える場合に実行する必要があります。詳細は、 『Vivado Design Suite: AXI リファレンス ガイド』 (UG1037) を参照してください。

デフォルトでは、アダプターは、各カーネルのデータ全体を安全にバッファリングできるように、すべてのデータが使用可能になるまで (最大未処理要求パラメーターによる)、バースト要求の送信をストールします 。これは、メモリ サブシステム上での同時要求 (読み出しまたは書き込み) によるデッドロックを減らすために実行されますが、書き込みレイテンシを増加させる可能性があります。インターフェイス コンフィギュレーション で説明されるように、syn.interface.m_axi_conservative_mode=false を設定することで、この書き込み要求のホールドを無効にできまうが、デッドロックのリスクは高まります。

アダプターを介すると、レイテンシのサイクル数が通常 5 ~ 7 サイクル増加します。その後、要求が AXI インターコネクトに送信され、カーネル要求が MIG に送信されてから、最終的に DDR メモリに送信されます。インターコネクトを介すると、レイテンシが長くなり、30 サイクルほどかかることがあります。DDR に到達してから戻るのには、9 ~ 14 サイクルほどかかる可能性があります。これらは正確に測定されたレイテンシではなく、これらの特殊なモジュールの相対的なレイテンシ コストを示すための見積もりです。AXI パフォーマンスのケース スタディ に説明するように、より正確なレイテンシ値を取得するには、テストを実行して、特定のシステムのアプリケーション タイムライン レポートを確認します。
ヒント: アプリケーション タイムライン レポートの詳細は、 『Vitis 統合ソフトウェア プラットフォームの資料』タイムライン トレース を参照してください。

システム内のレイテンシを確認するには、次の方法もあります。たとえば、インターコネクトの平均 II が 2 で、要求時の DDR メモリ コントローラーの平均 II が 4 ~ 5 サイクルだとします (データ上は両方とも II=1)。インターコネクト アービトレーション ストラテジは、読み出し/書き込み要求のサイズに基いており、長いバーストで要求されたデータの方が短いバーストで要求されたものよりも優先されるので、競合があった場合に広いチャネル帯域幅が長いバーストに割り当てられます。バースト要求が大きいと、ほかのものが DDR メモリにアクセスできないという影響があるので、バースト長と DDR ポート競合の削減とのバランスを取る必要があります。レイテンシを長くするとこのポート競合の一部が発生しなくなり、要求を効率的にパイプライン処理することでシステムの帯域幅スループットを改善できます。

バーストは 1 つの要求で最大サイズを要求するため、レイテンシはパイプライン バーストを使用するループ/関数には影響しません。

レイテンシは、次の 2 つの方法でシーケンシャル バーストを使用するループ/関数に影響します。

  • システムの読み出し/書き込みレイテンシがデフォルトのツール レイテンシよりも長い場合、Vitis HLS はデータを待機する必要があります。レイテンシを変更しても、システムのパフォーマンスは向上しません。
  • 読み出し/書き込みレイテンシがツールのデフォルトよりも短い場合、Vitis HLS はアイドル状態になり、残りのカーネル サイクルは無駄になります。このアイドル状態ではタスクが実行されないため、デザインのパフォーマンスに影響を与える可能性があります。次の図に示すように、システム レイテンシとデフォルト レイテンシのパラメーターの差によって、シーケンシャル要求がさらに遅延するようになります。これにより、スループットが大幅に低下します。
図 2. デフォルトのツール レイテンシ

ただし、LATENCY プラグマまたは指示子を使用してツールのレイテンシを短かくすると、次の図に示すように、シーケンシャル バーストの要求を密にパックします。

図 3. 調整後のツール レイテンシ

ポート幅

load-store 関数のスループットは、転送されるバイト数を最大化すると、さらに向上できます。Vitis Unified IDE および v++ では最大 1024 ビット幅のカーネル ポートがサポートされるので、カーネルはポートごとに各クロック サイクルで 128 バイトまで読み出しまたは書き込みできます。

また、Vitis HLS はソース コードのメモリ アクセス パターンを解析することで、ポート幅の自動最適化もサポートします。コードがバースト アクセスの前提条件と制限を満たしている場合、Vitis カーネル フローのポートのサイズは自動的に 512 ビット幅に変更されます。

重要: コンパイル時にサイズと反復回数が可変になっていると、ポート幅は自動的には大きくなりません。

ポート幅を自動的に大きくできない場合は、ベクター データ型 または 任意精度 (AP) 型 をポートのデータ型として使用すると、ポート幅を手動で変更できます。

複数のポートとチャネル

load-store 関数のスループットは、同時読み出し/書き込みを最大にすると、さらに向上できます。Vitis HLS では、関数の引数はデフォルトで単一のポートにバンドル/マップ/グループ化されます。ポートを 1 つのポートにバンドルすることで、リソースの節約に役立ちます。ただし、すべてのメモリ転送が 1 つのポートを通ることになるので、1 つのポートにより、カーネルのパフォーマンスが制限されてしまうことがあります。m_axi インターフェイスには独立した READ チャネルと WRITE チャネルがあるので、1 つのポートで読み出しと書き込みを同時に実行できます。 M_AXI チャネル で説明されるように、m_axi インターフェイスもまた、1 つのポートにチャネルを提供し、ポートの読み出しチャネルと書き込みチャネルを増やします。

複数ポートを使用すると、「マルチ DDR チュートリアル」に示すように、複数のインターフェイスを作成して異なるメモリ バンクに接続することで、カーネルの帯域幅とスループットを向上できます。こうしない場合、アクセスはシーケンシャルになります。複数の引数が同じメモリ ポートまたはメモリ バンクにアクセスする場合、アービタにより、同じメモリ ポートまたはバンクへのこれらの同時アクセスが順番付けされます。複数ポートを異なるメモリ バンクに接続すると、ロードおよびストア関数のスループットが向上します。その結果、ロードおよびストア関数からのスループット要求に合わせて、計算ブロックも均等にスケーリングする必要があります。そうしないと、load-store 関数にバック プレッシャーまたはストールが発生します。

未処理の読み出し/書き込み数

load-store 関数のスループットは、システムがレイテンシの一部を隠すことができるようにすることで、さらに向上できます。config_interface コマンドまたは INTERFACE プラグマまたは指示子に m_axi_num_read_outstanding または m_axi_num_write_outstanding オプションを使用すると、カーネルは、前回の要求が完了するのを待たずに、グローバル メモリに送信されるパイプライン処理されるメモリ要求の数を制御できます。

パイプライン処理される要求の数を増やすと、読み出し/書き込み要求のパイプラインの深さが増加し、追加の BRAM/URAM リソースが必要になります。

注記: ほとんどの場合、バースト長が 16 以上なので、デフォルトの未処理の読み出し/書き込み数で十分です。バースト サイズが 16 未満の場合、AMDではデフォルトの 16 から未処理数のサイズを 2 倍にすることをお勧めします。

INTERFACE プラグマを使用したバースト属性の定義

最適な AXI4 インターフェイスを作成するには、INTERFACE 指示子に次のコマンドオプションを使用して、バースト ビヘイビアーを指定し、AXI4 インターフェイスの効率を改善します。

これらのオプションの中には、内部ストレージを使用してデータをバッファリングすることがあるので、エリアおよびリソースへの影響があるものもあります。

latency
AXI4 インターフェイスのレイテンシを指定して、読み出しまたは書き込みの前にバスが複数サイクル (レイテンシ) の要求を送信するようにできます。このレイテンシ値が小さすぎると、デザインが準備完了になるのが早すぎ、バスを待つために停止する可能性があります。レイテンシ値が大きすぎると、バス アクセスは承認されても、デザインがアクセスを開始するのを待つためにバスが停止する可能性があります。Vitis HLS のデフォルト レイテンシは 64 です。
max_read_burst_length
バースト転送中に読み出されるデータ値の最大数を指定します。デフォルト値は 16 です。
num_read_outstanding
デザインが停止する前に、AXI4 バスに対して応答なしで送信できる読み出し要求の数を指定します。これにより、デザインの内部ストレージである FIFO のサイズ (num_read_outstanding*max_read_burst_length*word_size) が決まります。デフォルト値は 16 です。
max_write_burst_length
バースト転送中に書き込まれるデータ値の最大数を指定します。デフォルト値は 16 です。
num_write_outstanding
デザインが停止する前に、応答なしで AXI4 バスに何回書き込み要求を送信できるかを指定します。これにより、デザインの内部ストレージである FIFO のサイズ (num_write_outstanding*max_write_burst_length*word_size) が決まります。デフォルト値は 16 です。
次は、これらのオプションを使用した INTERFACE プラグマの例です。
#pragma HLS interface mode=m_axi port=input offset=slave bundle=gmem0         
depth=1024*1024*16/(512/8) latency=100 num_read_outstanding=32 num_write_outstanding=32 
max_read_burst_length=16 max_write_burst_length=16
  • インターフェイスは、レイテンシ 100 になるように指定されています。HLS コンパイラは、デザインが AXI4 バスにアクセスできるようになる 100 クロック サイクル前に、バースト アクセス要求をスケジューリングしようとします。
  • バスの効率をさらに向上するには、num_write_outstanding および num_read_outstanding オプションを使用して、デザインに最大 32 個の読み出しおよび/書き込みバーストを格納できるバッファー容量が含まれるようにします。要求ごとにバッファーが必要になります。これで、バス要求が送信されるまでデザインの処理を続行できるようになります。
  • 最後に、max_read_burst_length および max_write_burst_length オプションを使用することで、最大バースト サイズが 16 になり、AXI4 インターフェイスがそれを超える時間バスを保持しないようにします。HLS ツールは、指定されたバースト長に従って長いバーストを分割し、次のようなメッセージでこの状態をレポートします。
    Multiple burst reads of length 192 and bit width 128 in loop 'VITIS_LOOP_2'(./src/filter.cpp:247:21)has been inferred on port 'mm_read'.
    These burst requests might be further partitioned into multiple requests during RTL generation based on the max_read_burst_length settings.

バーストを設定するコマンド

これらのコマンドは、動作するシステムの AXI4 インターフェイスを最適化するグローバル設定をコンフィギュレーションします。動作の効率は、これらの値が正しく設定されているかどうかによって異なります。デフォルト値が控えめな値であるため、デザインのメモリ アクセス プロファイルによっては変更が必要な場合があります。

表 1. Vitis HLS の制御
Vitis HLS コマンド [Value] 説明
syn.interface.m_axi_conservative_mode bool

デフォルト= true

書き込みデータがすべて揃うまで (通常はアダプターに格納されるか、既に発行済み)、書き込み要求ごとに M-AXI が遅延されます。これにより書き込みレイテンシが多少長くなりますが、メモリ サブシステムに対する同時要求 (読み出しまたは書き込み) により発生するデッドロックを解決できます。
syn.interface.m_axi_latency uint

0 は auto

Vivado IP フローのデフォルトは 0

Vitis カーネル フローのデフォルトは 64

M-AXI アクセスの予測レイテンシを含めてスケジューラに表示します。レイテンシは、読み出し要求と最初の読み出しデータ間、または最後の書き込みデータと書き込み応答間の遅延です。この数値は正確である必要はありません。過小評価するとレイテンシの短いスケジューリングができますが、ダイナミックな停止が長くなる点に注意してください。スケジューラは、追加のアダプター レイテンシを把握して、数サイクル追加します。
syn.interface.m_axi_min_bitwidth uint

デフォルト = 8

M-AXI インターフェイスのデータ チャネルの最小ビット幅。8 ~ 1024 の 2 のべき乗を指定する必要があります。実際のアクセスが必要なインターフェイスよりも少ない場合は、このオプションでスループットが必ずしも大きくなるわけではありません。
syn.interface.m_axi_max_bitwidth uint

デフォルト = 1024

M-AXI インターフェイスのデータ チャネルの最小ビット幅。8 ~ 1024 の 2 のべき乗を指定する必要があります。実際のアクセスが必要なインターフェイスよりも多い場合、アクセスがマルチサイクル バーストに分割されるので、スループットが落ちます。
syn.interface.m_axi_max_widen_bitwidth uint

Vivado IP フローのデフォルトは 0

Vitis カーネル フローのデフォルトは 512

M-AXI インターフェイスのバーストを選択した幅まで自動的に広げるようになります。8 ~ 1024 の 2 のべき乗を指定する必要があります。バースト幅を広げる場合は、バーストだけでなく、強力なアライメント プロパティが必要となります。
syn.interface.m_axi_auto_max_ports bool

デフォルト = false

オプションが false の場合、明示的にバンドルされていない M-AXI インターフェイスすべてが 1 つの共通のインターフェイスにまとめられるので、リソース使用量が少なくなります (アダプターは 1 つ)。オプションが true の場合、明示的にバンドルされていない M-AXI インターフェイスはすべて個別のインターフェイスにマップされるので、リソース使用量が増加します (アダプターは複数)。
syn.interface.m_axi_alignment_byte_size uint

Vivado IP フローのデフォルトは 1

Vitis カーネル フローのデフォルトは 64

M-AXI インターフェイスにマップされる最上位関数ポインターが少なくとも指定したバイト幅 (2 のべき乗) に揃えられるとするとします。これにより、自動バースト幅拡張が実行されやすくなります。警告: ポインターがランタイムにアライメントされない場合、動作が正しくなくなります。
syn.interface.m_axi_num_read_outstanding uint

デフォルト = 16

M-AXI インターフェイスの num_read_outstanding パラメーターのデフォルト値。
syn.interface.m_axi_num_write_outstanding uint

デフォルト = 16

M-AXI インターフェイスの num_write_outstanding パラメーターのデフォルト値。
syn.interface.m_axi_max_read_burst_length uint

デフォルト = 16

M-AXI インターフェイスの max_read_burst_length パラメーターのデフォルト値。
syn.interface.m_axi_max_write_burst_length uint

デフォルト = 16

M-AXI インターフェイスの max_write_burst_length パラメーターのデフォルト値。