SDSoC のデバッグの概要

SDSoC™ 環境は、ヘテロジニアス エンベデッド システムをインプリメントするための Eclipse ベースの統合設計環境 (IDE) です。SDSoC では、Zynq®-7000 SoC および Zynq® UltraScale+™ MPSoC デバイスを使用した Arm® Cortex™ ベースのアプリケーションと、ザイリンクス SoC および FPGA 上の MicroBlaze™ プロセッサ ベースのアプリケーションがサポートされます。

この資料では、SDSoC 環境のデバッグ機能について説明し、SDSoC フローで発生した問題を解析する方法を詳細に示します。

注記: パフォーマンスの問題については説明しません。ツールの問題がなく、デザインが正しく機能している場合は、SDSoC プロファイリングおよび最適化ガイド を参照して、デザインのパフォーマンスに改善の余地があるかどうかを調べてみてください。

SDSoC 環境の概要

SDSoC 環境には、選択した関数をプログラマブル ロジック (PL) にコンパイルし、C/C++ プログラムを完全なハードウェア/ソフトウェア システムに変換するシステム コンパイラが含まれます。SDSoC のシステム コンパイラは、プログラムを解析してソフトウェア関数とハードウェア関数間のデータフローを判断し、プログラムを実現するアプリケーション特定のシステム オン チップ (SoC) を生成します。

高パフォーマンスを達成するため、各ハードウェア関数は独立したスレッドとして実行されます。システム コンパイラは、ハードウェア コンポーネントおよびソフトウェア コンポーネントを生成してハードウェア スレッドとソフトウェア スレッド間が同期するようにし、パイプライン計算および通信もイネーブルにできます。アプリケーション コードには、多数のハードウェア関数、特定のハードウェア関数の複数のインスタンス、プログラムの異なる部分からのハードウェア関数呼び出しなどを含めることができます。

SDx 統合開発環境 (IDE) では、プロファイリング、コンパイル、リンク、システム パフォーマンス解析、デバッグを含むソフトウェア開発ワークフローがサポートされています。また、高速なパフォーマンス見積もり機能があり、ハードウェアの完全なコンパイルを実行する前に、さままなハードウェア/ソフトウェア インターフェイスを試すことが可能です。

SDSoC システム コンパイラは、ベース プラットフォームをターゲットとし、Vivado® 高位合成 (HLS) ツールを起動して合成可能な C/C++ 関数をプログラマブル ロジックにコンパイルします。その後 Vivado Design Suite ツールを起動して、システム コンパイラで DMA、インターコネクト、ハードウェア バッファー、その他の IP、および FPGA ビットストリームを含む完全なハードウェア システムを生成します。すべてのハードウェア関数呼び出しで元の動作が保持されるようにするため、SDSoC システム コンパイラはシステム特定のソフトウェア スタブおよびコンフィギュレーション データを生成します。このプログラムには、生成された IP ブロックを使用するのに必要なドライバーへの関数呼び出しが含まれています。アプリケーションおよび生成されたソフトウェアは、標準の GNU ツールチェーンを使用してコンパイルおよびリンクされます。

システム コンパイラでは、1 つのソースから完全なアプリケーションを生成することにより、プログラム レベルでデザインおよびアーキテクチャを繰り返し変更できるので、ターゲット プラットフォームで実行可能なプログラムを達成するまでの時間を短縮できます。

用語

次の用語は、SDSoC 環境での設計に関する内容でよく使用されます。用語とその説明は次のとおりです。

アクセラレータ
FPGA 汎用インターコネクトのハードウェアにインプリメントされるアプリケーション コードの部分。「ハードウェア関数」とも呼ばれます。
データ ムーバー
データ ムーバーは、アクセラレータ間、およびプロセッシング システム (PS) とアクセラレータの間でデータを転送します。SDSoC 環境では、転送されるデータの特性とサイズに基づいてさまざまなタイプのデータ ムーバーを生成できます。
パイプライン処理
パイプライン処理は、アルゴリズムのハードウェア インプリメンテーションで命令レベルの並列処理を増加させる手法で、演算または関数の独立した段をオーバーラップさせます。機能が等価になるよう元のソフトウェア インプリメンテーションのデータ依存性は保持されますが、必要な回路は独立した段のチェーンに分割されます。チェーンのすべての段は、同じクロック サイクルで並列実行されます。唯一の違いは、各段のデータのソースです。計算の各段は、前のクロック サイクルで前の段で計算された結果からデータ値を受信します。
プラグマ
システム コンパイラに指示を与えるためにソース コードに挿入可能な特別な指示子。SDSoC 環境では、通信と計算のバランスが取られるようにハードウェア関数およびハードウェア関数への呼び出しを構成し、システム コンパイラに指示を与えるプラグマをソース コードに挿入することにより、システム生成プロセスを制御します。
プロセッサ
SDSoC 環境では、プロセッサとは MicroBlaze プロセッサなどのソフト プロセッサまたは Zynq-7000 SoC および Zynq UltraScale+ MPSoC などの Arm プロセッサを意味します。
システム ポート
システム ポートは、データ ムーバーを PS に接続します。システム ポートとしては、Zynq の ACP、AFI (ハイ パフォーマンス ポートに対応)、MIG (PL ベースの DDR メモリ コントローラーに対応)、またはストリーム ポートを使用できます。

