cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
futuristic
Participant
Participant
3,553 Views
Registered: ‎11-02-2017

How to pass an array/pointer to HLS IP in SDK

Folks,

 

I need help on how I can pass an array/pointer to HLS IP in SDK. I know that if it is a scalar value I can use <>_get/set(*Instance) function but how to do it when you want to pass a memory region as array/pointer. I tired the following with no success.

 

#define DRAM_ADDR 0x00100000
u32 val;
u32* DRAM = (u32*)DRAM_ADDR;
XSimple_ddr simple_ddr;
int* res_hw;
memcpy(DRAM, data, 100*sizeof(int)); //data is an array with 100 elements
for(int i=0; i<100; i++) { xil_printf("\nRead Memory: %d, %d, %d\n", res_hw[i], DRAM[i], DRAM[i+100]); } XSimple_ddr_Set_DRAM(&simple_ddr, DRAM); XSimple_ddr_Set_num(&simple_ddr, 100); if (XSimple_ddr_IsReady(&simple_ddr)) print("HLS peripheral is ready. Starting... "); else { print("!!! HLS peripheral is not ready! Exiting...\n\r"); exit(-1); } XSimple_ddr_Start(&simple_ddr); print("Detected HLS peripheral complete. Result received.\n\r"); do { res_hw = (int*)XSimple_ddr_Get_DRAM(&simple_ddr); } while (!XSimple_ddr_IsReady(&simple_ddr)); xil_printf("------------------Read after IP------------------------\n"); for(int i=0; i<100; i++) { xil_printf("\nRead Memory: %d, %d, %d", (res_hw[i]), DRAM[i], DRAM[i+100]); }

The IP is: 

void simple_ddr(int* DRAM, int num)
{
#pragma HLS INTERFACE m_axi port=DRAM depth=400 offset=slave bundle=DRAMBUS register
#pragma HLS INTERFACE s_axilite port=num bundle=CONFIGBUS register
#pragma HLS INTERFACE s_axilite port=return bundle=CONFIGBUS register

	int BRAM[100];
	int j;
	memcpy(BRAM, DRAM, num*sizeof(int));
	int val=0;
	for(j=0; j<num; j++)
	{
		BRAM[j]=7 + val;
		val++;
	}
	memcpy(DRAM+num, BRAM, num*sizeof(int));
}

So what I observed is that the following line returns the base address of the DDR and the memory region starting from (base address + num) doesn't have the modifies data from the HLS IP. 

res_hw = (int*)XSimple_ddr_Get_DRAM(&simple_ddr);

Cheers!

 

12 Replies
hbucher
Scholar
Scholar
3,536 Views
Registered: ‎03-22-2016

@futuristic  Use the offset=slave option on the INTERFACE pragma. 

See page 129 for an example

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_1/ug902-vivado-high-level-synthesis.pdf

Then HLS will generate a AXI-LITE register that you can set the pointer's memory offset from SDK.

vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
futuristic
Participant
Participant
3,527 Views
Registered: ‎11-02-2017

Thanks! Modified the Pragmas to these: 

 

#pragma HLS INTERFACE m_axi port=DRAM depth=400 offset=slave bundle=DRAMBUS register
#pragma HLS INTERFACE s_axilite port=num bundle=CONFIGBUS_1 register
#pragma HLS INTERFACE s_axilite port=return bundle=CONFIGBUS_2 register
#pragma HLS INTERFACE s_axilite port=DRAM bundle=CONFIGBUS_2

 

Still the (DRAM + num) memory region has garbage data. 

 

Below is the circuit. Capture.PNG

0 Kudos
Reply
hbucher
Scholar
Scholar
3,501 Views
Registered: ‎03-22-2016

@futuristic Now you have to replace your IP with the newly generated one. In my experience, you are better deleting simple_ddr_0 and placing it again as upgrading is a pain.

Have a look at the IP folder and look at the generated C sources for SDK. 

You should see C-functions related to setting the offset.

 

vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
0 Kudos
Reply
futuristic
Participant
Participant
3,452 Views
Registered: ‎11-02-2017

