PYNQ: PYTHON PRODUCTIVITY FOR ZYNQ

How to write an IP with an array as a parameter to a function

Hi All,
I am new to PYNQ and Xilinx Vivado HLS.
I want to have a custom overlay to give me an element from an array in a round-robin fashion upon invocation.
I am trying to implement HLS function such that I want to send an array of say 4 values and select one element in round-robin fashion each time the function is being invoked.
I am stuck with what type of mode to use for the input array A, such as axis, m_axi or ap_memory. I don’t understand what to use for my application.
I tried with “axis”. But When I created Block design with AXI DMA in Xilinx-HLX, it has given me critical warning as :
“Interface connected to S_AXIS_S2MM does not have TLAST port”

Please, find attached my C++ code.
Please, give me some pointers on how to achieve my task.rr.cpp (482 Bytes)

Any help is much appreciated.

Thanks
Gandhimathi

There are a few ways to do this which will have trade-offs.

AXI Slave is simple (you can use MMIO to transfer data) but it will be low performance. You probably want to use AXI master for highest performance, or if you intend to connect your IP in a pipeline, AXI stream may be best.

If you want to use an AXI stream + DMA -
You are using int as the interface data type, but an AXI stream has side channel data which includes TLAST. This is used by the DMA to indicate the last piece of data in a stream. The tools can’t automatically infer this, so you need to do something to add this information.

You can add this in different ways. You can use the hls_stream.h, or you can simply use a struct for the stream.

#include <ap_int.h>
typedef struct{
int data;
ap_uint<1> user;
ap_uint<1> last;
} stream_type;

For output streams from your IP, you need to set (and reset) TLAST manually. If you have one stream in and one stream out at the same data rate, an easy way to do this is to assign the input->TLAST to the output->TLAST.

Not really examples, but some HLS IP used in PYNQ that may be useful to review:


Cathal

Hi Cathal McCabe,

Thank you so much for your guidance. Your response is very much informative to me.
I have managed to create an Overlay with round-robin selection.
I have a couple of doubts.

  1. I am interested in only getting the position of the elements in the array that is passed to the HLS function. Right now I am passing the index variable as a parameter to the function as an interface and read the value from it. Instead, how can I return the index value from my function?
  2. I am stuck with writing a driver function so that I could call the function such that index=RR([1,2,3,4,5]). I tried similar to the stream multiplication explained here:https://pynq.readthedocs.io/en/v2.0/overlay_design_methodology/overlay_tutorial.html. But I could not get it done. It is not recognizing the function defined in the driver.

I am wondering whether I have to split my functionalities of generating round-robin selection for a given size and select a round-robin index for a received array.
I mean I have to create two IPs in my HLS and need to bind the IPs to the respective drivers?
But in the above tutorial link the stream_multiplier driver there is no bind_to attribute given?

I have attached my Jupiter file for your reference.rr.ipynb (21.0 KB) rrms.cpp (664 Bytes)

Any pointers on how to achieve my requirements are highly appreciated.

Hi,
I solved my requirement. I have created a hierarchy in the Vivado HLX block design and added my two IPs namely, rrms_sm and axi_dma_sm into it. Then, I followed the tutorial. Now, I am able to call my function using a driver as follows:
ol.RR_H.stream_rr([3,4,5,6,7])

Thanks
Gandhimathi