SDSoC のエレメント

SDSoC 環境には、次の機能が含まれます。

  • 完全なハードウェア/ソフトウェア システムを生成する sds++ システム コンパイラ。sds++ システム コンパイラでは、Vivado 高位合成 (HLS)、Vivado IP インテグレーター、データ移動およびインターコネクト用の IP ライブラリ、RTL 合成、配置、配線、ビットストリーム生成用のツールを含む Vivado Design Suite System Edition からの機能が使用されます。
  • アプリケーション プロジェクトおよびワークフローを作成および管理する Eclipse ベースの統合開発環境 (IDE)。
  • ハードウェア/ソフトウェア インターフェイスで異なるシナリオを試すためのシステム パフォーマンス見積もり。

SDSoC 環境は、Zynq-7000 SoC および Zynq UltraScale+ MPSoC 用の GNU ツールチェーン、標準ライブラリ (glibc など)、エンベデッド プロセッサ ターゲットとの通信に使用される TCF (Target Communication Framework) を含むザイリンクス ソフトウェア開発キット (SDK) などの多数のツールも継承しています。Eclipse/CDT ベースの IDE には、パフォーマンス解析パースペクティブも含まれます。

sds++ システム コンパイラでは、ターゲット プラットフォームをカスタマイズしてアプリケーションのシステム オン チップが生成されます。この環境には、アプリケーション開発用の多数の標準ベース プラットフォームのほか、サードパーティ パートナーや SDSoC 設計チームの開発したプラットフォームも含まれます。SDSoC 環境プラットフォーム開発ガイド に、Vivado Design Suite を使用したプラットフォーム デザインの作成方法、プラットフォーム インターフェイスの設定方法、プラットフォームを構築するソフトウェア ランタイム環境を定義して SDx™ IDE で使用できるようにする方法などが説明されています。

SDx™ IDE では、アプリケーション特定のハードウェア アクセラレータおよびアクセラレータをプラットフォームに接続するデータ モーション ネットワークを使用して、ターゲット プラットフォームをカスタマイズします。次に、メモリ アクセス ポートとハードウェア アクセラレータを含む簡略化した Zynq と DDR コンフィギュレーションを示します。

図: メモリ アクセス ポートとメモリを示した Zynq + DDR の簡略図



SDSoC アプリケーションの実行モデル

SDSoC 環境アプリケーションの実行モデルは、プラットフォームのブート後にターゲット CPU で実行される C++ プログラムの通常実行を考えると理解できます。C++ バイナリの実行ファイルがハードウェアとどのようにインターフェイスするかを理解しておくと有益です。

プログラム内で宣言されたハードウェア関数はハードウェア アクセラレータにコンパイルされ、標準 C ランタイムでこれらの関数への呼び出しによりアクセスされます。各ハードウェア関数呼び出しがタスクとしてアクセラレータを起動し、関数への各引数が CPU とアクセラレータ間で転送されて、アクセラレータ タスクの完了後にプログラムでアクセスできるようになります。メモリとアクセラレータ間のデータ転送には、DMA エンジンなどのデータ ムーバーが使用され、zero_copy などのユーザー データ ムーバー プラグマを考慮して、sds++ システム コンパイラにより自動的に挿入されます。

図: SDSoC システムのアーキテクチャ

プログラムが正しく機能するようにするため、システム コンパイラはハードウェア関数への各呼び出しをインターセプトし、シグネチャが同じで派生した名前が付けられたスタブ関数への呼び出しに置き換えます。スタブ関数はすべてのデータ移動とアクセラレータの演算を制御し、ハードウェア関数呼び出しの終了時にソフトウェアとアクセラレータ ハードウェアを同期化します。スタブ内では、すべてのアクセラレータとデータ ムーバーは sds_lib ライブラリに含まれる送信および受信 API により制御されます。

