Library / SDK
enjoy-digital/litedram avatar
enjoy-digital/litedram

LiteDRAM is a configurable DRAM controller core written in Migen

Small footprint and configurable DRAM core

568 stars162 forksPythonNOASSERTION

At a glance

What is it?
LiteDRAM is a small footprint DRAM controller for FPGAs, described in Migen rather than Verilog so that the PHY, the command timing and the frontend can be configured from Python, and it can either be used as a LiteX library or dumped as generated Verilog. It supports DDR, LPDDR, DDR2, DDR3 and DDR4 PHYs across four FPGA vendors.
Who is it for?
Adopt LiteDRAM if you are building an SoC on an FPGA that needs external DRAM and you want a controller you can configure and read rather than a vendor core you have to accept, because the Migen description makes the timing parameters Python values and the same core can be exported as Verilog for a non-LiteX flow.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Writing the controller in Migen is the whole point

LiteDRAM describes itself as a small footprint and configurable DRAM core powered by Migen and LiteX, and the reason it is written the way it is comes in one line of the introduction: using Migen to describe the HDL allows the core to be highly and easily configurable.

Migen is a Python HDL, so a DRAM controller written in it is a Python program that emits Verilog. That has a concrete consequence for anyone considering this. The command timing, the PHY configuration and the frontend crossbar are not compile-time constants in a Verilog file that you edit and re-simulate; they are values in Python, and the core generator produces a Verilog file from them. Changing the memory geometry means editing a parameter, not tracing a timing diagram through a state machine.

The package metadata confirms the shape. The package is named litedram at version 2026.08, the description is Small footprint and configurable DRAM core, the author is Florent Kermarrec, and the install_requires is pyyaml and litex. The python_requires is ~=3.7, and there is a console entry point named litedram_gen pointing at litedram.gen:main, which is the generator that turns the Python description into Verilog.

The library is part of the LiteX family, and the README explains the family's aim as lowering the entry level of complex FPGA cores by providing simple, elegant and efficient implementations of components used in today's SoC, listing Ethernet, SATA, PCIe and SDRAM controller among them.

The second half of the design decision is the escape hatch. LiteDRAM can be used as a LiteX library or can be integrated with your standard design flow by generating the verilog rtl that you will use as a standard core. That matters more than it first appears, because it means the project is not a licence to adopt LiteX. You can take the generated Verilog, drop it into a Vivado or Quartus flow, and never touch LiteX again, keeping only the Python source as the configuration surface.

Seven vendor PHY families, and the ones that are still on the list

The PHY section is where the practical fit is decided, and it is a specific list rather than a generic claim.

There is a generic SDRAM PHY described as vendor agnostic and tested on Xilinx, Altera and Lattice, which is the fallback when a specific device PHY is not listed. Then there are the device-specific ones: Xilinx Spartan6 for DDR, LPDDR, DDR2 and DDR3 with a 1:2 or 1:4 frequency ratio, Xilinx Spartan7, Artix7, Kintex7 and Virtex7 for DDR2 and DDR3 with the same ratio options, Xilinx Kintex and Virtex Ultrascale plus Ultrascale Plus for DDR3 and DDR4 at 1:4, Lattice ECP5 for DDR3 at 1:2, and Gowin G2A for DDR3 at 1:2.

The frequency ratio is the detail that decides whether a PHY will work on your board. A 1:2 or 1:4 ratio describes how many memory clock cycles are needed per controller cycle, which determines the achievable data rate for a given controller clock. Getting it wrong means the core cannot keep up with the memory, and the symptom is a core that passes a short test and fails under sustained traffic.

Two gaps are visible in this list. There is no PHY for Altera devices specifically, and the possible improvements section lists add support for Altera devices as a to-do. There is also no Avalon-ST interface, which the same section lists as another to-do. Both entries are on the list of things EnjoyDigital will do if someone contacts them, which is the honest way of saying they are not scheduled.

The board examples in the repository tell you which devices are actually exercised: arty.yml, genesys2.yml, kcu105.yml, nexys4ddr.yml, ulx3s.yml, versa_ecp5.yml and xcu1525.yml, covering Digilent Arty, Genesys2, Nexys4DDR and ULX3S, Xilinx KCU105 and XCU1525, and Lattice Versa ECP5. So the PHY list and the example list line up, and both tell you the same thing about which boards are a known-good starting point.

The core, the frontend and what each layer does for you

