cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
pmousoul
Explorer
Explorer
3,904 Views
Registered: ‎05-21-2017

SDSoC 2016.4: Variable size array synthesis

Jump to solution

Hello!

I'm trying to synthesize the following function, which it is described in my "main.hpp" as:
#pragma SDS data copy(veco[0:pM*pHout*pWout], bia[0:pM])
void hbias(float* veco, int pM, int pHout, int pWout, float* bia);

 

Due to the functionality of my "main.cpp" the "int pM, int pHout, int pWout" change at runtime, but are known during compile time (e.g. I add bias to the numbers of different sized arrays, which their sizes are known a priori). I would like to have one hardware function to add "bias" to the elements of each of them and not having to implement a hardware function for each different array size.

So, after selecting the "hbias" function for hardware synthesis, I get the following error:
ERROR: [SYNCHK 200-61] hbias.cpp:18: unsupported memory access on variable 'bia' which is (or contains) an array with unknown size at compile time.

Does anyone have an idea of what I'm I doing wrong?

 

 

Thanks,

Panos

Without proper software tools the hardware is unusable no matter how good and well designed it is.
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
sskalick
Xilinx Employee
Xilinx Employee
6,114 Views
Registered: ‎06-29-2015

Hi pmousoul,

 

The problem is given your function declaration like:

 

#pragma SDS data copy(veco[0:pM*pHout*pWout], bia[0:pM])
void hbias(float* veco, int pM, int pHout, int pWout, float* bia);

SDSoC will try and implement the arguments veco and bia as BRAMs. To implement an argument as a BRAM, SDSoC needs to know the maximum depth that argument could have. You can specify this to SDSoC by changing your pointers to arrays like:

 

#pragma SDS data copy(veco[0:pM*pHout*pWout], bia[0:pM])
void hbias(float veco[MAX_VECO], int pM, int pHout, int pWout, float bia[MAX_BIA]);

 

Then SDSoC will generate a system with argument veco implemented as a BRAM that uses enough resources to store MAX_VECO elements statically, and then only use pM*pHout*pWout elements at runtime (which must be less than or equal to MAX_VECO). 

 

Or, if your access to veco and bia are sequential/in-order you can use the access_pattern pragma to tell SDSoC to use a FIFO for the argument like:

 

#pragma SDS data access_pattern(veco:SEQUENTIAL, bia:SEQUENTIAL)
#pragma SDS data copy(veco[0:pM*pHout*pWout], bia[0:pM])
void hbias(float* veco, int pM, int pHout, int pWout, float* bia);

In this case, the max depth (MAX_VECO) doesnt matter, since the data will stream into the accelerator. 

 

Sam

View solution in original post

4 Replies
sskalick
Xilinx Employee
Xilinx Employee
6,115 Views
Registered: ‎06-29-2015

Hi pmousoul,

 

The problem is given your function declaration like:

 

#pragma SDS data copy(veco[0:pM*pHout*pWout], bia[0:pM])
void hbias(float* veco, int pM, int pHout, int pWout, float* bia);

SDSoC will try and implement the arguments veco and bia as BRAMs. To implement an argument as a BRAM, SDSoC needs to know the maximum depth that argument could have. You can specify this to SDSoC by changing your pointers to arrays like:

 

#pragma SDS data copy(veco[0:pM*pHout*pWout], bia[0:pM])
void hbias(float veco[MAX_VECO], int pM, int pHout, int pWout, float bia[MAX_BIA]);

 

Then SDSoC will generate a system with argument veco implemented as a BRAM that uses enough resources to store MAX_VECO elements statically, and then only use pM*pHout*pWout elements at runtime (which must be less than or equal to MAX_VECO). 

 

Or, if your access to veco and bia are sequential/in-order you can use the access_pattern pragma to tell SDSoC to use a FIFO for the argument like:

 

#pragma SDS data access_pattern(veco:SEQUENTIAL, bia:SEQUENTIAL)
#pragma SDS data copy(veco[0:pM*pHout*pWout], bia[0:pM])
void hbias(float* veco, int pM, int pHout, int pWout, float* bia);

In this case, the max depth (MAX_VECO) doesnt matter, since the data will stream into the accelerator. 

 

Sam

View solution in original post

pmousoul
Explorer
Explorer
3,681 Views
Registered: ‎05-21-2017

Sam,

thank you very much for the detailed answer!


I have one more question to make related to the third option you described:


@sskalick wrote:

...

Or, if your access to veco and bia are sequential/in-order you can use the access_pattern pragma to tell SDSoC to use a FIFO for the argument like:

 

#pragma SDS data access_pattern(veco:SEQUENTIAL, bia:SEQUENTIAL)
#pragma SDS data copy(veco[0:pM*pHout*pWout], bia[0:pM])
void hbias(float* veco, int pM, int pHout, int pWout, float* bia);

In this case, the max depth (MAX_VECO) doesnt matter, since the data will stream into the accelerator. 

 

Sam


In the above case, do I have to consume the veco[]/bia[] data in my hardware function, before I'll process it? The way you describe it, I should not consume the data in a temporary buffer in my hardware function, because this infers local memory (or should I consume it inferring a FIFO?). Could you please provide (or give a pointer in the documentation) of a complete example of a hardware function which consumes data in a streaming fashion because of the sequential nature of the processed data?


Is the following a valid streaming hardware function description taken into account the above declaration you provided (both arrays are consumed sequentially/in-order (not with the same pace, but still sequentially))?

 

    void hbias(float* veco, int pM, int pHout, int pWout, float* bia)
    {
    	for (int k=0; k<pM*pHout*pWout; k++)
    	{
                #pragma HLS PIPELINE II=1
int idx = k/(pHout*pWout); veco[k] += bia[idx]; } }

 

Thank you very much for your time,
Panos

Without proper software tools the hardware is unusable no matter how good and well designed it is.
0 Kudos
sumitswaggyboy
Visitor
Visitor
3,625 Views
Registered: ‎06-02-2017
did you get the solution ?
0 Kudos
sumitswaggyboy
Visitor
Visitor
3,611 Views
Registered: ‎06-02-2017
Can anyone explain or answer the last query by pmousoul in this thread ?
0 Kudos