重要: インターフェイスでマルチアクセス ポインターはサポートされていますが、次に説明する問題を回避するため、マルチアクセス ポインターを使用する代わりに、
hls::stream
クラスを使用して必要な動作をインプリメントすることを強くお勧めします。hls::stream
クラスの詳細は、HLS ストリーム ライブラリ を参照してください。最上位関数 (インターフェイス上) の引数リストにポインターが使用されるデザインでは、ポインターを使用して複数回アクセスする場合に、特別な注意事項があります。複数アクセスは、同じ関数でポインターが複数回読み出されたり書き込まれたりすると発生します。
複数回アクセスされるポインターを使用すると、合成後に予期しない動作になることがあります。次の不適切な例では、ポインター d_i
が 4 回読み出され、ポインター d_o
に 2 回書き込まれます。
#include "pointer_stream_bad.h"
void pointer_stream_bad ( dout_t *d_o, din_t *d_i) {
din_t acc = 0;
acc += *d_i;
acc += *d_i;
*d_o = acc;
acc += *d_i;
acc += *d_i;
*d_o = acc;
}
このコードを合成すると、入力ポートが 1 回読み出され、出力ポートに 1 回書き込まれる RTL になります。標準的な C/C++ コンパイラと同様、Vitis HLS では最適化で不必要なポインター アクセスが削除されます。次に、このデザインを検証するテストベンチのコード例を示します。
#include "pointer_stream_bad.h"
int main () {
din_t d_i;
dout_t d_o;
int retval=0;
FILE *fp;
// Open a file for the output results
fp=fopen(result.dat,w);
// Call the function to operate on the data
for (d_i=0;d_i<4;d_i++) {
pointer_stream_bad(&d_o,&d_i);
fprintf(fp, %d %d\n, d_i, d_o);
}
fclose(fp);
// Compare the results file with the golden results
retval = system(diff --brief -w result.dat result.golden.dat);
if (retval != 0) {
printf(Test failed !!!\n);
retval=1;
} else {
printf(Test passed !\n);
}
// Return 0 if the test
return retval;
}
このコードを記述されているとおり、d_i
で 4 回読み出し、d_o
に 2 回書き込むようにインプリメントするには、pointer_stream_better の例に示すようにポインターを volatile
に指定する必要があります。
#include "pointer_stream_better.h"
void pointer_stream_better ( volatile dout_t *d_o, volatile din_t *d_i) {
din_t acc = 0;
acc += *d_i;
acc += *d_i;
*d_o = acc;
acc += *d_i;
acc += *d_i;
*d_o = acc;
}
インターフェイスでマルチアクセス ポインターをサポートするには、次の手順に従います。
- 合成前に C/C++ を検証し、その意図する動作と C/C++ 記述が正しいことを確認します。
- Vitis HLS 内で協調シミュレーションを使用して RTL を検証する場合は、ポインター引数のポート インターフェイスへのアクセス回数を指定する必要があります。