The features are grouped into three layers, and the grouping is meaningful because each one is a separate decision you might make.

The core layer is what talks to the memory. It is fully pipelined and described as high performance, the command depth on the bank machines is configurable, it handles auto-precharge, and it does periodic refresh and ZQ short calibration with up to 8 postponed refreshes. That last number is the interesting one. Postponing refresh is a performance technique that trades a risk of missing a refresh deadline for throughput, and the limit of eight is the safety margin the core keeps. It is also a behaviour your memory part's datasheet has an opinion about, so it is a parameter you should check rather than accept.

The frontend layer is what your design talks to. The crossbar is configurable, and the README gives the ergonomics of it: simply use crossbar.get_port() to add a new port. Port arbitration is transparent to the user, so you do not arbitrate between masters yourself. The user interface can be Native, AXI-MM or Wishbone, there is a DMA reader and writer, there is a BIST for testing the memory path, and there is ECC.

ECC is worth flagging because it changes the design. Error-correcting code on the memory interface means the core detects and corrects single-bit errors on the data path, which matters if you are running in a radiation-sensitive or long-lifetime environment, and it also means the memory width and the interface width have to be reconciled, since ECC adds check bits. The feature list puts it alongside BIST without elaboration, so the details are in the core rather than in the README.

BIST is the other one worth understanding. A built-in self test lets you verify the memory path without a testbench full of traffic, which is what you want when bringing up a new board and the failure you are hunting is between the PHY pins and the controller.

Running the unit tests, and what the licence permits

There are unit tests in the test directory, and the README gives both ways to run them. All of them:

sh
$ ./setup.py test

Or one at a time by module name:

sh
$ python3 -m unittest test.test_name

The setup.py points the test_suite at test, so the first form is the standard entry point. The repository also has a .sim-test.py at the root, which suggests simulation-based testing is part of the workflow alongside the unit tests, and a bench/ directory for benchmarks, which is where you would look for timing headroom numbers on a given PHY.

On the licence, the README is unusually explicit. LiteDRAM is released under the very permissive two-clause BSD license, and under the terms of this license you are authorized to use LiteDRAM for closed-source proprietary designs. The setup.py lists license as BSD and the classifier as License :: OSI Approved :: BSD License, and the README badge says BSD 2-Clause. Note that the repository lists a custom licence that GitHub cannot classify, while the README and the setup.py both name the two-clause BSD.

The two-clause BSD matters for hardware for a specific reason. Unlike the GPL, it does not require you to publish the design files of a device you build with the core. For an FPGA or ASIC design that you intend to ship, that is the point of using this class of library at all, and the README says so directly.

The project then asks for things back without requiring them: tell the authors you are using LiteDRAM, cite it in publications related to research it has helped, send feedback and bug reports, and send your modifications and improvements. EnjoyDigital also offers standard commercial support and consulting, and the README closes with a request to contact them, partly to shorten the list of possible improvements.

Where LiteDRAM is the wrong core

Three limits, and the first is about the memory families it does not cover.

The first is the PHY list, read as a constraint rather than a feature list. There is no Altera device PHY, only a generic PHY described as tested on Altera. There is no DDR4 support outside the Xilinx Ultrascale and Ultrascale Plus families, no LPDDR beyond the Spartan6 line, and no PHY for any of the smaller or more recent device families. If your board is not in the examples directory, you are probably going to write or adapt a PHY, which is the single most vendor-specific and least portable part of a memory controller.

The second is the maturity label. The setup.py classifiers put the project at Development Status :: 3 - Alpha. The version scheme is a date, 2026.08, which is honest about a rolling release model but means there is no semantic version to pin and no changelog discipline implied by the version. For a component that ends up as the Verilog in your bitstream, that combination, a date-based version and an alpha status, is worth weighing.

The third is that a memory controller is the least interesting part of the problem and the most expensive to get wrong. LiteDRAM saves you from writing a DDR3 PHY, which is genuinely hard, but it does not save you from the signal integrity work: routing constraints, write leveling, read DQS training, the board-level length matching. Those are still yours, and a controller that is correct in simulation is not a memory that is correct on a board.

