C/RTL 協調シミュレーションが終了すると、シミュレーション レポートが開き、計測されたレイテンシと II が表示さ れます。これらの結果は、HLS 合成後にレポートされたデザイン全体の絶対最短パスおよび最長パスに基づく値とは 異なる場合があります。C/RTL 協調シミュレーション後の結果には、指定したシミュレーション データ セットでの 実際のレイテンシと II であり、別の入力スティミュラスを使用すると変わる可能性があります。
パイプライン処理されていないデザインでは、C/RTL 協調シミュレーションで ap_start および ap_done 信号間の レイテンシが計測されます。すべての演算が終了した 1 サイクル後にデザインで新しい入力が読み出されるので、II はレイテンシより 1 長くなります。現在のトランザクションが終了してからしか次のトランザクションは開始され ません。
パイプライン処理されたデザインでは、最初のトランザクションが終了する前に新しい入力が読み出されるので、ト ランザクションが終了する前に複数の ap_start および ap_ready 信号がある可能性があります。この場合、
C/RTL 協調シミュレーションでレイテンシはデータ入力値とデータ出力値間のサイクル数として計測されます。II は、新しい入力を要求するために使用される ap_ready 信号間のサイクル数です。
注記: パイプライン処理されたデザインでは、C/RTL 協調シミュレーションの II 値は、デザインが複数のトランザク ションでシミュレーションされた場合にのみ決定されます。
シミュレーション波形の表示
RTL 波形データを表示するには、[Co-simulation] ダイアログ ボックスで次を実行する必要があります。
• RTL シミュレータに Vivado XSim を選択します。
• [Dump Trace] に port または all を選択します。
Vivado XSim が開き、RTL デザインのすべてのプロセスが表示されます。HLS デザイン内でアクティビティ プロセス
を可視化すると、プロセス アクティビティおよび 最上位モジュールの各アクティビティ 内の長さの詳細なプロファイ リングが可能になります。これにより、個別プロセスのパフォーマンスだけでなく、それぞれのプロセスの全体的な 並行処理実行を解析しやすくなります。実行全体を占めるプロセスの方がパフォーマンスを改善する可能性が高く、
プロセス実行時間を削減できます。
2 つのセクションに分割されます。
• HLS プロセスのサマリには、すべてのプロセスのアクティビティ レポートの階層表示が含まれます。
• [DUT name]: <name>
• [Function]: <function name>
• データフロー解析には、データフロー領域内のタスクに関する詳細なアクティビティ 情報が含まれます。
• [DUT name]: <name>
• [Function]: <function name>
• [Dataflow/Pipeline Activity]: データフロープロセスとしてインプリメントされる場合に並列実行される関数 の数を示します。
• [Active Iterations]: 現在のアクティブなデータフローのイテレーションを 示します。行数は現在の実行を表示 するため動的に増加します。
• [StallNoContinue]: データフロー プロセスで出力のストールがあるかどうかを示すストール信号です。関数は 完了しますが、隣接するデータフロープロセスからの続行信号は受信していません。
• [RTL Signals]: データフロー プロセスのトランザクション ビューを解釈するのに使用される RTL 制御信号で す。
図 35: 波形ビューアー
C/RTL 協調シミュレーションが終了したら、[Open Wave Viewer] ツールバーボタンをクリックするか、[Solution] →
[Open Wave Viewer] をクリックすると、Vivado IDE で RTL 波形を再び開くことができます。
重要: この方法で Vivado IDE を開く場合は、拡大/縮小、波形基数などの波形解析機能しか使用できません。
協調シミュレーションのデッドロック ビューアー
デッドロックとは、データフロー領域内のプロセスが同じチャネルを共有しており、お互いの書き込みまたは読み出 しを妨害するために、両方のプロセスが停止してしまう状態のことです。この状況は、データフロー領域内のチャネ
ルに FIFO または PIPO と FIFO の両方が使用されているよく発生します。
デッドロック ビューアーでは 、スタティック データフロー表示でこのデッドロック状況を視覚化でき、問題のある プロセスおよびチャネルがハイライトされます。問題のあるデータフロー チャネルから関連するソース コードへの クロスプローブが可能です。この情報を使用すると、問題をより短い時間と少ない労力で解決できます。ビューアー は、協調シミュレーションがデッドロック状態を検出し、実行を終了してからのみ開くことができます。
次に例を示します。データフロー領域には、PIPO と FIFO を介して通信する 2 つのプロセスがあります。proc_1 の 最初のループは、data_array に書き込む前に、data_channel1 に 10 個のデータを書き込みます。FIFO の深さが十分 でないため、data_channel ループが完了せず、残りのプロセスがブロックされます。この後、proc_2 は data_channel2 が空のためにデータを読み出せないのでブロックされ、data_channel1 からデータを削除できません。このためデッ ドロック状態になるので、data_channel1 のサイズを少なくとも 10 に増加する必要があります。
void example(hls::stream<data_t>& A, hls::stream<data_t>& B){
#pragma HLS dataflow ....
hls::stream<int> data_channel;
int data_array[10];
#pragma HLS STREAM variable=data_channel depth=8 dim=1 proc_1(A, data_channel, data_array);
proc_2(B, data_channel, data_array);
}
void proc_1(hls::stream<data_t>& A, hls::stream<int>& data_channel, int data_array[10]){
… for(i = 0; i < 10; i++){
tmp = A.read();
tmp.data = tmp.data.to_int();
data_channel.write(tmp.data);
} for(i = 0; i < 10; i++){
data_array[i] = i + tmp.data.to_int();
}}
void proc_2(hls::stream<data_t>& B, hls::stream<int>& data_channel, int data_array[10]){
int i;
.. ..
for(i = 0; i < 10; i++){
if (i == 0){
tmp.data = data_channel.read() + data_array[5];
} else {
tmp.data = data_channel.read();
}
B.write(tmp);
}
協調シミュレーション ログ:
////////////////////////////////////////////////////////////////////////////
///////
// Inter-Transaction Progress: Completed Transaction / Total Transaction // Intra-Transaction Progress: Measured Latency / Latency Estimation * 100%
//// RTL Simulation : "Inter-Transaction Progress" ["Intra-Transaction Progress"] @ "Simulation Time"
////////////////////////////////////////////////////////////////////////////
////////
// RTL Simulation : 0 / 1 [0.00%] @ "105000"
////////////////////////////////////////////////////////////////////////////
//// ERROR!!! DEADLOCK DETECTED at 132000 ns! SIMULATION WILL BE STOPPED! //
////////////////////////////////////////////////////////////////////////////
///////////////////////////
// Dependence cycle 1:
// (1): Process: example_example.proc_1_U0
// Channel: example_example.data_channel1_U, FULL // (2): Process: example_example.proc_2_U0
// Channel: example_example.data_array_U, EMPTY
////////////////////////////////////////////////////////////////////////
// Totally 1 cycles detected!
////////////////////////////////////////////////////////////////////////
図 36: デッドロック ビューアー