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: 
Visitor sephalon
Visitor
6,608 Views
Registered: ‎07-15-2016

AXI-Stream interface with data array side-channel does not build

Jump to solution

Hi there,

 

I would like to connect my custom IP core via an AXI DMA engine to my PS in the following way:

 

#include <ap_int.h>
#include <hls_stream.h>

template<int D>
struct axi_dma {
	ap_uint<8> data[D / 8];
	ap_uint<D / 8> keep;
	ap_uint<1> last;
};

void top(hls::stream<axi_dma<128> > &input,
         hls::stream<axi_dma<128> > &output) {
#pragma HLS INTERFACE axis port=input
#pragma HLS INTERFACE axis port=output

	axi_dma in, out;

	input >> in;

	...
	
	output << out;
}

 

This works well if I use a scalar (ap_uint<128> in this case) instead of an array for the data element of struct axi_dma. With the above example though, the C synthesis ends up with the following error message:

 

CRITICAL WARNING: [XFORM 203-103] Cannot partition array 'input.V.data' (top.cpp:11): different array partition directive on the same group of AXI-Stream ports.

 

This thread mentions that one has to add DATA_PACK directives to the corresponding input and output streams like so:

 

void top(...) {
... #pragma HLS DATA_PACK variable=input #pragma HLS DATA_PACK variable=output ... }

 

According to UG902 this should already happen automatically though:

 

Vivado HLS automatically applies the DATA_PACK directive to the data struct and all
elements of the data struct are combined into a single wide-data vector. The interface is
implemented as a single wide-data vector with associated side-channels, TVALID and
TREADY signals.

 

What am I missing here? Up to Vivado HLS 2015.4 the build proceeds successfully now. However the IP core ends up with AXI-Stream interfaces which are 152 bits wide instead of the expected 128 bit. To my understanding the pack process should not add any padding in this case, so where are those additional 3 bytes coming from?

 

In Vivado HLS 2016.1 and beyond I end up with this error message instead:

 

CRITICAL WARNING: [XFORM 203-801] Interface read on 'input.V.data' (top.cpp:11) has incompatible types. Possible cause(s): data pack is only applied on source(port) or destination(variable).

 

I was thinking that adding HLS_PACK directives to the local in and out variables would solve this problem, but the critical warning persists even in this case.

 

Right now I use a scalar instead of an array for the data element and unpack it manually in the top function. This is an acceptable workaround, but for my use case it would be more natural to deal with a byte array in the first place. What am I doing wrong here?

 

Regards,

 

Sephalon

0 Kudos
1 Solution

Accepted Solutions
Xilinx Employee
Xilinx Employee
11,302 Views
Registered: ‎08-17-2011

Re: AXI-Stream interface with data array side-channel does not build

Jump to solution

hi @sephalon

 

using a large ap_int is probably the recommended way  rather than as array.

i also praise you for using hls::streams but this however add a layer of things/indirection and then can't access the contained objects.

 

you could not use hls::streams and use pointers and axis interface if you really really want aD array for data. please make sure that accesses are always with *input++ or *output++

- Hervé

SIGNATURE:
* New Dedicated Vivado HLS forums* http://forums.xilinx.com/t5/High-Level-Synthesis-HLS/bd-p/hls
* Readme/Guidance* http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

* Please mark the Answer as "Accept as solution" if information provided is helpful.
* Give Kudos to a post which you think is helpful and reply oriented.
3 Replies
Xilinx Employee
Xilinx Employee
11,303 Views
Registered: ‎08-17-2011

Re: AXI-Stream interface with data array side-channel does not build

Jump to solution

hi @sephalon

 

using a large ap_int is probably the recommended way  rather than as array.

i also praise you for using hls::streams but this however add a layer of things/indirection and then can't access the contained objects.

 

you could not use hls::streams and use pointers and axis interface if you really really want aD array for data. please make sure that accesses are always with *input++ or *output++

- Hervé

SIGNATURE:
* New Dedicated Vivado HLS forums* http://forums.xilinx.com/t5/High-Level-Synthesis-HLS/bd-p/hls
* Readme/Guidance* http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

* Please mark the Answer as "Accept as solution" if information provided is helpful.
* Give Kudos to a post which you think is helpful and reply oriented.
Visitor sephalon
Visitor
6,226 Views
Registered: ‎07-15-2016

Re: AXI-Stream interface with data array side-channel does not build

Jump to solution

Oh I see, should have thought of that. Thanks!

 

I unpack the scalar in the following way:

 

ap_uint<128> src;
ap_uint<8> state[16]; for (int i = 0; i < 16; i++) { #pragma HLS UNROLL state[i] = src(7 + i * 8, i * 8); }

 

Does this bring a performance penalty or is this optimized away anyway? I also get a warning saying that "variable-indexed range selection may cause suboptimal QoR", but I guess that refers to index overflows and can be safely ignored here?

 

Regards,

 

Sephalon

0 Kudos
Scholar u4223374
Scholar
6,217 Views
Registered: ‎04-26-2015

Re: AXI-Stream interface with data array side-channel does not build

Jump to solution

The warning is just because to access variable-indexed ranges of a value, it's going to have to build some huge multiplexers. Since you've got the loop fully unrolled this won't actually happen - it should just connect the relevant bits across directly.

 

You'll probably need to use the ARRAY_PARTITION pragma on "state"; otherwise it'll be implemented as a distributed RAM which only allows a single element to be written in each clock cycle, so the loop unrolling won't work.