Skip to content

LiteX Approach

github-actions[bot] edited this page Oct 28, 2026 · 4 revisions

This page is the why behind LiteX: the choices we made since 2012, building systems for clients and open-source projects, and still stand by. The code, the cores and the rest of this wiki follow from them.

The LiteX design flow

Python is the glue, Migen the HDL

A LiteX design is a Python program. Migen describes the logic (Modules, Signals, finite state machines, clock domains) and generates the Verilog; Python does everything around it: parameters, address maps, generated software headers, toolchain scripts, simulation, host scripts talking to the running SoC. A SoC is short because the work is in the cores and in the builder, not in each design.

Migen is a small DSL (sync vs comb, Signal, If/Else, FSM, Record) shared by the whole ecosystem of cores, and LiteX stays on it: it is stable, well understood, and no longer a barrier for an engineer coming from Verilog/VHDL, all the more since today's AI coding assistants are fluent in it. The LiteX for Hardware Engineers page is written for that reader, and existing Verilog/VHDL/Amaranth/SpinalHDL/Chisel cores are reused as they are, converted to Verilog at build time when needed.

A SoC is a composition of cores with stable contracts

Cores talk to each other and to the CPU through a small number of interfaces, and the whole framework is built on them:

  • Streams (valid/ready/first/last/payload/param) for data paths: converters, FIFOs, packetizers and clock domain crossings are generic and reused by every core.
  • Wishbone and AXI/AXI-Lite for memory-mapped traffic, with an interconnect (shared bus or crossbar), width/burst converters and bridges between them.
  • CSRs (control/status registers, generated by AutoCSR) for control: the same Python declaration gives the hardware register, its address, the C/Rust header, the csr.csv/json/svd description and the documentation.
  • EventManager for interrupts.

Because the contracts are stable, a core written for one project (a video pipeline, a PCIe DMA, a SerDes link) drops into another, and the SoC builder can wire the common parts (add_sdram, add_ethernet, add_pcie, add_sdcard, ...) in one call each.

Layered for portability

A protocol does not depend on the FPGA it runs on. The architectural style document is the reference; in short, each decision lives in its owning layer:

Layer Owns
Protocol core (LiteEth MAC, LitePCIe endpoint, LiteDRAM controller...) framing, state machines, stream behavior
Device adapter (litex/build/<vendor>, the PHYs) primitives, PLLs, SerDes, I/O, clock domains, reset sequences
Integration wrapper the stable stream/control/CSR interface between the two
Platform and target pins, clocks, constraints, which cores are instantiated

So the same SoC builds for Xilinx, Intel, Lattice, Gowin, Efinix, CologneChip, Anlogic or Microsemi parts, with vendor toolchains or the open-source ones (Yosys/nextpnr, Project Trellis/IceStorm/Oxide/Apicula/Peppercorn, F4PGA), and in Verilator. Adding a device means writing an adapter, not a copy of the protocol.

Simulation first, hardware with instruments

  • Cores are developed with Migen's Python simulator and pytest (test/ in each repository: unit tests with Python models, CI on every push).
  • A full SoC runs in Verilator with its real BIOS and firmware (litex_sim), with models for the serial port, Ethernet (TAP), SDRAM, SPI flash, SD card...; QEMU co-simulation runs the CPU in QEMU against the simulated gateware.
  • On hardware, the SoC is never a black box: a host bridge (UART, JTAG, Ethernet, PCIe) exposes the whole address space to the host (litex_server, litex_cli, Python scripts), LiteScope captures internal signals through the same bridge, and the CPU is debugged with GDB over JTAG. A board bring-up starts with the bridge and the BIOS, before any application.

Experiment, get it working, understand, refine, strip down

That is the order most LiteX features went through, and the last step matters as much as the first: what stays is the solid part the next project builds on. Features land when they have been used on real hardware; the Projects page shows where they come from, and the recent ones (USB3-PIPE, TriXium, LiteX-M2SDR) are documented with the same approach: simulation, measurements on the board, then upstream contributions to LiteX and the cores.

Practical rules

  • No vendor IP in the protocol cores. Vendor primitives stay in the device adapters, so that a design can move between vendors and to the open-source toolchains.
  • Keep the public names. Class names, constructor arguments, CSR layouts, command-line options and clock domain names are used by many targets; a refactor provides compatibility aliases or a migration path.
  • Generated outputs are the interface with software. csr.h, soc.h, mem.h, memory.x, csr.csv/json/svd and the device trees are generated from the SoC, never written by hand.
  • Standalone cores for other flows. The cores ship a generator (litedram_gen, liteeth_gen, litepcie_gen, litex_soc_gen, ...) producing a Verilog core with a plain interface for designs that are not LiteX SoCs (Export).
  • Validate with elaboration, simulation and one real build. A Python import proves nothing: elaborate every supported variant, run the tests, build a representative target when the toolchain is available, and say in the pull request what was not tested on hardware.
  • Code and commits in the house style: the coding style and module: Description of the change. (Feedback, contribution, support).

Releases and compatibility

LiteX and the cores are released together three times a year, tagged YYYY.04, YYYY.08 and YYYY.12 (the tag is the version on PyPI, litex_setup.py --tag=2026.08 checks out a release of every repository); master is where the development happens and is used by most projects. CHANGES.md lists what changed in each release, the release process how a release is made. CI builds and runs the test suite of each repository on every push (simulations of every CPU, buses, cores); an hardware CI runs the designs on real boards.

Where it comes from

LiteX was started by Enjoy-Digital to build custom FPGA systems for clients, and is still used for that: most of the cores and features come from these projects, were made open source with the clients' agreement and have been improved by the community since. Enjoy-Digital leads the development; the collaborative projects live in LiteX-Hub. The framework is permissively licensed (BSD-2-Clause), and we ask in return for feedback, contributions and the respect of the work involved (Feedback, contribution, support).

Next

Clone this wiki locally