ハードウェア関数呼び出し間のプログラム データフローに、プログラム内で関数呼び出し (デストラクターまたは free() 呼び出し以外) が実行された後にアクセスされない配列引数が関係する場合、およびハードウェア アクセラレータをストリームを使用して接続できる場合、メモリへの往復がインプリメントされるのではなく、1 つのハードウェア アクセラレータから直接ハードウェア ストリーム接続を介して次のハードウェア アクセラレータにデータが転送されます。この最適化により、パフォーマンスが大幅に向上し、ハードウェア リソースを削減できます。

SDSoC プログラム実行モデルの手順は次のとおりです。
  1. プログラムのコンストラクターが main() に入る前に sds_lib ライブラリが初期化されます。
  2. プログラム内で、ハードウェア関数への各呼び出しが、元の関数と関数シグネチャが同じ (名前は異なる) のスタブ関数への関数呼び出しによりインターセプトされます。スタブ関数内では、次の手順が実行されます。
    1. 同期アクセラレータ タスク制御コマンドがハードウェアに送信されます。
    2. ハードウェア関数への各引数に対して、非同期データ転送要求が関連付けられた wait() ハンドルと共に適切なデータ ムーバーに送信されます。void 以外の戻り値は、出力スカラー引数として扱われます。
    3. 各転送要求に対して、バリア wait() が発行されます。アクセラレータ間のデータ転送がダイレクト ハードウェア ストリームとしてインプリメントされる場合、この転送のバリア wait() は、この引数のアクセラレータ関数チェーンの最後のアクセラレータ関数に対するスタブ関数で発生します。
  3. プログラムのデストラクターが main() を終了するときに、sds_lib ライブラリがクリーンアップされます。
ヒント: 手順 2a ~ 2c は、アクセラレータ パイプラインの開始および終了時にプログラムを正しく保ち、それと同時にパイプライン内での同時実行を可能にします。

場合によっては、システム コンパイラで自動的には推論できないアクセラレータ タスクの同時実行の可能性を、プログラマが認識していることもあります。sds++ システム コンパイラでは #pragma SDS async(ID) プラグマがサポートされており、このような場合にハードウェア関数への呼び出しの直前に挿入できます。このプラグマを指定すると、データ転送に対してバリア wait() 呼び出しなしでスタブ関数が生成されます。その結果、すべての転送要求を発行した後、制御がプログラムに戻り、アクセラレータの実行中にプログラムの同時実行が可能になります。この場合、プログラム内の適切な同期ポイントに #pragma SDS wait(ID) を挿入してください。このプラグマは sds_wait(ID) API 呼び出しとなり、ハードウェア アクセラレータ、その暗示的なデータ ムーバー、および CPU が正しく同期化されます。

重要:async(ID) プラグマには、対応する wait(ID) プラグマが必要です。

SDSoC のビルド プロセス

SDSoC のビルド プロセスでは、標準のコンパイルおよびリンク プロセスが使用されます。g++ と同様に、sds++ システム コンパイラはサブプロセスを呼び出してコンパイルおよびリンクを実行します。

次の図に示すように、コンパイル段階では、CPU で実行されるオブジェクト コードのコンパイルだけでなく、Vivado 高位合成 (HLS) ツールを使用したハードウェア関数の IP ブロックへのコンパイルおよびリンク、およびターゲット CPU ツールチェーンを使用した標準オブジェクト ファイル (.o) の作成も実行されます。システムのリンク段階では、すべてのハードウェア関数における呼び出し元/呼び出し先の関係のプログラム解析、各ハードウェア関数呼び出しをインプリメントするアプリケーション特定のハードウェア/ソフトウェア ネットワークの生成が実行されます。sds++ システム コンパイラは、Vivado HLS (関数コンパイラ)、生成されたハードウェア システムをインプリメントする Vivado Design Suite、CPU で実行されるアプリケーション バリアを作成する Arm コンパイラおよび sds++ リンカーなど必要なすべてのツールを呼び出して、SD カード用の完全なブート可能イメージを出力することにより、各ハードウェア関数用のアクセラレータ (スタブ) を呼び出します。

図: SDSoC のビルド プロセス

コンパイル プロセスには、次のタスクが含まれます。

  1. コードが解析され、Arm コアの main アプリケーションがコンパイルされ、各ハードウェア アクセラレータに対して個別にコンパイルが実行されます。
  2. 標準 GNU Arm コンパイル ツールでアプリケーションがコンパイルされ、最終出力としてオブジェクト ファイル (.o) が生成されます。
  3. ハードウェアでアクセラレーションされる関数が HLS ツールで実行され、カスタム ハードウェア作成プロセスが開始し、出力としてオブジェクト ファイル (.o) が生成されます。

