UPGRADE YOUR BROWSER
We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!
01-21-2019 06:52 AM
I know that by doing the following:
void example(int *a) { #pragma HLS INTERFACE m_axi depth=50 port=a #pragma HLS INTERFACE s_axilite port=a bundle=control #pragma HLS INTERFACE s_axilite port=return bundle=control
int A[50];
for (int i=0; i<50; i++)
A[i] = a[i]; }
I can assign an address to the register "a" located in the AXI Lite interface and my IP automatically knows the address to read the data from.
What I would like to do is something like this:
void example(int *a, int64_t addr_a, int64_t addr_b, int64_t addr_c) { #pragma HLS INTERFACE m_axi depth=150 port=a #pragma HLS INTERFACE s_axilite port=addr_a bundle=control #pragma HLS INTERFACE s_axilite port=addr_b bundle=control #pragma HLS INTERFACE s_axilite port=addr_c bundle=control #pragma HLS INTERFACE s_axilite port=return bundle=control int A[50], B[50], C[50]; a = addr_a; for (int i=0; i<50; i++) A[i] = a[i]; a = addr_b; for (int i=0; i<50; i++) B[i] = a[i]; a = addr_c; for (int i=0; i<50; i++) C[i] = a[i]; }
Thus, with a single AXI4 master interface I could read from 3 different addresses (of course this code does not synthesize). Is it possible to do something like this? And how could I test it in my testbench?
01-23-2019 04:26 AM
Hi @ieronym,
Can you try to have multiple memory arguments which are connected to single Master interface using bundle as below?
void example(int *a, int *b, int *c) { #pragma HLS INTERFACE m_axi depth=150 port=a bundle=gmem0
#pragma HLS INTERFACE m_axi depth=150 port=b bundle=gmem0
#pragma HLS INTERFACE m_axi depth=150 port=c bundle=gmem1 #pragma HLS INTERFACE s_axilite port=return bundle=control int A[50], B[50], C[50]; for (int i=0; i<50; i++) A[i] = a[i]; for (int i=0; i<50; i++) B[i] = b[i]; for (int i=0; i<50; i++) C[i] = c[i]; }
If you are using same bundle value for multiple arguments, it is going to create single AXI4 Master interface.
-Heera
01-22-2019 12:25 PM
Hey @ieronym
I think that code does not synthesize because of the assignment of int64_t to int*. But also, it's not how I would recommend reading from various addresses. The m_axi INTERFACE directive has an offset parameter, which you can set to 'direct' to tell HLS to create an axilite interface to control the address offset.
I would recommend instead creating IP which only has one s_axilite input, then passing three different address into that top level IP.
Here's the top level function I would use:
void example(volatile int *a, int addr_a[50]){ #pragma HLS INTERFACE m_axi depth=50 port=a offset=direct #pragma HLS INTERFACE s_axilite port=addr_a bundle=control #pragma HLS INTERFACE s_axilite port=return bundle=control int i; for(i=0; i < 50; i++){ a[i] = addr_a[i]; } }
And in the testbench, call that function 3 times:
int A_in1[50], A_in2[100], A[150]; //Create data for(i=0; i < 50; i++) A_in1[i] = i; for(i=0; i < 100; i++) A_in2[i] = i+50; // call the function three times with different offsets example(A,A_in1); example(&A[50],A_in2); example(&A[100],&A_in2[50]);
I think this accomplishes what you're looking for, and it should pass C/RTL Co-Sim. However, I think the waveform is confusing. You won't see the address offset change how you expect. Instead, the co-simulation just loads up the appropriate values from the testbench and leaves the address offset alone.
01-23-2019 03:14 AM - edited 01-23-2019 04:07 AM
This example has the same effect as if in my initial example I had called the example function 3 times. This means that, every time, my accelerator does the same thing and I just have to start/wait for it to stop 3 times. Also the "direct" directive has the same result as the "slave" directive except that it creates an additional port and not a register inside the AXI Lite to control the address.
In my case, my accelerator needs to read from 3 different addresses data of different sizes every time it executes (actually it needs to read 2 arrays of different size and a file). This could easily be done with 3 AXI master interfaces but I think this results to redundant utilization, and it could be convenient if the addresses where stored in 3 registers inside the AXI Lite and the accelerator could choose one of the 3 whenever it likes.
For now I think one solution could be to store the data in 3 addresses relative to the address the axi master reads from, but this makes the software developement less agile. I mean, I could just simply call mmap or malloc 3 times and pass 3 addresses to the accelerator, but now I have to do one big malloc, insert the data in a specific way and pass an address and 3 offsets to it.
PS You I right, I should have written a = (int *) addr_a; but this does not synthesize also.
01-23-2019 04:26 AM
Hi @ieronym,
Can you try to have multiple memory arguments which are connected to single Master interface using bundle as below?
void example(int *a, int *b, int *c) { #pragma HLS INTERFACE m_axi depth=150 port=a bundle=gmem0
#pragma HLS INTERFACE m_axi depth=150 port=b bundle=gmem0
#pragma HLS INTERFACE m_axi depth=150 port=c bundle=gmem1 #pragma HLS INTERFACE s_axilite port=return bundle=control int A[50], B[50], C[50]; for (int i=0; i<50; i++) A[i] = a[i]; for (int i=0; i<50; i++) B[i] = b[i]; for (int i=0; i<50; i++) C[i] = c[i]; }
If you are using same bundle value for multiple arguments, it is going to create single AXI4 Master interface.
-Heera
01-23-2019 05:04 AM
You are right. Thank you