Intel® High Level Synthesis Compiler Pro Edition: Best Practices Guide

ID 683152
Date 4/01/2024
Public
Document Table of Contents

8.4.2. Explicitly Add Buffer Capacity to Your Design When Needed

When the Intel® HLS Compiler cannot infer the optimal capacity requirements, you can explicitly add buffer capacity to your design by specifying a value for the capacity parameter of the ihc::launch and ihc::collect functions.

Adding Capacity When Launching Task Functions

Consider specifying the capacity parameter of the ihc::launch call if you see stall patterns in your simulation waveforms that indicate an imbalance between the following things:
  • Any back-pressure introduced by the task function
  • How often the caller launches the task function

The figure Data Flow of Multiple Component Invocations Through a System of Tasks in Enable the Intel HLS Compiler to Infer Data Path Buffer Capacity Requirements shows the block diagram of such a design.

Adding Capacity When Collecting Task Functions

Consider specifying the capacity parameter of the ihc::collect call if you see stall patterns in your design waveforms that indicate a difference in the following things:
  • The cadence of data production in the task function
  • The cadence reading that data by the caller function

Deciding When To Specify The capacity Parameter

When you decide whether to add ihc::launch or ihc::collect capacity, ask yourself the following questions:
  • Do any tasks spend cycles stalled waiting for input data to reach them?

    If yes, these tasks require launch capacity equal to the number of cycles it takes input data to reach the task.

    Adding launch capacity allows stalled tasks to buffer their start signals so that they do not stall the other tasks that are scheduled to launch on the same cycle.

    Because the consumer task depends on data from the producer task function, the consumer task stalls until data from the producer task reaches it, so you should add capacity to the ihc::launch call for the consumer task.

  • Do any tasks finish their first execution before the slowest task in the design (that is, the task that produces its initial return signal last) finishes its first execution?

    If yes, the tasks that finish before the slowest task in the design finishes require additional collect capacity.

    Add capacity equal to the number of cycles between when the task produces its first return signal and when the slowest task in the design produces its first return signal.

    When you add collect capacity, tasks can buffer their return signals. Buffering the return signal consumes it from the task, which allows the task to produce more return signals without stalling.

Typically, tasks that communicate only through a return value do not require buffer capacity. The top-level component handles the synchronization of the communication of task functions, as the following figure shows:



When task functions communicate via streams, you might need to add capacity when there is a chance that a task might be launched before its inputs are ready. In the following diagram, you might need to add launch capacity to the consumer task:



For an example of adding buffer capacity to a design, refer the following tutorial:
<quartus_installdir>/hls/examples/tutorials/system_of_tasks/launch_and_collect_capacity