PYNQ: PYTHON PRODUCTIVITY

Connect DMA to non power of 2 stream

I am developing a simple design to test the vivado fft block. I connect my fft directly to the DMA and I simply run some transformations of my signals. I have already tested my design in PYNQ and in works perfectly.

However I was trying to analyze how the input data width of my fft impacted the output resolution. I have been able to test my design for data widths that are padded to a power of 2 (as an example, 16bits input data width is padded to 32, 25bits input data width is padded to 64bits).

However if I select a data width equal to 17, my stream is padded to 48bits, and I am not able to connect it to my DMA.

How can I solve this problem? Is there a way to connect the 2 IPs?
Here is my design

You may be better asking this on the Xilinx forums as this is not a PYNQ question.
The S_AXIS_DATA port on the FFT block is a bundle of all the signals. You can’t expand it and partially connect some signals to the underlying signals. IPI uses an ‘all-or-nothing’ approach. You either connect the ports using the bundled interface, or you expand it and connect every signal individually.
You should be able to connect the IPs and Vivado will automatically remove redundant signals.
The DMA doesn’t support arbitrary widths, so there will be some slicing of signals in HW/padding of data in software.

Cathal

as a suggestion, you can use axi stream data width converter followed by axi4-stream subset converter in the middle of your IP and DMA.

Why these two blocks? Isn’t the subset converter enough?

It depends on what you want, if you want to add paddings only a subset converter is enough, but if you want to take specific data without padding then both would be needed. Like you want to take 1byte of data from 2byte of stream, but DMA supports 32-bit configuration, so you first need a subset converter to take a byte of specific data, and a stream width converter to hold 4bytes data to be gathered and sent to DMA. Or you can add 2bytes extra padding with subset converter, later delete those padding including the extra bytes in main stream after receiving the data from DMA.

Ok thanks! Basically what I need is a downward and then upward conversion.

The FFT with an Input Data Width parameter set to 17bit (as an example), pads it to the next byte (24bits in this case) and multiplies the stream size by 2 (24bits for real part and 24 for imaginary part), generating an overall size of 48bits on the stream.

My DMA only accepts 64bits streams, so I will transfer 64bits each time. In the middle between my DMA and my FFT I placed a subset converter with the following tdata conversion:

  1. tdata[55:32], tdata[23:0] → first subset converter, downward conversion from DMA to FFT

  2. 8'b00000000,tdata[47:24],8'b00000000,tdata[23:0] → second subset converter, upward conversion from FFT to DMA.

Does this make sense to you?

I actually tested my solution and it doesn’t work properly, I guess there’s a problem with the sign extension in the second subset converter. I am padding with zeros and reading as sign extended number. Is there a way to sign extend my number inside the subset converter (instead of zero padding)?

The data structure you have declared fully depends on what you are sending from the PYNQ. I think it will have no problem assuming you know what you are sending. I don’t know how it works, but I assume the DMA driver in PYNQ sends every data that you are sending without adding any padding bits. So, you shouldn’t require any subset converter in the first case (It is my assumption only, I might be wrong, the experts can tell you more).
In the second case, I would have used only a stream width converter, where only the master interface will have an output of 8bytes.

In the end I used different subset converters to downscale/pad the signal from/to the DMA as needed