pragma HLS unroll
Description
Unroll loops to create multiple independent operations rather than a single collection of operations. TheUNROLL
pragma transforms loops by creating multiples copies of the loop body in the RTL design, which allows some or all loop iterations to occur in parallel.
Loops in the C/C++ functions are kept rolled by default. When loops are rolled, synthesis creates the logic for one iteration of the loop, and the RTL design executes this logic for each iteration of the loop in sequence. A loop is executed for the number of iterations specified by the loop induction variable. The number of iterations might also be impacted by logic inside the loop body (for example,break
conditions or modifications to a loop exit variable). Using theUNROLL
pragma you can unroll loops to increase data access and throughput.
TheUNROLL
pragma allows the loop to be fully or partially unrolled. Fully unrolling the loop creates a copy of the loop body in the RTL for each loop iteration, so the entire loop can be run concurrently. Partially unrolling a loop lets you specify a factorN, to createNcopies of the loop body and reduce the loop iterations accordingly. To unroll a loop completely, the loop bounds must be known at compile time. This is not required for partial unrolling.
for(int i = 0; i < X; i++) { pragma HLS unroll factor=2 a[i] = b[i] + c[i]; }
break
construct is used to ensure the functionality remains the same, and the loop exits at the appropriate point:
for(int i = 0; i < X; i += 2) { a[i] = b[i] + c[i]; if (i+1 >= X) break; a[i+1] = b[i+1] + c[i+1]; }
Because the maximum iteration countXis a variable, Vivado HLS may not be able to determine its value and so adds an exit check and control logic to partially unrolled loops. However, if you know that the specified unrolling factor, 2 in this example, is an integer factor of the maximum iteration countX, theskip_exit_check
option lets you remove the exit check and associated logic. This helps minimize the area and simplify the control logic.
config_unroll
command. See
config_unrollin the
Vivado Design Suite User Guide: High-Level Synthesis(UG902) for more information.
Syntax
Place the pragma in the C/C++ source within the body of the loop to unroll.
#pragma HLS unroll factor= region skip_exit_check
Where:
factor=
: Specifies a non-zero integer indicating that partial unrolling is requested. The loop body is repeated the specified number of times, and the iteration information is adjusted accordingly. Iffactor=
is not specified, the loop is fully unrolled.region
: An optional keyword that unrolls all loops within the body (region) of the specified loop, without unrolling the enclosing loop itself.skip_exit_check
: An optional keyword that applies only if partial unrolling is specified withfactor=
. The elimination of the exit check is dependent on whether the loop iteration count is known or unknown:- Fixed (known) bounds: No exit condition check is performed if the iteration count is a multiple of the factor. If the iteration count is not an integer multiple of the factor, the tool:
- Prevents unrolling.
- Issues a warning that the exit check must be performed to proceed.
- Variable (unknown) bounds: The exit condition check is removed as requested. You must ensure that:
- The variable bounds is an integer multiple of the specified unroll factor.
- No exit check is in fact required.
- Fixed (known) bounds: No exit condition check is performed if the iteration count is a multiple of the factor. If the iteration count is not an integer multiple of the factor, the tool:
Example 1
loop_1
in function
foo
. Place the pragma in the body of
loop_1
as shown:
loop_1: for(int i = 0; i < N; i++) { #pragma HLS unroll a[i] = b[i] + c[i]; }
Example 2
loop_2
of function
foo
, and removes the exit check:
void foo (...) { int8 array1[M]; int12 array2[N]; ... loop_2: for(i=0;i
Example 3
loop_1
in function
foo
, but not
loop_1
itself due to the presence of the
region
keyword:
void foo(int data_in[N], int scale, int data_out1[N], int data_out2[N]) { int temp1[N]; loop_1: for(int i = 0; i < N; i++) { #pragma HLS unroll region temp1[i] = data_in[i] * scale; loop_2: for(int j = 0; j < N; j++) { data_out1[j] = temp1[j] * 123; } loop_3: for(int k = 0; k < N; k++) { data_out2[k] = temp1[k] * 456; } } }
See Also
- pragma HLS loop_flatten
- pragma HLS loop_merge
- pragma HLS loop_tripcount
- Vivado Design Suite User Guide: High-Level Synthesis(UG902)
- opencl_unroll_hint
- SDAccel Environment Optimization Guide(UG1207)