Flushing Pipelines and Pipeline Types - 2023.2 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
Release Date
2023.2 English

Flushing Pipelines

Pipelines continue to execute as long as data is available at the input of the pipeline. If there is no data available to process, the pipeline stalls. This is shown in the following figure, where the Input Data Valid signal goes low to indicate there is no more valid input data. Once the signal goes high, indicating there is new data available to process, the pipeline continues operation.

Figure 1. Loop Pipelining with Stall

In some cases, it is desirable to have a pipeline that can be “emptied” or “flushed.” The flush option is provided to perform this. When a pipeline is “flushed” the pipeline stops reading new inputs when none are available (as determined by a data valid signal at the start of the pipeline) but continues processing, shutting down each successive pipeline stage, until the final input has been processed through to the output of the pipeline.

As described below, the tool automatically selects the right pipeline style to use for a given pipelined loop or function. However, you can override this default behavior by using the syn.compile.pipeline_style configuration command to specify the default pipeline style.

You can also specify the pipeline style for functions or loops with the PIPELINE pragma or directive. This option applies to the specific scope of the pragma or directive and does not change the global default assigned by syn.compile.pipeline_style.

Both stp and flp types of pipelines use the standard pipeline logic where the hardware pipeline created use various kinds of blocking signals to stall the pipeline. These blocking signals often become the driver of a high-fanout net, especially on pipelines that are deep in the number of physical stages and work on significant data sizes. Such high fanout nets, when they are created, are the prime cause of timing closure issues which cannot be fixed in RTL/Logic Synthesis or during Place-and-Route. To solve this issue, a new type of pipeline implementation called free-running pipeline (or frp) was created. The free-running pipeline is the most efficient architecture for handling a pipeline that operates with blocking signals. This is because

  • It completely eliminates the blocking signal connections to the register enables
  • It is a fully flushable pipeline, which allows bubbling invalid transactions
  • Unlike the previous architectures which distribute fanouts (across flops), this reduces the fanouts
  • It does not rely on the synthesis and/or place and route optimizations such as flop cloning
  • This helps PnR by creating a structure where the wire length is reduced along with the reduction of the high fanouts

But there is a cost associated with this fanout reduction:

  • the size of the FIFO buffers required for the blocking output ports causes additional resource usage.
  • the mux delay at those blocking output ports
  • the potential performance hit due to early validation of forward-pressure triggers
Important: The free-running pipeline (frp) can only be called from within a DATAFLOW region. The frp style cannot be applied to a loop that is called in a sequential or a pipelined region.

Pipeline Types

The three types of pipelines available in the tool are summarized in the following table. The tool automatically selects the right pipeline style to use for a given pipelined loop or function. If the pipeline is used with hls::tasks, the flushing pipeline (FLP) style is automatically selected to avoid deadlocks. If the pipeline control requires high fanout, and meets other free-running requirements, the tool selects the free-running pipeline (FRP) style to limit the high fanout. Finally, if neither of the above cases apply, then the standard pipeline (STP) style is selected.

Table 1. Pipelining Types
Name Stalled Pipeline Free-Running/ Flushable Pipeline Flushable Pipeline
Use cases
  • When there is no timing issue due to high fanout on pipeline control
  • When flushable is not required (such as no performance or deadlock issue due to stall)
  • When you need better timing due to fanout to register enables from pipeline control
  • When flushable is required for better performance or avoiding deadlock
  • Can only be called from a dataflow region.
When flushable is required for better performance or avoiding deadlock.
Pragma/Directive #pragma HLS pipeline style=stp #pragma HLS pipeline style=frp #pragma HLS pipeline style=flp
Global Setting syn.compile.pipeline_style=stp (default) syn.compile.pipeline_style=frp syn.compile.pipeline_style=flp
  • Not flushable, hence it can:
    • Cause more deadlocks in dataflow
    • Prevent already computed outputs from being delivered, if the inputs to the next iterations are missing
  • Timing issues due to high fanout on pipeline controls
  • Moderate resource increase due to FIFOs added on outputs
  • Requires at least one blocking I/O (stream or ap_hs).
  • Not all pipelining scenarios and I/O types are supported.
  • Can have larger II
  • Greater resource usage due to less sharing when II>1
  • Default pipeline. No usage constraints.
  • Typically the lowest overall resource usage.
  • Better timing due to
    • Less fanout
    • Simpler pipeline control logic
  • Flushable
  • Flushable
  • Avoids deadlock
Important: Flushing pipelines (flp) are compatible with the rewind option specified in the PIPELINE pragma or directive when the syn.compile.enable_auto_rewind configuration command is also enabled.