ブロッキング API で説明したように、ブロッキング API は、確定的ビヘイビアーと非確定的ビヘイビアーの両方を持つことができます。次のコード例を参照してください。
func1()
{
while(!s.empty()) {
s.read();
}
}
C シミュレーション中は、ストリームへのデータが常に使用可能になるため、while
ループは完了するまで実行されます。ただし、データ ストリームがハードウェアで実行される際にバブルが 1 つある場合、while
ループは終了し、func1
は途中の状態で戻ります。これにより、C シミュレーションと RTL 実行間で非確定的なビヘイビアーが発生します。
このループを正しくインプリメントするには、次の例に示すように、tlast
サイドチャネル信号を使用する必要があります。詳細は、サイドチャネルありの AXI4-Stream インターフェイス を参照してください。
func1()
{
while(!tlast) {
s1.read()
}
}
ブロッキング API は、次のいずれかの方法で使用されると、確定的にできます。
- ケース 1 - FIFO への単純な読み出し/書き込み
-
int data = in.read(); if (data >= 10) out1.write(data); else out2.write(data);
- ケース 2 - ブロッキング API を使用した Full および Empty のチェック
-
この場合、悪影響のあるような計算は実行されません。たとえば、ストリーム、メモリ、スタティック変数の読み出しまたは書き込みには、引き続きブロック ストリーム アクセスのみが使用されるはずです。
void df(hls::stream<...> &s1, hls::stream<...> &s2, ...) { #pragma HLS dataflow p1(s1, ...); p2(s2, ...); ... } void p1(hls::stream<...> &s1, ...) { if (s1.empty()) return; ... = s1.read(); ... } void p2(hls::stream<...> &s2, ...) { if (s2.full()) return; ... s2.write(...); }