Wednesday, May 24, 2023

Xilinx SDRAM IP Core

 I have used plain old SDRAM with different Intel (Altera) FPGAs - as Intel used to have IP core support in the Quartus for free. Well, it used to be free, but now it is removed from Quartus Lite (the option is to install from an older version).

But I always thought that using SDRAM with Xilinx is complicated as Xilinx does not offer plain old SDRAM IP core in the IP catalog.

Until today - I was challenged to test SDRAM on the new version of the MEGA65 home computer. So here is how it did go:

First google: "AXI SDRAM IP core"

taking the first hit, it goes to opencores that has link to the GitHub repository

Downloading from GitHub.

Vivado new project, create new peripheral, assigning nets to AXI memory mapped slave, packaging the IP core.

Vivado, add SDRAM IP Core

Vivado, add a new VHDL module - this was needed to have proper tristate buffers.

Vivado add Microblaze, run automation.

Connecting buses, clock and reset and making SDRAM IO's external.


This is what the new IP and tristate module looks like. Synthesize, open the IO window, type in the constraints for the clock, reset, and SDRAM. Starting to Generate Bitstream. Done, starting Vitis, new platform, new application, selecting memory test. Build, debug:

!?! it does not work, there comes memtest starting text then all is frozen. It does not work. What can it be? I did take an untested IP core in the hope it works. I have no intention of debugging this IP core. Looking at the IP core in block design. Ha, reset polarity is wrong! Changing, starting the build. Ready go, starting to debug in Vitis.

And it works!

We now have a free and working solution to support SDRAM on the Xilinx platform!

Easy as that. It did take less than two hours to verify this solution. So SDRAM on MEGA65 R4 is functional! 

It is interesting that it works the way I did it because the original IP core docs show that ODDR primitive has to be used for CLK output with clock inversion. I did not implement this! It is possible pure luck that it worked out of the box.

Adding clock forward block, connecting it to extra clock output from MMCM. Trying a 100MHz clock, working. Trying 133MHz clock working! Trying 166MHz clock, failing :(

Adjusting SDRAM clock phase on the MMCM, setting it to 180 degrees, and voila SDRAM is finally working at 166MHz! Changing SDRAM size to 32M bytes. Testing, working!

OK, trying to give the project for others to test out with the source files. Placing all source code to GitHub, done! Trying myself to open the GitHub project with Vivado 2022.2

OK, some manual tweaking seems to be needed, but with a few minutes of trying the project is compiling again. Seems that the version upgrade from the files provided in github is possible. There is also a MEMT.ELF file that runs 32Mbyte Xilinx memorytest application, it is included as file to initialize the brams so it will start if you program the bit file. Testing new bitfile and working. So the files from GitHub can be used to create working SDRAM test application for MEGA65. What I had todo was adding new IP repository path, changing the ELF file and removing and adding again the RTL modules.