Running FFT with axi dma channel wait "DMA channel not started"


I have made a simple design to run an FFT with xilinx IP block in vivado. You can see it here: design.pdf (91.8 KB)

I then try to load data into the FFT with this small snippit:

# setup buffers of both input and output
fft_in_buffer = xlnk.cma_array(shape=(N,),dtype=np.int32)
fft_out_buffer = xlnk.cma_array(shape=(N*2,),dtype=np.int16) # convert to 2 16 bit numbers for total of 2*N 16 bit numbers
# memcpy the input data into the buffer
np.copyto(fft_in_buffer, aud_data)
# trigger the dma transfers for send and receive, this will trigger the FFT too

however the wait statement always triggers “DMA channel not started”. trying to manually start the channel results in a hanging function call. The funny thing is there is data in the output buffer, its just completely non sensical.
I am running on a PYNQ-Z2 board.
Things I have tried the following things after reading the forums:

  • disabled scatter engine
  • added the interrupt controller
  • added the fifo queues
  • Tried fft throttle scheme real-time and non real-time on the FFT block
    al result in the same situation. Its a bit frustrating and I’m running out of ideas. Can somebody help me?

Hi Frank,
Can you please let us know which version of PYNQ, Vivado you are using?

Can you check make sure you are using up to date bitstream, tcl/hwh files? If these are out of sync it can cause the error you see. It is easy to forget to copy one of the files to the board, or copy the wrong version. (I’ve made this mistake more times than I want to admit :wink: )
Are you using a Tcl file, or HWH with your bit file?

At a glance, I don’t see anything obvious wrong in your block diagram.
As a sanity check, you could do a loop-back between your DMAs, but I think you have a different problem as the DMA is showing as not started.

I presume this isn’t your full code? You only seem to be starting the DMA for the data, and not the config, but even if you have left this step out, I think you should see the DMA initialized (or “started” after you call the transfer).


Hi, I am using:
PYNQ 2.5.1
Vivado 2020.1

I have a script which copies all three files and uploads it to the board, the tcl hwh and bit file.

I have tried creating a DMA loopback like so: design.pdf (80.6 KB) but when I do that the DMA controller doesnt even show up in the overlay ip blocks.

It is indeed not the full code, the config part is like so and completes successfully:

config_value = 1 # forward FFT, no scaling

# create CMA buffer and lay the config value in it
#fft_buffer_config = xlnk.cma_array(shape=(1,),dtype=np.int16)
fft_buffer_config = xlnk.cma_array(shape=(1,),dtype=np.int8)

fft_buffer_config[0] = config_value
# send the config value and wait for confirmation

thank you for taking the time to look at my problem!

We have not tested 2020.1 and in the next release 2.6.0 we will probably test it. Currently I am not sure if DMA still works fine. For your image 2.5 (there is no image v2.5.1), 2019.1 is the verified Vivado version.

Hi, this seems to indeed solve the problem for the simple dma fifo when building the same design in 2019.2 This now works

I also recreated my FFT design in 2019.2 like so: design.pdf (74.2 KB) However I still have the same problem of error “RuntimeError: DMA channel not started” when calling recvchannel.wait() and the output is random data. I will try to get the ILA probe to work (I am a bit of a noob with all this).

Do you have any other ideas maybe?

Can you share your source files?


sure, I have now also inserted FIFO because some people say that helps with the DMA. However now the wait call simply never returns. The ILA shows the same data on the tdata output port of the fft but tvalid and tlast never become high. So it seems its stuck somewhere.

my block design in pdf form: design.pdf (77.5 KB) and my block design code: (7.1 KB) and my notebook: fft.ipynb (8.7 KB)

if you need more files let me know! thanks in advance!

It seems that the problem was the size of the FIFO in combination with buffer register width of the DMA. making both of these sufficiently large I can now run my FFT in non-realtime mode.