Canonical Body - 2023.2 English

Vitis High-Level Synthesis User Guide (UG1399)

Document ID
Release Date
2023.2 English

Inside the canonical region, the canonical body should follow these guidelines:

  1. Use a local, non-static scalar or an array variable. A local variable is declared inside the function body (for dataflow in a function) or loop body (for dataflow inside a loop). Refer to Limitations of Control-Driven Task-Level Parallelism for additional limitations on arrays.
  2. A sequence of function calls that pass data forward (with no feedback unless using hls::stream/hls::stream_of_blocks), from a function to one that is lexically later, under the following conditions:
    1. Variables (except scalar) can have only one reading process and one writing process.
    2. Use write before read (producer before consumer) if you are using local non-scalar variables, which then become channels. For scalar variables, both write before read and read before write are allowed.
    3. Use read before write (consumer before producer) if you are using function arguments. Any intra-body anti-dependencies must be preserved by the design.
    4. Function return type must be void.
    5. No loop-carried dependencies are allowed among different processes via variables except when FIFOs are used. Forward loop-carried dependencies are supported for arrays transformed to streams and both forward and backward dependencies are supported for hls::streams.
      • Except when these dependencies exist across successive calls to the top function (i.e., inout argument written by one iteration and read by the following iteration).
    6. No control whatsoever is supported inside a dataflow region, except inside function calls (that define processes).
      • For canonical dataflow, there should be no conditionals, no loops, no return or goto statements, and no C++ exceptions such as throw.