News and Views 2014 Autumn / Vol. 11: 上流設計&組込み

エミュレータを用いたソフトウェアデバッグの資源活用効率化

RTLのシミュレーションにエミュレータを用いると、論理シミュレータで行った場合と比較して3桁から4桁もの速度面でのメリットが得られます。SoC設計の検証にソフトウェア実行を伴う場合には、それがよほど小さなテストケースでない限り、論理シミュレータで検証を進めることは現実的ではありません。組込みLinuxのブートが終了するまでの時間は、エミュレータでは20分から30分かかるのに対して、論理シミュレータでは7ヶ月から8ヶ月を要します。

検証セッションにおいてソフトウェアの実行量が多い場合、デバッグする手法を何かしら確立させておく必要があります。通常、JTAGと汎用デバッガを組合せたデバッグが一般的です。JTAGは、プロセッサのレジスタ値を読み取ることでデバッガ上にプロセッサの状態を表示させます。また逆に、デバッガからJTAGを介してレジスタ値を設定し、ソフトウェア実行を外部から制御することも可能です。JTAGの使用は、FPGAプロトタイプでベアメタルを扱う場合の標準的なデバッグ手法となっています。

JTAGとエミュレーション

JTAGプローブが組込みシステムのプロトタイプをデバッグする標準的な手法であることから、ボードで構成されるエミュレータでもJTAGを使うというのはごく自然な発想なのかも知れません。

JTAGプローブの機能をエミュレータ上で実現する方法は二通りあります。1つ目はプローブを介して物理的にデザイン内の信号に接続する方法です。この方法では、デザイン内のJTAG用信号を特定した上でI/Oカードに引き込み、物理的にエミュレータの外部で接続します。2つ目の方法は、プログラム的に信号にアクセスする方法です。エミュレーションでは、デザイン内の任意の信号をサンプリングしたりドライブしたりできるので、プログラムからデバッガに直接アクセスし、JTAGの機能を物理的なプローブやコネクタを使用せずに実現します。

プローブを用いたデバッグの問題点

実は、プローブを用いたデバッガをエミュレーションに接続する手法には問題点があります。エミュレーションのターゲットの特徴は、組込みシステムなどの物理ターゲットの特徴とは異なるからです。

組込みシステムが実装される物理ターゲットは常に完成されたシステムが前提になっており、開発途中ということはあり得ません。しかしエミュレーションの場合、そのターゲットは開発途中の不完全な状態が想定され、かつターゲットが機能し始める前にデバッグ環境を実装しなくてはならないという大きな課題を抱えています。つまり、設計サイクルのかなり後段になってからでないと、実際にはプローブは使用するに値しないのです。

もう1つの問題は、JTAGの信号線数が少ないという点です。物理ターゲットではコアの内部情報を得ることは困難であり、実質的にはブラックボックスの扱いになります。このことから、JTAG規格を作成した技術委員会であるJoint Test Action Groupは、JTAGが扱える信号数を少なくしています。また、コアの周波数が高速化したことでプローブ用クロックとの差異も広がっています。例えば、スキャンチェーンを介して1つのインストラクションを実行するには数十万クロックから100万ものクロックが要されます。複雑なインストラクションや複数インストラクションによる振舞いのデバッグにはさらなるクロックが必要とされ、数メガヘルツで動作するエミュレーションでは問題となります。

デバッグ時にはプロセッサ動作がサスペンド状態となりますが、その間にもデザインの他の部分の動作は進行しています。このことから、タイミングにずれが生じ、デザイン内部に矛盾が発生します。同期やタイミングが絡むデバッグの作業は一層困難なものとなります。

図1. エミュレーション時にJTAGを使用したソフトウェアデバッグの様子図1. エミュレーション時にJTAGを使用したソフトウェアデバッグの様子

