Visible to Intel only — GUID: fkr1550767758400
Ixiasoft
1. Intel® HLS Compiler Pro Edition Best Practices Guide
2. Best Practices for Coding and Compiling Your Component
3. FPGA Concepts
4. Interface Best Practices
5. Loop Best Practices
6. fMAX Bottleneck Best Practices
7. Memory Architecture Best Practices
8. System of Tasks Best Practices
9. Datatype Best Practices
10. Advanced Troubleshooting
A. Intel® HLS Compiler Pro Edition Best Practices Guide Archives
B. Document Revision History for Intel® HLS Compiler Pro Edition Best Practices Guide
5.1. Reuse Hardware By Calling It In a Loop
5.2. Parallelize Loops
5.3. Construct Well-Formed Loops
5.4. Minimize Loop-Carried Dependencies
5.5. Avoid Complex Loop-Exit Conditions
5.6. Convert Nested Loops into a Single Loop
5.7. Place if-Statements in the Lowest Possible Scope in a Loop Nest
5.8. Declare Variables in the Deepest Scope Possible
5.9. Raise Loop II to Increase fMAX
5.10. Control Loop Interleaving
Visible to Intel only — GUID: fkr1550767758400
Ixiasoft
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.