Description
This message is generated when a cyclic dependence cannot be computed within II cycles.
The II Violation in module
'hls_complexf_exp_Pip_2' (loop 'VITIS_LOOP_456_1'):
Unable to enforce a carried dependence constraint (II = 4, distance = 1, offset = 1) between
'select' operation 32 bit ('z', hlscaflib.c:457->hlscaflib.c:243) and
'fsub' operation 32 bit ('z', hlscaflib.c:459->hlscaflib.c:243).
Resolution: For help on HLS 200-880 see docs.amd.com/
access/sources/dita/topic?Doc_Version=2026.1%20English&url=ug1448-hlsguidance&
resourceid=200-880.html
INFO: [HLS 200-2198] Existing conflicting constraints include
from 'fsub' operation 32 bit ('z', hlscaflib.c:459->hlscaflib.c:243)
to 'fsub' operation 32 bit ('z', hlscaflib.c:459->hlscaflib.c:243) with distance of 3 (conflict 1
of 2)
INFO: [HLS 200-2198] Existing conflicting constraints include
from 'fsub' operation 32 bit ('z', hlscaflib.c:459->hlscaflib.c:243)
to 'select' operation 32 bit ('z', hlscaflib.c:457->hlscaflib.c:243) with distance of 1 (conflict 2 of 2)
Explanation
The code appears as follows:
fx = 1.0f;
for ( i = 0; i < n; i++ ) {
if ( poweroftwo < z ) {
fx = fx * a[i];
z = z - poweroftwo;
}
poweroftwo = poweroftwo / 2.0f;
}
In this case, the critical dependence cycle, also shown in the GUI as the II violation, involves the following:
- The subtraction
z-poweroftwo, calledfsubabove, which has latency 3 for timing reasons (shown bywith distance of 3above). - The conditional if,
poweroftwo<z, calledselectabove, which has a latency of one cycle (fromfsubtoselect) for timing reasons. It also affects the execution of the subtraction and the value assigned toz, and has latency 1 (fromselecttofsub) because it closes the dependence cycle. All loop carried dependences involve at least one register.
Therefore, the resulting II is 5. Specifying a II of 1, because both
fsub and select can be combinational (albeit with a large delay), results in a
II of 1 and a timing violation for the selected clock period.
The HLS 200-880 message prints the distance (in loop iterations)
between the conflicting operations. Both the previous example and the following
example (which uses arrays instead of scalars) have an iteration distance of 1,
because the write at iteration j affects the read
at iteration j+1.
for (int i=1; i<N; i++)
A[i] = A[i-1];
Recommendation
If Vitis HLS cannot correctly infer the
dependence distance between accesses, or cannot automatically infer that all
accesses are independent and can be fully parallelized, as shown in the following
code example, use #pragma HLS dependence to inform
the scheduler about true and false inter- and intra-iteration dependences. Refer to
pragma HLS dependence for more
information.
for (int i=1; i<N; i++)
A[i-1] = A[i];
If the dependence cycle is due to operations that can be combinational, specifying the II also forces the scheduler to ignore timing constraints. However, the Vitis HLS timing analysis is conservative, because it ignores the effect of logic optimizations. For example, it does not perform constant propagation within hardware resources (a + b has the same cost as a + 1), and it cannot merge two cascaded multiplexers.
When the goal is maximum performance, lower II values and check if Vivado synthesis, placement, and routing can actually meet timing for the more aggressive design. Doing this trades off design time versus quality of results.
For more information and for a definition of terms, refer to Pipeline II Violations.