The alternative approach is a vendor memory interface IP, which every FPGA vendor ships and which is qualified, characterised and supported for their own devices, at the cost of being locked to that vendor and often to that Vivado or Quartus version. The difference in approach is that LiteDRAM gives you a vendor-agnostic controller whose PHY you can read and modify, with a permissive licence that lets you ship the result, while a vendor IP gives you a better-tested implementation of the same function with a licence and a toolchain attached to it. For a design that has to ship on one Xilinx board next quarter, the vendor core is usually faster. For a design that has to work across vendors, or that has to fit into an existing non-LiteX flow, LiteDRAM is the answer.

Getting started requires LiteX, a vendor toolchain and a supported board

The setup sequence is short and the README is explicit about the prerequisites. You install Python 3.6 or later and the FPGA vendor's development tools, then install LiteX and the cores by following the LiteX installation guide, and then you find examples of integrating the core with LiteX in LiteX-Boards and in the examples directory.

The vendor toolchain requirement is not incidental. LiteDRAM generates Verilog, and the generated core is then placed in a vendor project, so you need the vendor's tools regardless of whether you use LiteX or only take the Verilog.

The Python version in the setup.py is ~=3.7, which permits 3.7 and later, and the dependencies are pyyaml for the configuration files and litex itself. The develop extra pulls in meson, pexpect, setuptools and requests, which is the set a contributor needs for the native simulation flow.

The examples are the fastest way to see what a working configuration looks like. Each board file in the examples directory describes the memory device and the board's wiring, and the board list in the repository maps to specific hardware: the Artix7-based Arty, the Genesys2, the KCU105 and XCU1525 boards, the Nexys4DDR, the ULX3S and the Lattice Versa ECP5. Starting from the example for a board you own, or one close to it, is a faster route to a working core than writing the configuration from scratch.

The setup.py also excludes the test, sim, doc and examples packages from the installed distribution, so a pip install gives you the library and the generator entry point rather than the development scaffolding.

Editorial conclusion

Adopt LiteDRAM if you are building an SoC on an FPGA that needs external DRAM and you want a controller you can configure and read rather than a vendor core you have to accept, because the Migen description makes the timing parameters Python values and the same core can be exported as Verilog for a non-LiteX flow. Do not adopt it if you need a controller for a device outside the listed PHY families, since Altera support is listed as a possible improvement rather than a shipped feature, and note that the package itself declares Development Status 3 - Alpha. Verify first that your board and memory part match one of the shipped PHYs, because the PHY list is per vendor and per memory generation, that the refresh and ZQ calibration behaviour suits your memory, since the core can postpone up to eight refreshes, and that the generated Verilog drops into your flow with the timing constraints you expect, because that export path is the one thing the README does not detail.

Frequently asked questions

What is LiteDRAM and what is it built with?

It is a small footprint and configurable DRAM core for FPGAs, powered by Migen and LiteX. The core is described in Migen, a Python HDL, which is what makes it highly and easily configurable, and the package installs pyyaml and litex as its dependencies.

Which DRAM PHYs does LiteDRAM support?

A generic vendor-agnostic SDRAM PHY tested on Xilinx, Altera and Lattice, plus device-specific PHYs for Xilinx Spartan6, Spartan7, Artix7, Kintex7, Virtex7, Kintex and Virtex Ultrascale and Ultrascale Plus, Lattice ECP5 and Gowin G2A. The ratio of memory to controller clock is 1:2 or 1:4 for most of them.

How do I run the LiteDRAM unit tests?

Run ./setup.py test from the repository root to run them all, or python3 -m unittest test.test_name to run one module at a time. The setup.py points the test_suite at the test directory, and the repository also includes a .sim-test.py script for simulation-based testing.

Can I use LiteDRAM in a closed-source commercial design?

Yes. LiteDRAM is released under the two-clause BSD licence, and the README states that under its terms you are authorized to use LiteDRAM for closed-source proprietary designs. The project asks you to tell the authors you are using it and to send back modifications, but does not require it.

Can I use LiteDRAM without adopting LiteX?

Yes. LiteDRAM can be used as a LiteX library, or you can generate the verilog rtl and use it as a standard core in your own design flow, keeping the Python source only as the configuration surface.

What frontend features does the LiteDRAM core provide?

A configurable crossbar where a new port is added with crossbar.get_port(), transparent port arbitration, a Native, AXI-MM or Wishbone user interface, a DMA reader and writer, a BIST for testing the memory path, and ECC for error-correcting code.

Official sources

  1. enjoy-digital/litedram on GitHub
  2. Issues
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/enjoy-digital-litedram.svg)](https://hysenlabs.com/projects/enjoy-digital-litedram)

Was this useful?