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

ID 683152
Date 3/28/2022
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

5.1. Reuse Hardware By Calling It In a Loop

Loops are a useful way to reuse hardware. If your component function calls another function, the called function will be the top-level component. Calling a function multiple times results in hardware duplication.

For example, the following code example results in multiple hardware copies of the function foo in the component myComponent because the function foo is inlined:
int foo(int a)
{
    return 4 + sqrt(a) /
}

component
void myComponent()
{
  ...
  int x =
  x += foo(0);
  x += foo(1);
  x += foo(2);
  ...
}
If you place the function foo in a loop, the hardware for foo can be reused for each invocation. The function is still inlined, but it is inlined only once.
component
void myComponent()
{
  ...
  int x = 0;
#pragma unroll 1
  for (int i = 0; i < 3; i++)
  {
    x += foo(i);
  }
  ...
}
You could also use a switch/case block if you want to pass your reusable function different values that are not related to the loop induction variable i:
component
void myComponent()
{
  ...
  int x = 0;
#pragma unroll 1
  for (int i = 0; i < 3; i++)
  {
     int val = 0;
     switch(i)
     {
     case 0:
         val = 3;
         break;
     case 1:
         val = 6;
         break;
     case 2:
         val = 1;
         break;
     }
     x += foo(val);
  }
  ...
}

You can learn more about reusing hardware and minimizing inlining be reviewing the resource sharing tutorial available in <quartus_installdir>/hls/examples/tutorials/best_practices/resource_sharing_filter.