ソフトウェアのデバッグでは、さまざまな時間のポイントでソースコードを確認し、変数やレジスタを確認します。この間、エミュレータは止まっています。クロックを進めエミュレータが新たなステートになったら、再びソフトウェアのデバッグを開始します。エミュレーション実行中にはソフトウェアデバッグは停止し、逆に、ソフトウェアデバッグの間はエミュレーションが停止します。エミュレータは高価な資産であり、複数のエンジニアや複数のプロジェクト、事業所で共有し有効活用することが求められていますが、ソフトウェアをインタラクティブにデバッグするこの手法は、その有効活用を阻害する要因となっています。(図1)

ハードウェアのデバッグでは、LSFやSunGridにジョブをキューイングして実行させ、設計者はログファイルや波形を用いてデバッグを行います。しかし、ソフトウェアのデバッグではこのプロセスを実現できません。

トレースベースのデバッグ

プローブベースのソフトウェアデバッグが持つ数多くの問題を緩和する手法が、トレースベースのアプローチです。これは、エミュレータから信号やレジスタに簡単にアクセスできるメリットを活かした手法です。エミュレーション実行中は、プロセッサのRTL内部/外部の信号がログとしてホストに送られます。ホスト上において信号からの情報を再構築し、プロセッサの状態やメモリの状態を再現すると、組込みソフトウェアデバッガはこのデータを「仮想ターゲット」として利用できるようになります。JTAGプローブでエミュレータに接続していたデバッガは仮想ターゲットに対しても使用可能であり、ステップ実行、ブレイクポイント、メモリ確認、ソースコードの参照など、従来のデバッグ手法を変更する必要はありません。

図2. エミュレーション時に仮想ターゲットを使用したソフトウェアデバッグの様子図2. エミュレーション時に仮想ターゲットを使用したソフトウェアデバッグの様子

上記2つの手法の最も大きな違いは、後者では、仮想ターゲットに対してソフトウェアデバッグを行っている間はエミュレータが解放され、他のエミュレーションを必要とするジョブを実行できるという点です。(図2)ソフトウェア開発者がデバッグ作業に膨大な時間を必要としたとしても、エミュレータのスループットに影響を及ぼすことはなく、数メガヘルツというエミュレータの実行速度の真価が発揮されます。従来の手法では、エミュレータにもユーザ側にも待ち状態が続くという問題がありました。トレースベースの手法は、仮想ターゲットに対してソフトウェアデバッグを行うことでこの問題を解決し、さらにLSFやSunGridにジョブをキューイングし実行させることで、スループットを最大に引き上げます。

トレースベースのデバッグ手法のメリットはこれだけではありません。デバッグを進める上で、時間を先に進めることは当然ですが、仮想ターゲットを使用する場合には時間を前に巻き戻すことも可能になります。例えば、例外処理のタイミングをブレイクポイントに設定して実行させた後、時間を巻き戻して例外が発生した原因を突き止めることができます。その際には、ハードウェアの非決定的な要素も排除されています。

プローブベースでは、数百万クロックに及ぶデバッグの仕組みを設定する必要があり、前述の通り、同期やタイミングに関する問題をデバッグすることが非常に困難です。しかし、トレースベースのデバッグでは、トレースが非侵入的であることから、時間に関する制約がなく、ハードウェアとソフトウェア間のタイミングはもちろんのこと、マルチコア間での通信についても深いデバッグが可能になります。

まとめ

プローブを用いたソフトウェアデバッグは、FPGAボード上でベアメタルのデバッグには有効ですが、エミュレーションに対しては効力を発揮しません。対してトレースベースの手法では、エミュレーション実行後の仮想ターゲットを用いることにより、デバッグの質と生産性が大幅に向上するだけでなく、数メガヘルツオーダーの真価を下げることなく、エミュレータのリソースを有効活用できます。さらに、マルチコア間の通信など、従来のプローブベースでは不可能に近かったデバッグを可能にします。

エミュレーションの社内クラウド使用でも可能な
仮想ターゲットを用いたマルチコア同期のデバッグ環境はこちら

今すぐダウンロード