Cyclone 5 F2SDRAM issue

I’m struggling with SDRAM access over a 128bit AXI F2SDRAM port on my Cyclone 5 DE10 Nano board.
On the FPGA, my IP core tries to access address 0x30100000. That’s the address I get from my device driver (dma_alloc_coherent). The controller accepts the read request but the response is a repeated byte pattern, e.g. 0xb2b2b2b2b2b2b2b2b2…
I tried to move CMA region to a lower address (0x1c000000) with the same result. Surprisingly, other addresses can be read from FPGA. I guess, the problem is caused by some Linux settings/actions.

What is even more weird: Reading the memory at 0x30100000 (resp. 0x1c000000) with CPU reveals that it is filled with random garbage. After access via FPGA, a region of 1 MB starting at address 0x30100000 is suddenly filled with the byte pattern I read on the FPGA SDRAM port.

Read access looks OK in signal tap:

Any ideas what is causing this? Probably any cache effects?

  1. Have you verified your RTL? That AXI looks fishy to me. Why do you keep your ARVALID asserted during a significant portion of your burst read? Although it sounds like it works well enough to do reads to other physical memory locations.
  • This still would not explain why the data changes when you do a read from the PL
  1. My understanding was that dma_alloc_coherent memory is not cached. I think Zynq uses dual A9’s much like CycloneV, so the kernel should behave the same way and this reference ought to be valid.
    https://forums.xilinx.com/t5/Embedded-Linux/DMA-caching-problem/td-p/570791
  1. Keeping ARVALID asserted is okay. AXI channels are independent of each other (more or less :wink:). I’m trying to fire out the next read command as soon as possible. Thus, ARVALID is high and the controller waits for ARREADY to be asserted. Apparently, the slave only supports 12 outstanding reads.

  2. That is also my understanding. I found out a bit more in the meantime:
    I had mapped the dma memory into user space using mmap and filled with with a test pattern. Instead of the pattern, I see what is depicted in the waveform above.
    Now, I also tried to write a test pattern to the dma memory from my kernel driver. Surprisingly, this works. I can actually see the data written by the kernel driver on the bus.
    I think I can rule out any AXI or RTL issues.
    I seems that the problem has to do with the mmap to user space. But I’m running out of ideas :thinking:

And…it was a very silly bug in my user space application…
Thanks anyway :smiley:

So I am actually running to issues on this same application now. For whatever reason, my arready is never asserting when I am using the DMA (30. DMA Controller Core)
It would appear as though the F2SDRAM is never ready to send me data or I am requesting data from a bad address. I am programming the DMA with the address I get from Linux in my driver using

typedef struct tx_dma_buf {
struct cdev cdev;
volatile phys_addr_t phys_addr_tx;
volatile unsigned int *virt_addr_tx;
volatile unsigned int *dma_regs;
dev_t dev_node;
struct class *class;
} tx_dma_buf_t;
tx_dma_buf_t *tx_dma_buf;
tx_dma_buf->virt_addr_tx = (unsigned int *)kmalloc(BUFFER_SIZE, GFP_KERNEL);
tx_dma_buf->phys_addr_tx = virt_to_phys( (volatile void *)tx_dma_buf->virt_addr_tx);

I know it’s old but your kernel code is wrong.

  1. why do you have volatile for phys_addr_tx?! it isn’t a pointer and this address should never be used to access anything
  2. DMA memory must NOT be allocated with kmalloc (dma_alloc_coherent)
  3. virt_to_phys shouldn’t be used, see 2.

If there is no IOMMU enabled, you’re accessing a random region of your RAM via DMA, that’s a huge problem, if you write to it, you might corrupt something with random data.

These are the latest versions of the files I am using. Please feel free to correct the buffer allocation.
https://drive.google.com/drive/folders/1eF8RhR024tLfaUnhejxUGysTrvlqMaax?usp=sharing

The driver allocates three buffers. The first buffer is for the processor to write V4L2 data into, then two others to serve as ping-pong buffers. At any given point, one buffer is being fed FPGA-processed data and the other is serving as the source for the VGA display.