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!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
130 Views
Registered: ‎08-30-2018

Handling out of order streaming data

I have been working with neural networks and currently I'm trying to write IP's for functions like convolution and pooling etc. I'm using DMA to transfer the data from memory to these IP's. The problem is that I'm using a streaming port and when I try to access data out of order (like e.g accessing 4th element of array before the 3th one), S2MM transfer is of DMA is halted and is never completed. Can someone guide me how to create such IP which has capability of handling out of sequence data. Second part of this question is that when the stored the incoming stream of data from a PORT in a local array and perform operations on it then it doesn't work on hardware either. S2MM transfer is halted. Any help/suggestion/opinion will be highly appreciated.

0 Kudos
7 Replies
Scholar u4223374
Scholar
112 Views
Registered: ‎04-26-2015

Re: Handling out of order streaming data

ali_ahmad@qureshi1997 Streams fundamentally cannot handle out of order data. You get the data sequentially, and there is no way for the downstream block (ie the HLS block) to indicate to the DMA that it wants data in a different order. The solutions to this are:

 

(1) Don't use a stream, use an AXI Master. Random access will be slow, but at least it's possible.

(2) Buffer the data internally so you can work with it later. This joins on to your second question.

 

For the second question, you're going to have to post the code. I've done this many times and it's worked fine in hardware, so HLS is quite capable of managing it.

95 Views
Registered: ‎08-30-2018

Re: Handling out of order streaming data

Mate..can you upload a pic of IP having axi master connected with DMA in block design so I can get better idea.  And here's the code by the way:

#include "pool.h"


void maxpool(ap_axis <32,2,5,6> inp[r][c],ap_axis <32,2,5,6> pooled[row][col])
{

#pragma HLS INTERFACE ap_fifo port=pooled
#pragma HLS INTERFACE ap_fifo port=inp

#pragma HLS RESOURCE variable=inp core=AXIS metadata="-bus_bundle STREAM_inp"
#pragma HLS RESOURCE variable=pooled core=AXIS metadata="-bus_bundle STREAM_pooled"
int i = 0, j = 0; int arr[3][3];
//int arr2[2][3]={1,2,-2,-1};

for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
arr[i][j] = inp[i][j].data;
}

for(i = 0; i < r; i++)
for (j = 0; j < c; j++)
pooled[i][j].data = arr[r - i - 1][c - j - 1] + 1;
//pooled[i][j].data = arr[i][j] + 1;
pooled[i][j].keep = inp[i][j].keep;
pooled[i][j].strb =inp[i][j].strb;
pooled[i][j].user =inp[i][j].user ;
if(i==2 & j==2 )
{
pooled[i][j].last =1;
}
else
{
pooled[i][j].last =0;
}
pooled[i][j].id = inp[i][j].id;
pooled[i][j].dest =inp[i][j].dest;
}

 In fact, if I try to save data coming from port to a local array and try to perform operations then won't work either. S2MM still remains halted. Do you know how actually a for loop is being translated into the verilog/vhdl code.. Theoretically speaking it should  work.Right?

0 Kudos
Scholar u4223374
Scholar
75 Views
Registered: ‎04-26-2015

Re: Handling out of order streaming data

ali_ahmad@qureshi1997 Sorry, I should have explained that better. The AXI Master doesn't connect to the DMA, it connects straight to the memory controller (MIG or Zynq HP AXI Slave ports).

 

With your code, I can see three major problems. First is that you've dropped the braces on one of your loops; the result is that (with indenting) the code looks like this:

 

