C/C++ の定義されていないビヘイビアーは、シミュレーションと合成で異なるビヘイビアーになる可能性があります。次は、そのビヘイビアーの例です。
for (int i=0; i<N; i++) {
int val; // uninitialized value
if (i==0) val=0;
else if (cond) val=1;
// val may have indeterminate value here
A[i] = val; // undefined behavior
val++; // dead code
}
上記の例の場合、i==0
も (cond)
も true でない場合、A[i] は前のループ反復から val の値を取得しません。increment (val++
) になることすらありません。パーティションが完了した後に取得されたスカラー値についても同様です。
このように C/C++ の未定義のビヘイビアーがあると、コードのコンパイル時に GCC と Vitis HLS 間のビヘイビアーが異なる可能性が高くなり、RTL/協調シミュレーションで不一致になります。これは、CPU 用にコンパイルされた GCC では、多くの場合、val
は同じレジスタまたはループの反復間の同じスタック位置に残っているためです。この結果、val
の値がループの反復間で保持されます。
解決策としては、各反復ごとに val を初期化するか (その必要がある場合)、ループよりもなるべく上の方に val
の宣言を移動することです。これで、val が常に初期化され、再利用できるようになります。コンパイラが、未定義の C/C++ ビヘイビアーから特定の定義済み RTL ビヘイビアーを推論することはありません。