Loop Flatten - 2024.1 English

Vitis HLS Messaging (UG1448)

Document ID
UG1448
Release Date
2024-05-30
Version
2024.1 English

Description

Warning: [200-960] Cannot flatten a loop nest %s.
This message reports 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 have the following characteristics:
  • The innermost loop has a variable bound.
  • The loop body is not exclusively inside the inner loop

The following example shows an imperfect loop nest. It will take one cycle 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

The solution is to convert the imperfect loop to a perfect loop or a semi-perfect loop nest.

HLS provides the loop_flatten constraint to allow labeled perfect and semi-perfect nested loops to be flattened. This removes the need to re-code for optimal hardware performance and reduces 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. The following is an example:

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.