Post Go back to editing

Peripheral to Memory DMA Transaction using no-OS Driver for axi_dmac HDL IP with ADAQ23878

Thread Summary

The user encountered issues with the AXI DMAC IP block in Vivado 2020.2, where data was zeroed after a software request in Autorun mode and cyclic transfers did not update the DDR destination buffer. The solution involved invalidating the data cache after each DMA transaction or disabling it at startup. The user also inquired about enabling transfer done interrupts for cyclic mode, which is not supported; instead, scatter-gather mode can be used to monitor end-of-transfer events.
AI Generated Content
Category: Hardware
Product Number: ADAQ23878

I also posted this issue here: ADI HDL Github

Describe the bug
Using the axi_dmac in Vivado, I am able to transfer FIFO input data from peripheral to DDR only once using Autorun mode. But doing a software request to the same address sets the destination data to zero.

To Reproduce

  1. Setup Vivado project with axi_dmac IP Block, set Source to FIFO width 32-bit, Destination to AXI3 64-bit wide, enable Autorun with Destination address 0x10000000. Connect fifo_wr_din[31:0] to a 32-bit constant block with 0xaabbccdd (test data), and fifo_wr_en to a single bit constant of 1.
  2. Build a Vitis project with any of these sets of sources:
  1. Connect to Zynq PS7 UART port with baud 115200 or add breakpoint on the last line of the while loop.
  2. Start debug session to flash bitfile and program elf.
  3. See that:
  • Initial data on DMA_TEST_BUFFER1 (0x10000000) is the FIFO test data.
  • Data is zeroed by memset at the start of the while loop.
  • DMA transaction completes and interrupt is obtained, but data on DMA_TEST_BUFFER1 (0x10000000) is still zero.

Expected behavior
Data on destination (0x10000000) should be test data (0xaabbccdd) after each DMA transaction has been completed

Desktop

  • Project name: adaq23878_eval
  • Carrier board: Omdazz XC7Z020 Zedboard-compatible with FMC
  • Used Software: No-OS
  • Tool version: Vivado 2020.2
  • HDL Release version: git commit a22fce4
  • No-OS Software Release version: git commit b75d62f

Additional context
Also, if I connect the DMA block to the ADC IP block, even after enabling Cyclic mode in the AXI_DMAC IP Block and setting the Autorun Flags to 0x1 (CYCLIC) or 0x7 (CYCLIC, TLAST,PARTIAL_REPORTING_EN), I only observe one DMA transfer. If I disable TESTPAT, I still see the same data on the destination buffer (0x330fc), it does not change if the ADC data changes (there is an ILA block and I can see that the ADC data is changing). Expected behavior is that the data on DDR destination would change as the ADC data changes. 

Vivado block diagram with ADC block connected: design_1_adc_connected.pdf

Edit Notes

Fixed typo
[edited by: bleudoutremer at 7:57 PM (GMT -4) on 10 Sep 2025]

Thread Notes

  • Hello,

    I moved your thread to the FPGA Reference Designs group for better assistance regarding the HDL side.

    As we are looking into this issue, could you please provide us more details:

    • Is there any particular reason why you chose to use Vivado 2020.2? We offer support only for the latest releases, with their correspondent Vivado versions, that can be found here: Releases · analogdevicesinc/hdl.
    • Did you modify the adaq2387 HDL design (except for porting it to another carrier)?

    Regards,

    Stanca

  • Hi Stanca,

    I was having some UI bugs with the newer Vivado versions, but if you believe the issue is related I can try updating it.

    The Vivado project is a simplified version of CN0577. The AXI LTC2387 and AXI DMAC source have not been modified in any way, just cloned the repo and built them.

    Kind regards,

    Vitor.

  • Regarding the DMA issue, someone from our team is looking into it and will come back with an answer in the upcoming days.

    In the meantime, I have an auxiliary question:

    By "simplified version" you mean that you deleted the logic that you found unnecessary from cn0577 and followed the build_hdl guide, or you manually added the IPs in your design either from the Vivado GUI or from a custom tcl script?

  • I have built the cn0577 project and the IP blocks using the build_hdl guide and used it as a reference. The adaq23878_eval project whose diagram I showed was made by manually adding the IP blocks using the GUI. I also replicated the IP customization and constraints as much as I could.

  • So I checked out the 2023_r2_p1 HDL release, regenerated all the HDL using Vivado 2023.2, exported and regenerated adaq23878_project for Vivado 2023.2 with write_project_tcl.

    I noticed the axi_dmac from 2023_r2_p1 does not have Autorun. I disabled cyclic mode and used the no-os-driver project I shared before with the 2023_R2 branch of the no-OS repo. 

    Still got the same result. I am able to see the ADC test pattern 0x330fc in the ILA but no transfer is performed with axi_dmac_transfer_start / axi_dmac_transfer_wait_completion. Destination data is still zero.

  • Found the problem. We need to invalidate the data cache after the DMA transfer or disable it a the start. 

    #include "xil_cache.h"
    
    // Either disable the data cache at startup or invalidate after each DMA transaction
    //Xil_DCacheDisable();
    
    /* ... other code ...*/
    
    dma_transfer_and_wait(&transfer1);
    Xil_DCacheInvalidate();

    This seems to work with both the newer axi_dmac in Autorun/Cyclic mode and the older core (2023_r2_p1 release) in single transfer mode.

    I saw there is a cache-coherency option and tried to enable it in the block but it didn't work. Tried the default values and experimented with others but so far only the software solution worked.

  • Hello  ,

    Sorry for the long wait. We discussed internally and the feedback is that we currently support Cache-Coherency only on Linux. We are planning to add support on No-OS, too, but we don't have a specific timeline for that.

    Was this the only issue that you encountered?

  • Hi Stanca,

    No problem. That sounds good. Yes, this has been the only issue so far.

    I have another question regarding IRQ generation. The docs say that the TRANSFER_COMPLETED interrupt is not generated for cyclic mode.

    Is it possible somehow to enable the transfer done interrupts for cyclic transfers, or use another interrupt to monitor the end of transfer?

    I was thinking of enabling autorun and setting the transfer size to something like 1K ADC samples so that would give a lower interrupt rate even on cyclic mode.

  • Hi,

    Cyclic mode does not generate interrupts, so you'd have to use another approach to get the end-of-transfer interrupts.

    You can either submit the same transfer in a loop, therefore having access to each transfer interrupt individually, or you can use scatter-gather transfers in which you can set the end-of-transfer interrupt flag of each descriptor. Please note that we currently offer support for scatter-gather transfers on linux only.

    Regards,

    Ionut

  • Hi Ionut,

    OK then, I'll try to use scatter-gather mode to do it.

    Will mark this as answered.

    Kind regards,

    Vitor.

Before You Switch


Switching languages will make ADI Explorer unavailable. Resume your session by switching back to English and reopening ADI Explorer.