c++cvivado-hls

HLS - Array parameter interfaces are different when using a loop


I have the following function with the directive set_directive_interface -mode axis -register -register_mode both "FIR" Result in Vivado HLS:

void Func(int A[2], int B[2], int* Result)
{
    int Temp = 0x00;

    Loop: for(int i = 0x00; i < 0x02; i++)
    {
        Temp += A[i] * B[i];
    }

    *Result = Temp;
}

This function will produce the following report:

enter image description here

I got two memory interfaces with address, CE and a data input. Everything as expected.

Now I use the following function:

void Func(int A[2], int B[2], int* Result)
{
    int Temp = 0x00;

    Temp = A[1] * B[1] + A[0] * B[0];

    *Result = Temp;
}

This will produce the following output:

enter image description here

So why does the second function produce an interface with two RAM ports?


Solution

  • Actually you are doing loop unrolling manually. It's equals to

    void Func(int A[2], int B[2], int* Result)
    {
        int Temp = 0x00;
    
        Loop: for(int i = 0x00; i < 0x02; i++)
        {
    #pragma HLS UNROLL
            Temp += A[i] * B[i];
        }
    
        *Result = Temp;
    }
    

    When you are doing this you access all 4 elements of your arrays at the same time, so Vivado HLS apply partitioning on your arrays and convert them into multiple smaller arrays, each implemented with its own interface. This includes the ability to partition every element of the array into its own scalar element. On the function interface, this results in a unique port for every element in the array. This provides maximum parallel access. Doing so allows multiple elements to be read at the same time and improves the initiation interval. Refer to xilinx UG902 section Array Interfaces for more informations.