インテル®高位合成 (HLS) コンパイラー プロ・エディション: ベスト・プラクティス・ガイド

ID 683152
日付 12/16/2019
Public
ドキュメント目次

3.2. 可変遅延MMマスター・インターフェイスのLSUの制御

ロード・ストア・ユニット (LSU) は、 インテル®HLSコンパイラー プロ・エディションによって可変レイテンシーMemory Mapped (MM) Masterインターフェイスとの対話に使用されます。LSUのタイプを制御すると、デザインの面積が節約できます。また、ロード/ストアと他のロード/ストア動作の静的結合をディスエーブルすると、デザインのパフォーマンスが向上する場合があります。

次のチュートリアルで、LSUの制御について確認してください。 <quartus_installdir>/hls/examples/tutorials/best_practices/lsu_control

LSU制御を使用する必要性を確認するには、コンポーネント、特にFunction Memory ViewerのHigh-Level Design Reportを確認します。その上で、メモリー・アクセス・パターン (およびその関連LSU) が、 インテル®HLSコンパイラー プロ・エディションで予想するメモリー・アクセス・パターンと一致するかどうかを確認します。一致しない場合は、LSUタイプ、LSU結合、またはその両方の制御を検討してください。

作成されたLSUのタイプを制御する

インテル®HLSコンパイラー プロ・エディションでは、バースト結合LSUまたはパイプラインLSUを作成します。

通常、バースト結合LSUを使用するのは、LSUによる連続するメモリーワードへのロード/ストア要求の処理が多数予想される場合です。バースト結合したLSUでは、メモリー帯域幅をより効率的に利用するために、要求を「動的結合」して大きなバーストにしようとします。

パイプライン処理されたLSUでは、消費するFPGA領域は大幅に少なくなりますが、ロード/ストアリクエストの処理は、結合はしないで個別に行います。この処理が役立つのは、デザインが面積の点で厳しい場合や、可変遅延MM Masterインターフェイスへのアクセスが必ずしも連続していない場合です。

次のコード例で示しているLSUのタイプは両方とも、可変遅延MM Masterインターフェイス用に実装されているものです。
component void
dut(mm_master<int, dwidth<128>, awidth<32>, aspace<4>, latency<0>> &Buff1,
    mm_master<int, dwidth<32>, awidth<32>, aspace<5>, latency<0>> &Buff2) {
  int Temp[SIZE];

  using pipelined = lsu<style<PIPELINED>>; 
  using burst_coalesced = lsu<style<BURST_COALESCED>>;

  for (int i = 0; i<SIZE; i++) {
    Temp[i] = burst_coalesced::load(&Buff1[i]); // Burst-Coalesced LSU
  }

  for (int i = 0; i<SIZE; i++) {
    pipelined::store(&Buff2[i], 2*Temp[i]); // Pipelined LSU
  }
}

静的結合のディスエーブル

静的結合が一般的に有益である理由は、デザイン内のLSUの総数を削減するため、複数のロード/ストア動作を組み合わせて、広い静的ロード/ストア動作にするからです。

しかし、場合によっては、静的結合により、非整列アクセスが発生します。また、一部のロード/ストアのみが同時に動作することを意図していた場合でも、複数のロード/ストアが結合する場合があります。このような場合、結合させたくないロード/ストア動作に対して静的結合をディスエーブルすることを検討してください。

次のコード例の場合、 インテル®HLSコンパイラーでは、2つのロード動作を静的結合して1つのワイドロード動作にすることはありません。
component int
dut(mm_master<int, dwidth<256>, awidth<32>, aspace<1>, latency<0>> &Buff1,
    int i, bool Cond1, bool Cond2) {

  using no_coalescing = lsu<style<PIPELINED>, static_coalescing<false>>;
  int Val = 0;
  if (Cond1) {
    Val = no_coalescing::load(&Buff1[i]);
  }
  if (Cond2) {
    Val = no_coalescing::load(&Buff1[i + 1]);
  }
  return Val;
}
2つのロード動作が結合すると、非整列LSUが作成され、それによってコンポーネントのスループットが低下します。