My DMA send and receive keep stalling if i send multipple data

Hi, I am currently using Pynq 3.0.1 on ZCU104

this is my block diagram


Here i want to send data from txt and send it to my rtl code (Master.v) via pynq. But i keep getting (*) in my notebook.

Here is my python code to send data and receive it via dma

# First allocate the buffers
input_buffer = allocate(shape=(chunk_size,), dtype=np.uint32)
output_buffer = allocate(shape=(chunk_size,), dtype=np.uint32)

# Open and parse the file
with open('dummy.txt','r') as f:
    txt = f.read().split('\n')

# Initialize DMA
dma_send.start()  # Start the DMA channel before transfers
dma_recv.start()

#chunked transfer logic
for i in range(0, Config_size, chunk_size):
    for j in range(0, chunk_size, 2):
        if (i + j + 1 <= Config_size):
            input_buffer[j//2] = int(txt[i + j],16) << 8 | int(txt[i + j + 1],16)
    while not dma_send.idle:
        pass
    dma_send.transfer(input_buffer)

dma_recv.transfer(output_buffer)

Because the config_size is around 500k line of 1byte data, i separate for every chunk of data to be send. I have checked the dma_send.idle and it keep saying it stays in the busy state

Can someone help me to fix this problem?

Hi @Michael,

Welcome to the PYNQ community.

This is likely due to an issue with the signaling of your AXI4-Stream IP.
I wrote a debug tutorial, but I would suggest you simulate your IP thoroughly before hand.

Mario

I have simmulate my IP and it works fine for me.
I’ve read your tutorial about the DMA hasnt started issue, but yesterday i tried to send a chunk of data yesterday and after the second attempt to send a data the dma stalls in busy

I’ve found the solution for sending huge amount of data.

I changed my code order become this and the DMA won’t stall

# First allocate the buffers
input_buffer = allocate(shape=(chunk_size,), dtype=np.uint32)
output_buffer = allocate(shape=(chunk_size,), dtype=np.uint32)

# Open and parse the file
with open('dummy.txt','r') as f:
    txt = f.read().split('\n')

# Start DMA
dma_send.start()
dma_recv.start()

# Double buffering loop
for i in range(0, Config_size, chunk_size):
    for j in range(0, min(chunk_size, Config_size - i) - 1, 2):
        if (i + j + 1 < len(txt)):
            input_buffer[j//2] = int(txt[i + j], 16) << 8 | int(txt[i + j + 1], 16)
    
    input_buffer.flush()
    # Start transfers
    dma_send.transfer(input_buffer)
    
    while not dma_send.idle:
        pass

or I can simply increase the DMA buffer address width in IP

1 Like