Vitis HLS transforms the region to apply the DATAFLOW optimization. For more predictibility of the resulting dataflow network, AMD recommends writing the code inside this region (referred to as the canonical region) using canonical forms. There are two main canonical forms for the dataflow optimization:
-
The canonical form for a function where sub-functions are not inlined. Note that these subfunctions can themselves be dataflow in function regions or dataflow inside loop regions. Note also that variable initialization (including those performed automatically by constructors) or passing expressions by value to processes are not part of canonical form. Vitis HLS does its best to implement the resulting dataflow but, if the code is not in canonical form, you should always check the GUI dataflow viewer and the cosimulation timeline trace to ensure that the dataflow happens as expected and the achieved performance is as expected.
void dataflow(Input0, Input1, Output0, Output1) { #pragma HLS dataflow UserDataType C0, C1, C2; // UserDataType can be scalars or arrays func1(Input0, Input1, C0, C1); // read Input0, read Input1, write C0, write C1 func2(C0, C1, C2); // read C0, read C1, write C2 func3(C2, Output0, Output1); // read C2, write Output0, write Output1 }
- Dataflow inside a loop body enclosed in a function without any other code but
the loop. For the
for
loop (where no function inside is inlined), the integral loop variable should have:- The initial value is declared in the loop header and set to 0.
- The loop bound is a non-negative numerical constant or scalar argument of the function that encloses the loop.
- Increment by 1.
- Dataflow pragma needs to be inside the loop as shown below.
void dataflow(Input0, Input1, Output0, Output1) { for (int i = 0; i < N; i++) { #pragma HLS dataflow UserDataType C0, C1, C2; // UserDataType can be scalars or arrays func1(Input0, Input1, C0, C1); // read Input0, read Input1, write C0, write C1 func2(C0, C0, read C1, C2); // read C0, read C0, read C1, write C2 func3(C2, Output0, Output1); // read C2, write Output0, write Output1 } }