Coding Style for Array to Stream - 2023.2 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 English

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);
  }
}