Stream FIFO Depth - 2020.2 English

Versal ACAP AI Engine Programming Environment User Guide (UG1076)

Document ID
UG1076
Release Date
2020-11-24
Version
2020.2 English

The AI Engine architecture uses stream data extensively for DMA-based I/O, for communicating between two AI Engines, and for communicating between the AI Engine and the programmable logic (PL). This raises the potential for a resource deadlock when the data flow graph has reconvergent stream paths. If the pipeline depth of one path is longer than the other, the producer kernel can stall and might not be able to push data into the shorter path because of back pressure. At the same time, the consumer kernel is waiting to receive data on the longer path due to the lack of data. If the order of data production and consumption between two stream paths is different, a deadlock can happen even between two kernels that are directly connected with two stream paths. The following figure illustrates the paths.

Figure 1. Producer and Consumer Kernels with Reconvergent Streams

If the producer kernel is trying to push data on stream S1 and runs into back pressure while the consumer kernel is still trying to read data from stream S2, a deadlock occurs. A general way to fix this situation is to create more buffering in the paths that have back pressure in the source code by using a fifo_depth constraint on a connection.

p = kernel::create(producer);
c = kernel::create(consumer);
connect<stream> s1(p.out[0], c.in[0]);
connect<stream> s2(p.out[1], c.in[1]);
fifo_depth(s1) = 20;
fifo_depth(s2) = 10;

Specifying FIFO Depth on the Producer and Consumer Side

Specifying a single fifo_depth value assigns the FIFO to the destination side, or consumer kernel. You can also specify two values for fifo_depth, assigning the first value to the source side, the producer, and the second value to the consumer for greater control of the FIFO implementation. Both source and destination can be all AI Engine kernels, or a combination of AI Engine kernels and PL kernels. For example:

fifo_depth(stream_input1) = {10, 6}; // producer fifo depth=10, consumer fifo depth=6
fifo_depth(stream_input2) = {8, 20};
Tip: If both the source and destination are AI Engine kernels, or both are PL kernels, the source-side FIFO depth and destination-side FIFO depth are added to get a single total FIFO depth.