02-08-2019 09:59 AM - edited 02-08-2019 10:03 AM
I all, I have looked in some similar topics via google, and couln't find a clear answer, so let me try with you guys:)
My design as an AXI S2MM DMA, moving data between a stream FIFO and DDR. the fifo is written from PCIE DMA Bridge/Subsystem for PCIe provided Xilinx IP, running in Streaming mode.
my DMA transfers are basically moving 8 MB of data from FIFO into DRAM. the S2MM AXI DMA is configured for 64MB transfers (maximal allowed) both in DMA IP and in S2MM.Length field of the descriptor. as it is recommened to set the maximal /biggest expected transfer size, regardless of what I am actually transfering.
My next step is to put a custom logic block between the FIFO and DMA, as I need to do some processing on the FIFO data before passing it to DRAM, which will inflate the data.
right now everything works fine, without my custom logic. 8 MB of data are written to the DRAM. but not sure what to do when I add the custom logic block.
SO, I would like to know how I should handle the TLAST value. Should I assert TLAST togethwer with the final data sent? or I could just make the TLAST assert every 256 words or so and split my stream into packets. Will the DMA completly stop after it recieved the first TLAST? or will it continue even when multiple TLASTS are asserted?
Also, since without the custom logic everything workis, any clarification on how the DMA is treating the TLAST right now without custom logic? I programmed 64 MB length, so i assume it got a TLAST after 8MB has been read from the FIFO and stops?
02-13-2019 11:22 AM
With streaming data TLAST should be asserted at the end of each packet. You could assert TLAST sending your entire data in 1 packet, or send multiple packets with multiple TLASTs to designate the end of each packet. The DMA will do what it is defined to do, which is to say it should continue to transfer data after TLAST if it has more data to transfer.
Looking at the example code for AXI DMA Scatter Gather mode with Interrupts using the baremetal driver we can see this. On the #define NUMBER_OF_BDS_TO_TRANSFER line, the DMA is told to keep transferring data until it has sent the NUMBER_OF_BDS_TO_TRANSFER. That value comes from the NUMBER_OF_PKTS_TO_TRANSFER which should have a TLAST asserted for every packet (with each packet containing NUMBER_OF_BDS_PER_PACKET BDs).
This example code can be found where your Xilinx SDK install files are found or in the Xilinx repo : https://github.com/Xilinx/embeddedsw/blob/master/XilinxProcessorIPLib/drivers/axidma/examples/xaxidma_example_sg_intr.c
Documentation on how the BD rings are setup, and how the provided driver was created can be found at the top of xaxidma.h : https://github.com/Xilinx/embeddedsw/blob/master/XilinxProcessorIPLib/drivers/axidma/src/xaxidma.h
To your second set of questions, AXI DMA shouldn't finish with TLAST if there is more data to send. If your BDs are set to be 64MB in length, but if you only have 8MB of data, then the AXI DMA will see (because of TLAST) that it has finished sending data before the end of the BD. DMA IP will return that BD and stop sending data. I believe that you are correct in how you described your last set of questions.
02-14-2019 06:35 AM
calebd, thank you for the detailed answer,
So if I understand your answer correctly ,
* let say I am driving a stream from a custom IP, and I wish to send 800 MB of data , without generating any tlast signal
* I set the S2MM with scatter mode, and set each descriptor to fetch 8 mb (say, 100 descriptors total)
* Now, to make things work, I choose a random byte count for which I will generate a tlast. Let's say I output a Tlast for every 512 bits.
this will obviusly generate many tlasts. however, this will only serve as a way to "packetize" my data. the dma will see these tlasts and keep going until it reaches the end of the stream , i.e the last data beat on the last descriptor, and stop?
So in other words, it dosnt really matter if i generate a single tlast or many tlasts, the dma will still work. it is just has to be done to keep the dma going, because it must see tlasts here and there to actually work.
in that case, i can use a subset converter after my custom ip, and tell it to fire tlasts every 256, 512 bit of data or whatever.
am i right so far?
02-14-2019 09:17 AM
Of note is that AXI DMA sees TLAST as the way to know it is the last data beat, not based on the number of descriptors. There is a bit that is set called TXEOF (and RXEOF for receiving data) in either the MM2S_STATUS or S2MM_STATUS registers. This is flagged when TLAST is sent, and the data that was sent is processed in subsequent BDs. Then when TVALID is set it will set the bit TXSOF (or RXSOF) which will indicate a new transfer, and the process will go on unless you run out of data or BDs.
A forum thread that describes some of this nicely: https://forums.xilinx.com/t5/Embedded-Processor-System-Design/Axi-DMA-S2MM-Is-it-necessary-to-assert-TLAST/td-p/743336
Not setting TLAST would not be a good idea (as mentioned in that thread), because then AXI DMA wouldn't know when to finish.
You could do everything that you described, as long as you are sending TLAST signals such that all your data can fit in the BDs you allocated. Technically, you shouldn't need more than 1 TLAST as that will define the end of your data (and when no TVALID is asserted), then AXI DMA will stop sending/receiving data.
The diagram in xaxidma.h would be able to show what goes on for each transfer with regards to the BDs. Another resource is in the Product Guide (PG021), it mentions the steps to get AXI DMA working on the software side. On page 70-71 of PG021 is the relevant information about Scatter Gather, and how you would need to initiate transfers.