Problem while trying to implement a 2D FFT on PL

Hi!!
I am using pynq version 3.0.1 on Xilinx KRIA KR260 (SOM). Vivado 2022.1.
I am trying to implement a 2D FFT on the PL using the following resource:

(886) 4: Reconfigurable FFT Example on PYNQ Z2 #HLS #Jupyter - YouTube

In this, we attach a dma_driver to the config_dma(which sends the configuration information to the FFT IP), so that we can change the FFT size directly from the jupyter notebook and we need not change the .bit file every time we want to change the FFT configuration.
So, this worked fine for the first time(FFT on every row in a 2d matrix) we wanted to configure(setting FFT size) the FFT.
When we transpose the matrix, the FFT size needs to be changed. When I now try to configure the config_dma again (using dma_driver), the cell runs continuously and does not halt.
Could someone please help me with this!!
Any suggestions are appreciated!!.
Thank you


Fig: FFT design

from pynq import DefaultHierarchy
from pynq import allocate
from math import log
import numpy as np

class fft_block_driver(DefaultHierarchy):

def __init__(self,description):
    super().__init__(description)
    self.configuration=0
    self.ff_size=0

def convert_to_data(self,fft_direction,size):
    
    fft_direction.zfill(8)

    byte2='0'*8

    x=int(log(size,2))
    fft_size=bin(x)[2:]

    fft_size.zfill(8)
    tdata=fft_direction+byte2+fft_size
    return int(tdata,2)


def configure(self,fft_direction,fft_size):
    self.configuration=self.convert_to_data(fft_direction,fft_size)
    temp=allocate(1,np.uint32)
    temp[0]=self.configuration
    self.config_dma.sendchannel.transfer(temp)
    self.config_dma.sendchannel.wait()
    del temp
    
def stream_fft(self,input_buf):
    out_buffer=allocate(samples,np.csingle)
    self.data_dma.sendchannel.transfer(input_buf)
    self.data_dma.recvchannel.transfer(out_buffer)
    self.data_dma.sendchannel.wait()
    self.data_dma.recvchannel.wait()
    
    return out_buffer

@staticmethod
def checkhierarchy(description):
    if 'data_dma' in description['ip']\
        and 'config_dma' in description['ip']:
         return True
    return False

Fig: dma_driver


Fig: input signal


In the above screenshot, the last cell keeps on running and does not give any output.
(chirps and samples values are interchanged after transposing matrix and is not shown here )

1 Like

Have you seen this article there is a reconfigured fft at the end of the post.

MicroZed Chronicles: ZUBoard 1CG and PYNQ (adiuvoengineering.com)

1 Like

Hey…thank you!! I’ll look at it

so…after a bit of debugging… we found out that the “self.data_dma.recvchannel.wait()” command in the “stream_fft”( fft_block_driver class) method keeps on running infinitely…
@cathalmccabe !! sir, it would be very helpful if you could you please look at it, if possible…thank you

DMA wait can be if your DMA receive has received less data than it expected, or it doesn’t see TLAST.

Can you post the register map info before the transfer, and after the transfer?
Small example showing register map:

Cathal

1 Like

Hi sir!!
data_dma_register_map(before transferring):


during transfer(since this cell keeps on running, we cannot print register_map after transfer(next cell)):

The outputs that are being printed are from the ‘fft.configure’(executed completely) and ‘fft.stream_fft’(problem here):

Also sir:
I am able to run all the cells perfectly, only if both the values of samples and chirps are (>=64). If one of them is less than 64(32,16,8,2) the cell keeps on running and does not stop.

@cathalmccabe (or anyone who could help me with this) Hi!!..could you please look at the problem if possible(the fft does not work for ‘chirp’ and ‘samples’ values less than 64)…
Also…earlier, the dma register map was idle(idle=1) before the transaction has started…
but now, for some reason, it is not idle(idle=0) even before the transaction started and the notebook cell stuck while running…
could you please let me know the reason for this…
thank you…

1 Like

Try take the .sendchannel.wait() out of the configure() and stream_fft() functions.
I think the configure may be depending on the stream_fft, so you need to start them both before you call wait().

Cathal

(tried it sir, didn’t work…the stream_fft depends on the configure function(sets the size and direction of fft) sir )
But sir, the code was working initially for few inputs…now, the register map of dma shows idle=0 even before trying to send any data

was able to notice that the data is not being received by the dma after computation