コンパイル後のリンク プロセスには、次のタスクが含まれます。

  1. デザイン内のデータ移動が解析され、ハードウェア プラットフォームがアクセラレータを受け入れるよう変更されます。
  2. Vivado Design Suite で合成およびインプリメンテーションが実行されてハードウェア アクセラレータがプログラマブル ロジック (PL) 領域にインプリメントされ、デバイス用のビットストリームが生成されます。
  3. エンベデッド プロセッサ アプリケーションからハードウェア関数を呼び出すため、ソフトウェア イメージがハードウェア アクセス API でアップデートされます。
  4. ボードを ELF (Executable and Linkable Format) ファイルのアプリケーションでブートする統合 SD カード イメージが生成されます。

SDSoC デバッグ フローの概要

SDSoC 環境で生成されるシステムは、ハードウェア コンポーネントおよびソフトウェア コンポーネントで構成される高性能で複雑なシステムです。ソフトウェアの一部がプロセッサで実行され、ハードウェア アクセラレータがプログラマブル ファブリックで実行され、それらの間でデータ転送が同時に多数実行されるこのようなシステムでは、アプリケーションの実行を理解するのが困難なことがあります。SDSoC 環境では、ザイリンクス ソフトウェア デバッガー (XSDB) を使用してプロジェクトを作成およびデバッグできます。高度なハードウェア/ソフトウェア イベント トレースが提供されており、ドライバー ソフトウェア設定およびハードウェアでの実行を含むアクセラレータ タスクとデータ転送の統合タイムライン ビューがあります。コマンド ラインまたはスクリプト オプションを使用すると、SDx IDE 外でプロジェクトをデバッグできます。

SDSoC 開発環境では、コンパイルおよびリンク コマンドのビルド プロセスのターゲットをシステム エミュレーション ターゲットまたは指定のプラットフォームのハードウェア ターゲットに指定できます。完全なシステムをビルドする代わりに、ターゲットとアプリケーション バイナリを含むエミュレーション モデルを作成できます。エミュレーション ターゲットに対しては、sds++ システム コンパイラによりクセラレータ関数のソース ファイルを使用してシミュレーション モデルが作成されます。

システム エミュレーションは SDSoC 環境で最も有効なデバッグ機能の 1 つで、論理的な問題をデバッグしたり、アプリケーションがハングする原因を突き止めたりするのに役立ちます。この機能は、ザイリンクス ベース プラットフォーム ZC702、ZC706、ZCU102、ZCU104、ZCU106、および ZedBoard ベースのプラットフォームでのみ使用可能です。

ハードウェア関数を特定したら、システム エミュレーションを使用してロジックをすばやくコンパイルし、システム全体を検証できます。これによりクイック エミュレーター (QEMU) ベース エミュレーターでクロスコンパイルされた Arm コードを実行し、Vivado シミュレータで実行しているハードウェア アクセラレータと通信できます。RTL シミュレータでは波形を表示できますが、波形を表示せずに高速にシミュレーションを実行することもできます。エミュレーターは SDx IDE 内またはコマンド ライン (sdsoc_emulator) で実行でき、システムをビットストリームにコンパイルしてボード上のデバイスにプログラムせずに、最終的なハードウェア インプリメンテーションを正確に表示できます。

図: システム エミュレーション フロー

ハードウェア プラットフォームをターゲットとする場合、ハードウェアおよびソフトウェア イベント トレースを使用して、イベントの実行を解析したり、問題を見つけたりすることもできます (ハードウェア/ソフトウェア イベントのトレース を参照)。ハードウェア デザイン自体に問題がある場合は、SDSoC 環境にインプリメントされたハードウェア関数にデバッグ コアを挿入して、Vivado Lab Edition でハードウェア デバッグを使用できます。次の図に、典型的なハードウェアのビルドおよびデバッグ プロセスを示します。

図: ハードウェアのビルドおよびデバッグ フロー

ザイリンクス ベース プラットフォームでは、システム エミュレーションおよびハードウェア ターゲット ビルドの両方がサポートされます。カスタム プラットフォームおよびサードパーティ プラットフォームでは、ハードウェア ビルドおよびデバッグ フローのみがサポートされます。

システム エミュレーション

