While arrays can be converted to streams, it can often lead to coding and
synthesis issues as arrays can be accessed in random order while a stream requires a
sequential access pattern where every element is read in order. To avoid such issues,
any time a streaming interface is required, it is highly recommended to use the hls::stream
object as described in Using HLS Streams. Usage of this construct will enforce streaming
semantics in the source code.
However, to convert an array to a stream you should perform all the operations on temp variables. Read the input stream, process the temp variable, and write the output stream, as shown in the example below. This approach lets you preserve the sequential reading and writing of the stream of data, rather than attempting multiple or random reads or writes.
struct A {
short varA;
int varB;
};
void dut(A in[N], A out[N], bool flag) {
#pragma HLS interface mode=axis port=in,out
for (unsigned i=0; i<N; i++) {
A tmp = in[i];
if (flag)
tmp.varB = tmp.varA + 5;
out[i] = tmp;
}
}
If this coding style is not adhered to, it will lead to functional failures of the stream processing.
The recommended method is to define the arguments as hls::stream
objects as shown below:
void dut(hls::stream<A> &in, hls::stream<A> &out, bool flag) {
#pragma HLS interface mode=axis port=in,out
for (unsigned i=0; i<N; i++) {
A tmp = in.read();
if (flag)
tmp.varB = tmp.varA + 5;
out.write(tmp);
}
}