Accessing External DDR4 RAM

In my block diagram, I added DDR4 MIG to be able to access external RAM in my jupyter project using MMIO. However when I used my C app to try to access the external RAM, I am getting different data. What am I missing here?

Can you provide more info?

Guide to posting here:


So I put in the MIG IP in my block diagram and have the address offset at 0x0400000000. Then using jupyter, I write some test data at this offset in python. To test that I can read the same data from the same address offset, I use the peek.c to read data from the same offset but the data came out different.

Address editor:

Result of Jupyter test:


Result from peek C application:


Peek code:

Which board/device, PYNQ image? Precomiled image, and image you built yourself?


I am using ZCU104 board with the base PYNQ image.

Thanks. Did you try read back in Python what you wrote, or are you only checking from C?

Just looking at your C code again. I’m not sure if you are using the right types for 64-bit system (ZCU104/Zynq Ultrascale).
I presume “unsigned” for addr is unsigned int, which I think will be 32 bit. Maybe try check this first, and printf addr from within your C program to check?


1 Like

So I tried to assign addr with unsigned long int and when doing this peeking at 0x40000000, it gave seg fault.

Did you check if you can read back what you wrote in Python?


I did. The read back in python is the same data.

Hello @Laplace,

As @cathalmccabe mentioned your are not using the right types in your C code. Have a look at this simple piece of code. It shows the byte size of the different types and how your address is interpreted by the different types.


When you compile it, you can see some warning that the address was truncated for unsigned and unsigned long

Look at the result when you execute it


The above image shows that only unsigned long long and uint64_t types can hold the 64-bit address.

It always a good idea to check the byte size of a type using sizeof() as the number of bytes changes depending on the processor’s architecture. However, (u)int*_t guarantees the byte size independently of the processor’s architecture

Hopefully this helps.

typesTest.c (767 Bytes)

So using unsigned long long, it works now but using unsigned long int, it does not work even though I check that unsigned long int is 8 bytes using sizeof.

@Laplace, physical addresses do not have sign, so in this particular case use unsigned long long or uint64_t.
It is working for you now, so this post is solved.


1 Like