ポインター演算 (pointer_arith) を使用すると、RTL に合成可能なインターフェイスが制限されます。次の例は同じコードですが、データ値を 2 つ目の値から累積するために、単純なポインター演算が使用されている点が異なります。
#include "pointer_arith.h"
void pointer_arith (dio_t *d) {
static int acc = 0;
int i;
for (i=0;i<4;i++) {
acc += *(d+i+1);
*(d+i) = acc;
}
}
次に、この例をサポートするテストベンチのコード例を示します。累積を実行するループが pointer_arith
関数内に含まれるようになったので、テストベンチにより配列 d[5]
で指定されたアドレス空間に適切な値が指定されます。
#include "pointer_arith.h"
int main () {
dio_t d[5], ref[5];
int i, retval=0;
FILE *fp;
// Create input data
for (i=0;i<5;i++) {
d[i] = i;
ref[i] = i;
}
// Call the function to operate on the data
pointer_arith(d);
// Save the results to a file
fp=fopen(result.dat,w);
printf( Din Dout\n, i, d);
for (i=0;i<4;i++) {
fprintf(fp, %d \n, d[i]);
printf( %d %d\n, ref[i], d[i]);
}
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;
}
これは、シミュレーションすると、次のような出力になります。
Din Dout
0 1
1 3
2 6
3 10
Test passed!
ポインター演算では、ばらばらの順番でポインター データにアクセスします。一方、ワイヤ、ハンドシェイク、または FIFO インターフェイスは、次のように順番どおりにのみデータにアクセスできます。
- ワイヤ インターフェイスは、デザインがデータを消費するか書き込む準備ができたときに、データを読み出します。
- ハンドシェイクおよび FIFO インターフェイスは、制御信号により処理が許可されたときに読み出しおよび書き込みを実行します。
どちらの場合も、データは順序どおりに要素 0 から到着し、書き込まれる必要があります。ポインター演算を使用したインターフェイスの例では、インデックス 1 から読み出しが開始します (i
は 0 で開始されるので、0+1=1)。これは、テストベンチの配列 d[5]
の 2 つ目の要素です。
これがハードウェアにインプリメントされる際には、何らかのデータ インデックス形式が必要になります。Vitis HLS は、ワイヤ、ハンドシェイクまたは FIFO インターフェイスを使用するとこれはサポートされません。
または、ポインターではなく、次の例のようにインターフェイスの配列を使用してコードを変更する必要があります。これは、RAM インターフェイス (ap_memory
) を使用して合成できます。このインターフェイスは、アドレスを付けてデータのインデックスを作成できるので、順序どおりでなくても実行できます。
ワイヤ、ハンドシェイク、FIFO インターフェイスは、ストリーミング データでのみ使用可能で、データのインデックスを 0 から順に作成する場合以外は、ポインター演算と共に使用することはできません。
#include "array_arith.h"
void array_arith (dio_t d[5]) {
static int acc = 0;
int i;
for (i=0;i<4;i++) {
acc += d[i+1];
d[i] = acc;
}
}