Vitis HLS implements channels between the tasks as either ping-pong or FIFO buffers, depending on the access patterns of the producer and the consumer of the data:
- For scalar, pointer, and reference parameters, Vitis HLS implements the channel as a FIFO.
- If the parameter (producer or consumer) is an array, Vitis HLS implements the channel as a ping-pong buffer or a FIFO
as follows:
- If Vitis HLS determines the data is accessed in sequential order, Vitis HLS implements the memory channel as a FIFO channel with a depth that is estimated to optimize performance (but can require manual tuning in practice).
- If Vitis HLS is unable to determine
that the data is accessed in sequential order or determines the data is accessed in an
arbitrary manner, Vitis HLS implements the memory
channel as a ping-pong buffer, that is, with a size that is twice (or more, if the depth
of the PIPO is greater than the default 2, as in the case of PIPOs bypassing tasks) the
size of the original array.Note: A ping-pong buffer ensures that the channel always has the capacity to hold all samples without a loss. However, this might be an overly conservative approach in some cases, for example when the producer and the consumer access the data in the same order, and hence the array can be streamed.
To explicitly specify the default channel used between tasks, use the config_dataflow
configuration. This configuration sets the default
channel for all channels in a design. To reduce the size of the memory used in the channel and
allow for overlapping within an iteration, you can use a FIFO. To explicitly set the depth
(that is, number of elements) in the FIFO, use the -fifo_depth
option.
Specifying the size of the FIFO channels overrides the default value that is computed by the tool to attempt to optimize the throughput. If any task in the design can produce or consume samples at a greater rate than the specified size of the FIFO, the FIFOs might become empty (or full). In this case, the design halts operation, because it is unable to read (or write). This might result in or lead to a stalled, deadlock state.
When setting the depth of the FIFOs, Xilinx recommends initially setting the depth as the maximum number data values transferred (for example, the size of the array passed between tasks), confirming the design passes C/RTL co-simulation, and then reducing the size of the FIFOs and confirming C/RTL co-simulation still completes without issues. If RTL co-simulation fails, the size of the FIFO is likely too small to prevent stalling or a deadlock situation.
The Vitis HLS IDE can display a histogram of the occupation of each FIFO/PIPO buffer over time, after RTL co-simulation has been run. This can be useful to help determine the best depth for each buffer.