ザイリンクス ベース プラットフォームでは、システム エミュレーションを使用してシステム全体 (PS および PL) の RTL レベルのトランザクションをデバッグできます。SDSoC エミュレーター (sdsoc_emulator) でアプリケーションを実行すると、デバッガーでデータ転送を可視化できます。これによりシステム ハングプの問題をデバッグでき、シミュレーション波形ビューで関連するデータ転送調べて、そのデータ転送に関係するハードウェア ブロックの信号を表示できます。

ハードウェア実行フロー

ハードウェア実行では、実際のハードウェア プラットフォームを使用してアクセラレーションされたアプリケーションを実行できます。System Integrated Logic Analyzer (System ILA)、Virtual Input/Output (VIO) デバッグ コア、AXI パフォーマンス モニターなどの特別なデバッグ ロジックをアクセラレータに含むハードウェアのデバッグ コンフィギュレーションを作成できます。SDSoC 環境には Vivado ハードウェア マネージャーを使用したハードウェア デバッグ機能が含まれており、波形解析、カーネル アクティビティ レポート、およびメモリ アクセス解析を実行してハードウェアのクリティカルな問題を可視化できます。

インシステム デバッグを使用すると、ターゲット ハードウェアでデザインをリアルタイムにデバッグできます。これは、デザインを完成させるために必須の手順です。シミュレータでは再現するのが困難な状況もあるので、実行中のハードウェアで問題をデバッグすることが必要です。この手順では、デザインにデバッグ コアを配置して、デザインを監視および制御できるようにします。デバッグ プロセスが終了したら、パフォーマンスを向上してデバイスのリソース使用率を削減するため、デバッグ コアを削除できます。

SDx IDE およびコマンド ライン オプションを使用して、デザインをデバッグ用にインストルメント化できます。--dk コンパイラ オプションは、ハードウェア関数のインターフェイスに ILA デバッグ コアを追加します。アプリケーション コードで使用される C 呼び出し可能な IP をデバッグするには、IP を C 呼び出し可能な IP としてパッケージする前に、IP の RTL コードにデバッグ コアをインスタンシエートする必要があります。

重要: SDSoC プラットフォーム ハードウェア上でハードウェア関数をデバッグするには、ハードウェア モデル全体に追加のロジックを組み込む必要があります。つまり、ハードウェア デバッグを有効にすると、ザイリンクス デバイスのリソース使用率およびハードウェア関数のパフォーマンスに影響します。

ハードウェアへの接続

ボード接続要件は、オペレーティング システム (スタンドアロン、FreeRTOS、または Linux) によって多少異なります。
  • スタンドアロンおよび FreeRTOS の場合、USB/JTAG インターフェイスを使用して ELF ファイルをボードにダウンロードする必要があります。トレース データも同じ USB/JTAG インターフェイスを介して読み出されます。
  • Linux では、SDx 環境で OS が SD カードから起動されると想定されます。この後 .elf ファイルがコピーされ、ボードとホスト PC 間のイーサネット接続を介して、Linux で実行される TCP/TCF エージェントを使用して実行されます。トレース データは、USB/JTAG インターフェイスを介して読み出されます。このため、Linux アプリケーションのトレースには、USB/JTAG インターフェイスおよび TCP/TCF エージェント インターフェイスの両方が必要です。
次の図に、必要な接続を示します。

図: 異なるオペレーティング システムでトレースを使用した場合に必要な接続



イベント トレース

イベント トレース機能を使用すると、アプリケーション実行中にシステムで何が起こっているかを詳細に表示できます。トレース イベントが生成されてタイムライン ビューに収集され、実行中のアプリケーションに関する情報が表示されます。この詳細な表示により、アプリケーションに指定されたワークロードのパフォーマンス、ハードウェア/ソフトウェア パーティション、およびシステム デザインの選択肢などが理解しやすくなっています。この表示を使用すると、プロセッサで実行されているソフトウェアのイベント トレースと、システム内のハードウェア アクセラレータおよびデータ転送のリンクが可能になります。このような情報は、問題の特定、システム インプリメンテーションの最適化、システム インプリメンテーションの向上に役立ちます。

アプリケーションをトレースすると、システム実行に関する情報を記録するログが生成されます。イベント トレースでは、イベント ログとは異なり、特定の時間の瞬間的なイベントが表示されるのではなく、イベント期間中のイベント間の関係が表示されます。トレースの目標は、何がいつ発生するか、イベントがどれくらい続くのかなどを確認することで、デバッグ実行をしやすくすることにあります。これは、パフォーマンスを解析し、アプリケーションのハングアップが発生するかどうかを調べるの最適です。