void maxpool(ap_axis <32,2,5,6> inp[r][c],ap_axis <32,2,5,6> pooled[row][col]) {

	#pragma HLS INTERFACE ap_fifo port=pooled
	#pragma HLS INTERFACE ap_fifo port=inp

	#pragma HLS RESOURCE variable=inp core=AXIS metadata="-bus_bundle STREAM_inp"
	#pragma HLS RESOURCE variable=pooled core=AXIS metadata="-bus_bundle STREAM_pooled"
	int i = 0, j = 0; int arr[3][3];
	//int arr2[2][3]={1,2,-2,-1};

	for (i = 0; i < r; i++) {
		for (j = 0; j < c; j++)
			arr[i][j] = inp[i][j].data;
	}

	for(i = 0; i < r; i++)
		for (j = 0; j < c; j++)
			pooled[i][j].data = arr[r - i - 1][c - j - 1] + 1;
		
	//pooled[i][j].data = arr[i][j] + 1;
	pooled[i][j].keep = inp[i][j].keep;
	pooled[i][j].strb =inp[i][j].strb;
	pooled[i][j].user =inp[i][j].user ;
	
	if(i==2 & j==2 ) {
		pooled[i][j].last =1;
	} else {
		pooled[i][j].last =0;
	}
	pooled[i][j].id = inp[i][j].id;
	pooled[i][j].dest =inp[i][j].dest;
}

That second double-loop is not what you want.

 

The second problem is that from HLS's point of view, you're accessing pooled[i][j] seven times in a row. This also cannot be supported by a stream; just like you can't access an element less than once (eg. to skip some), you can't access an element more than once. The solution is something like this:

	for(i = 0; i < r; i++) { // Added braces
		for (j = 0; j < c; j++) { // Added braces
			ap_axis<32,2,5,6> dout;
			dout.data = arr[r - i - 1][c - j - 1] + 1;
			dout.keep = inp[i][j];
			dout.strb =inp[i][j].strb;
			dout.user =inp[i][j].user;
			
			if(i==2 & j==2 ) {
				dout.last =1;
			} else {
				dout.last =0;
			}
			dout.id = inp[i][j].id;
			dout.dest =inp[i][j].dest;
			pooled[i][j] = dout;
		}
	}

The third major problem is that you're reading all of inp in the first double-loop, and then you're going back to the start of inp and reading it all again in the second double loop. Again, streams don't do non-sequential access - you can't skip from the end back to the start. The solution to that problem is to also store all the bits you need from the input stream (eg. strb, user, id, dest) in addition to data, and write out the stored copies.

 

 

Apart from that, I would strongly suggest using the hls::stream type instead of arrays. The stream type makes it clear what can and cannot be done with streams; if you find yourself in a situation where the stream type cannot do what you want, that's a good indication that the AXI Stream interface also cannot do what you want.

0 Kudos
68 Views
Registered: ‎08-30-2018

Re: Handling out of order streaming data

Thanks a lot mate. This means I don't require DMA when using the AXI Master port for the IP?  Secondly, when I try to put axi master port on my input array(in this case 'inp') then while synthesising i get errors like:

ERROR: [XFORM 203-801] Interface parameter bitwidth 'inp.keep.V' must be a multiple of 8 for AXI4 master port.

Keep is currently  of 5 bits. This means that I have to change sizes of my side channels. Now my question is that I have used these bit sizes for side channels the same as the example given under design examples of HLS. Changing the bit size will be the right thing or not?

0 Kudos
Scholar u4223374
Scholar
59 Views
Registered: ‎04-26-2015

Re: Handling out of order streaming data

Normally you wouldn't use side-channels with an AXI Master. The side channels are generally to do with routing (id, dest), packing (keep), and stream management (last). AXI Masters don't need routing (they use standard addressing for that), packing (the bus is always full, at least in HLS), or stream management (because they're not streams). Instead you can just go for an array of integers.

 

As you have said, no need for a DMA with an AXI Master port.

0 Kudos
44 Views
Registered: ‎08-30-2018

Re: Handling out of order streaming data

Can you guide me how to set my ports(for m_axi) interfaces then. I mean should I need to add more arguments in function and what should be their directives value? Because up till now I have used DMA along with my IP's.

0 Kudos
37 Views
Registered: ‎08-30-2018

Re: Handling out of order streaming data

Also, I have to handle addresses in HLS or SDK? I mean how IP will get the desired data from memory.

0 Kudos