@hbucher that is actually what I did. I can't tell where the problem is. 

 

I don't know why res_hw = (int*)XSimple_ddr_Get_DRAM(&simple_ddr); is not returning a memory region with the updated data from the IP. 

 

BTW, the IP doesn't pass the Co-simulation with the following error message: 

 

ERROR: System recieved a signal named SIGSEGV and the program has to stop immediately!
This signal was generated when a program tries to read or write outside the memory that is allocated for it, or to write memory that can only be read.
Possible cause of this problem may be: 1) the depth setting of pointer type argument is much larger than it needed; 2)insufficient depth of array argument; 3)null pointer etc.
Current execution stopped during CodeState = ENTER_WRAPC_PC.
You can search CodeState variable name in apatb*.cpp file under ./sim/wrapc dir to locate the position.

ERROR: [COSIM 212-379] Detected segmentation violation, please check C tb.
ERROR: [COSIM 212-362] Aborting co-simulation: C TB post check failed.
ERROR: [COSIM 212-4] *** C/RTL co-simulation finished: FAIL ***

I ignored the above message to generate the RTL IP. Would that be something I need to investigate more. 

 

What would be the next effective debugging step, if not? 

 

0 Kudos
Reply
hbucher
Scholar
Scholar
3,441 Views
Registered: ‎03-22-2016

@futuristic What is your main.cpp you used to run simulation?

vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
0 Kudos
Reply
futuristic
Participant
Participant
3,429 Views
Registered: ‎11-02-2017

@hbucher Thanks for your help. I have attached both HLS and SDK source files. 

0 Kudos
Reply
futuristic
Participant
Participant
3,361 Views
Registered: ‎11-02-2017

@hbucher

 

Modified the IP to: 

void simple_ddr(int* DRAM, int num, int midResult)
{
...
midResult = 6;
...
}

to check if the IP is really working by checking if midResult changes values after the IP is started. In SDK I did this:

XSimple_ddr_Set_DRAM(&simple_ddr, DRAM);
XSimple_ddr_Set_num(&simple_ddr, 100);
XSimple_ddr_Set_midResult(&simple_ddr, midResult);

XSimple_ddr_Start(&simple_ddr); print("Detected HLS peripheral complete. Result received.\n\r"); do { res_hw = (int*)XSimple_ddr_Get_DRAM(&simple_ddr); midResult = XSimple_ddr_Get_midResult(&simple_ddr); numfromIP = XSimple_ddr_Get_num(&simple_ddr); } while (!XSimple_ddr_IsReady(&simple_ddr));
...
xil_printf("midResult=%d\n", midResult);

which returns midResult=0, not modified to the value in the IP. What does that mean? I am getting the ready signal from the IP yet not the computed results. I feel like the addressing between the PS and the IP is kinda messed up. Where to go from here? 

0 Kudos
Reply
hbucher
Scholar
Scholar
3,358 Views
Registered: ‎03-22-2016

@futuristic  In the C code, midResult is an input argument. All changes are local so the result is "correct".

 

vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
0 Kudos
Reply
futuristic
Participant
Participant
3,350 Views
Registered: ‎11-02-2017

@hbucher Not so clear. I passed the midResult to the IP and get the value after it is done which makes midResult=6. How would you change the code then to read the modified value from the IP? 

 

Best,

0 Kudos
Reply
hbucher
Scholar
Scholar
2,389 Views
Registered: ‎03-22-2016

@futuristic This is not anything specific to HLS, this is C language.

To make a variable return a value, you have to pass by reference, as in

 

void simple_ddr(int* DRAM, int num, int& midResult)
vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
0 Kudos
Reply
futuristic
Participant
Participant
2,373 Views
Registered: ‎11-02-2017

@hbucher My bad, clearly! 

 

That didn't solve my original issue though. 

0 Kudos
Reply
varun.nagpal
Observer
Observer
1,140 Views
Registered: ‎11-20-2018

@futuristic were you able to solve the problem ?

0 Kudos
Reply