The C/C++ undefined behaviors may lead to a different behavior in simulation and synthesis. An example of this behavior is shown below:
for (int i=0; i<N; i++) {
int val; // uninitialized value
if (i==0) val=0;
else if (cond) val=1;
// val may have indeterminate value here
A[i] = val; // undefined behavior
val++; // dead code
}
In the above example you should not expect that A[i] gets the value of val from
the previous loop iteration if neither i==0
, nor (cond)
are true. You should even not expect that the
increment (val++
) will happen. The same is true for
scalars values obtained after complete partition.
For such C/C++ undefined behavior situations, the behavior between GCC and
Vitis HLS when compiling code is likely to be
different, which will lead to a mismatch during RTL/Co-simulation. This is because in
GCC, compiled for CPU, val
is often left in the same
register or in the same stack location across loop iterations, and therefore the
behavior is that the value of val
is retained between
loop iterations.
The solution is either to initialize val at each iteration (if this is the
expected behavior) or to move the declaration of val
above the loop, as high as necessary, so that its lifetime scope matches the intent
reuse. You should not expect that the compiler will infer a specific defined RTL
behavior from an undefined C/C++ behavior.