C Test Bench and C Source Code - 2021.2 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
English (United States)
Release Date
2021.2 English

Check the C test bench and C source code as shown in the following table.

Table 1. Debugging the C Test Bench and C Source Code
Questions Actions to Take
Does the C test bench check the results and return the value 0 (zero) if the results are correct? Ensure the C test bench returns the value 0 for C/RTL co-simulation. Even if the results are correct, the C/RTL co-simulation feature reports a failure if the C test bench fails to return the value 0.
Is the C test bench creating input data based on a random number? Change the test bench to use a fixed seed for any random number generation. If the seed for random number generation is based on a variable, such as a time-based seed, the data used for simulation is different each time the test bench is executed, and the results can vary.
Are you using pointers on the top-level interface that are accessed multiple times? Use a volatile pointer for any pointer that is accessed multiple times within a single transaction (one execution of the C function). If you do not use a volatile pointer, everything except the first read and last write is optimized out to adhere to the C standard.
Does the C code contain undefined values or perform out-of-bounds array accesses?

Confirm all arrays are correctly sized to match all accesses. Loop bounds that exceed the size of the array are a common source of issues (for example, N accesses for an array sized at N-1).

Confirm that the results of the C simulation are as expected and that output values were not assigned random data values.

Consider using the industry-standard Valgrind application outside of the HLS design environment to confirm that the C code does not have undefined or out-of-bounds issues.

It is possible for a C function to execute and complete even if some variables are undefined or are out-of-bounds. In the C simulation, undefined values are assigned a random number. In the RTL simulation, undefined values are assigned an unknown or X value.

Are you using floating-point math operations in the design?

Check that the C test bench results are within an acceptable error range instead of performing an exact comparison. For some of the floating point math operations, the RTL implementation is not identical to the C. For details, see Verification and Math Functions.

Ensure that the RTL simulation models for the floating-point cores are provided to the third-party simulator. For details, see Simulating IP Cores.

Are you using Xilinx IP blocks and a third-party simulator? Ensure that the path to the Xilinx IP simulation models is provided to the third-party simulator.
Are you using the hls::stream construct in the design that changes the data rate (for example, decimation or interpolation)?

Analyze the design and use the STREAM directive to increase the size of the FIFOs used to implement the hls::stream.

By default, an hls::stream is implemented as a FIFO with a depth of 2. If the design results in an increase in the data rate (for example, an interpolation operation), a default FIFO size of 2 might be too small and cause the C/RTL co-simulation to stall.

Are you using very large data sets in the simulation?

Use the reduce_diskspace option when executing C/RTL co-simulation. In this mode, HLS only executes 1 transaction at a time. The simulation might run marginally slower, but this limits storage and system capacity issues.

The C/RTL co-simulation feature verifies all transaction at one time. If the top-level function is called multiple times (for example, to simulate multiple frames of video), the data for the entire simulation input and output is stored on disk. Depending on the machine setup and OS, this might cause performance or execution issues.