Loop Flatten - 2020.2 English

Vitis HLS Messaging (UG1448)

Document ID
UG1448
Release Date
2020-11-24
Version
2020.2 English

Description

The tool is informing the user that the specified loop nest is an imperfect loop and cannot be flattened.

Explanation

  • Imperfect loop nests cannot be flattened by the tool. This results in additional clock cycles to enter and exit the loops.
  • Imperfect loops are loops that show the following characteristics:
    • The innermost loop has a variable bound.
    • The loop body is not exclusively inside the inner loop
  • In the small example shown here, because of an imperfect loop nest. it will take one cycles to enter the loop and one cycle to exit the loop copy_A. This creates an additional n_elements * 2 clock cycles.
#define BUFFER_SIZE 256
  
void foo(int *a, int *b) {
  // n_elements: variables
  outCopyA: for (int i = 0 ; i < n_elements ; i += BUFFER_SIZE) {
              int size = BUFFER_SIZE;
     copyA: for (int j = 0 ; j < size/2 ; ++j) // 1 cycle to enter the loop
        {
                b[j*2] = a[i+j*2]; // even index for b
                b[(j*2)|1] = a[i+((j*2)|1)]; // odd index for b
       }
  }

Bursting: At times bursting optimization may result in introducing code in between the loops which may cause this warning. This is a limitation in the current version of the tool and will be addressed in a future releases.

Solution

This message is to inform the user that the loop is an imperfect loop nest and the user needs to convert it to a perfect loop or a semi-perfect loop nest.

HLS provides the loop_flatten constraint to allow labeled perfect and semiperfect nested loops to be flattened, removing the need to re-code for optimal hardware performance and reducing the number of cycles it takes to perform the operations in the loop.

Perfect loop nest: Only the innermost loop has loop body content, there is no logic specified between the loop statements and all the loop bounds are constant. Example is shown below.

void foo_top { a, b, c, d} {
 ...
 Outer: while(j<100)
 Inner: while(i<6) // 1 cycle to enter inner
 ...
 LOOP_BODY
 ...
 } // 1 cycle to exit inner
 }
 ...
}

Semi-perfect loop nest: Only the innermost loop has loop body content, there is no logic specified between the loop statements but the outermost loop bound can be a variable.