Closed charlesz1112 closed 7 years ago
Glad it was somewhat useful to you. I assume you are talking about test test_dma.py
test app. This whole thing was meant for "FPGA accelerator", as in you push data into FPGA, PS->PL then read processed data back PL->PS. What you want however is just PS->PL part.
You'll need to modify this function here:
to work with one way transfers, in your case only launch s2mm transfer, maybe when src_buf
is None
for example. Or better write a separate method that does transfer s2mm way only. In fact looking through AxiDMA
class it seems to assume two ways transfers throughout, you'll need to write a one way version of that class or generalise this one to support one way transfers. I haven't really turned this into a proper lib as you can see.
Then you'll need to run s2mm transfer again and again as long as your PL is generating data.
Reason why currently you can only run once is because mm2s transfer will block when buffers on the PL fill up. As a quick work around you can connect it in the PL to some sort of sink, so that it doesn't fill up.
Thank you so much for replying!
So I took some baby steps (I am a PhD student in IC design but need something like this to show how my IC can be used. I am really new to hardware dev at this level):
In PL, I cut your loop before FIFO and inserted a custom AXIS counter driving the FIFO, which drives the Slave port on DMA (this is the S2MM route, the AXIS counter outputs 32 bytes every 40 cycles - TLAST should go high every 40 clock cycle whereas TVALID will be high for 8 cycles). On the MM2S side, I just added another FIFO to be the sink but this FIFO is not driving anything.
If I run your code as they are (except for "sz"), I see the correct output and the program finishes. But if I run it again, it says DMA failed, which means the wait() function is not correctly executed.
If I comment out L70 of axidma.py (not launching mm2s), the program will do S2MM transfer but will hang at wait_for_interrupt in wait()..(doesn't help if I change n_iter = 1)
I think I need some extra guidance on the L73-82 of axidma.py and how to reset DMA for another S2MM transfer.
Thanks
I think FIFO will still fill up eventually, hence blocking (try changing source size to smallest valid transfer (32?) and see if you can get more reads out of it). Try looking for AXI sink IP in the xilinx that you can connect to the other end of FIFO.
try changing L39, to be self._streams = (s2mm,)
so that reset only resets s2mm
. Also remove mm2s
from idle
an halted
functions. Definitely wait for 1 interrupt only. Try playing around with buffer size (smaller transfers). Try tweaking DMA IP settings allow smallest, least efficient transfer size or enable all the "convenience options" like unaligned reads or whatever is there. Make sure your memory is aligned. Try to disable MM2S in the DMA block in Vivado altogether, shouldn't be necessary but who knows.
Instead of waiting for interrupt try busy polling for s2mm to go into idle mode.
Thanks again!
Since I was not able to pick a AXI sink IP, I focused on the 1-way transfer and tried many things... Always stuck at self._read() in uio.py during wait_for_interrupt.
This seems like a road block. Any suggestions?
I'm starting to think that you simply can not reset DMA core while your other IP is still pushing data into it. In my test reset works fine since both SINK and SRC get reset together.
See if you can launch new transfer without doing DMA core reset, you need to get familiar with pg021 manual doc.
You need to implement this:
You might have to switch to scatter gather mode (SG) to support streaming properly with this IP, I'm not sure. Maybe look if "Cyclic BD enable" bit can be of help in your case.
When debugging make sure to print out status register and interpret it using documentation in pg021.
Hi Kirill,
Thank you very much for your contribution here.
Now I have a sample generator in PL, and it is continuously pumping data at some slow rate (25KHz), and I would like to push such data continuously into PS. How should I modify your Python program to support this? (no read from memory is needed and so far my attempts at modifying your code can only do DMA transfer once)