Litex and FPGA
Litex
fjullien migen_litex_tutorials <-- Best Litex tutorial
ICEStorm Install icestorm_install.md
LiteLib
LiteLib provides a collection of small, reusable hardware building blocks for Migen-based FPGA designs. These cores fill gaps not covered by LiteX's built-in core library.
Originally ported from the Amaranth-based amlib utility library, all cores are pure Migen with no LiteX dependency — they can be used standalone in any Migen project or integrated into a LiteX SoC.
Litex and Efinix 2026-08
- Use Ubuntu 22.04 Python > 3.9
- No venv needed
- Install Litex along side efinix Tools
- Pay attention to which python3 path
- Only set LITEX_ENV_EFINITY="~/efinity-yyyy-d-linux-x64/efinity/yyyy.mm"
Litex Radiant Synth Tool Change
Add "--synth-mode=lse" after "--build"
Litex CSR is the Key to Connect to the Bus and the World
Litex without CPU
class BaseSoC(SoCMini):
def __init__(self, platform, **kwargs):
sys_clk_freq = int(100e6)
# SoCMini (No CPU, we are controlling the SoC over UART)
SoCMini.__init__(self, platform, sys_clk_freq,
csr_data_width=32,
ident="Hello World! \r\n",
ident_version=True)
# No CPU, use Serial to control Wishbone bus
self.add_uartbone(name="uart_debug", baudrate=115200)
#self.add_jtagbone()
# FPGA identification
self.submodules.dna = dna.DNA()
self.add_csr("dna")
Litex Bus
# Wishbone Master
serwb_slave_core = SERWBCore(self.serwb_slave_phy, self.clk_freq, mode="master")
self.submodules += serwb_slave_core
# Wishbone SRAM
self.serwb_sram = wishbone.SRAM(8192)
# self.comb += serwb_slave_core.bus.connect(self.serwb_sram.bus)
# You cannot do it.
self.submodules.wbreg = wbreg = WBSlave_Reg()
# self.comb += serwb_slave_core.bus.connect(wbreg.bus)
self.slave_bus = SoCBusHandler(
name = "SoCSlaveBusHandler",
standard = "wishbone",
data_width = 32,
address_width = 32,
)
self.slave_bus.add_master("s_master", serwb_slave_core.bus)
self.slave_bus.add_slave("ssram", self.serwb_sram.bus, region=SoCRegion(origin=0x3000_0000, size=0x0000_2000))
self.slave_bus.add_slave("sreg", wbreg.bus, region=SoCRegion(origin=0x3000_3000, size=0x0000_1000))
Litex Instance External Verilog
din = Signal(32)
dout = Signal(32)
dinout = Signal(32)
self.specials += Instance("custom_core",
p_DATA_WIDTH = 32,
i_din = din,
o_dout = dout,
io_dinout = dinout
)
#################################################################
# Create a Dict for the Parameters/IOs.
params_ios = dict()
# Add the Parameters.
params_ios.update(
p_DATA_WIDTH = 32
)
# Add the IOs.
params_ios.update(
i_din = din,
o_dout = dout,
io_dinout = dinout
)
# Do the Instance:
self.specials += Instance("custom_core", **self.params_ios)
#################################################################
for i in range(fifo_ports):
litedram_params.update(**{
# FIFO In.
f"i_user_fifo_{i}_in_valid": axis_in[i].valid,
f"o_user_fifo_{i}_in_ready": axis_in[i].ready,
f"i_user_fifo_{i}_in_data" : axis_in[i].data,
# FIFO Out.
f"o_user_fifo_{i}_out_valid": axis_out[i].valid,
f"i_user_fifo_{i}_out_ready": axis_out[i].ready,
f"o_user_fifo_{i}_out_data" : axis_out[i].data,
})
#################################################################
platform.add_sources("./", #Search path location
"core0.v",
"core1.vhd",
"core2.sv"
)
Litex use Radiant IP to wrap into Module
class Counter(LiteXModule):
def __init__(self, platform):
self.co = Signal()
platform.add_sources("./myCounter/rtl",
"myCounter.v",
)
platform.add_sources("./myCounter/constraints",
"myCounter.ldc",
)
clk_en_i = Signal()
q_o = Signal(24)
self.comb += [
clk_en_i.eq(1),
self.co.eq(q_o[23])
]
self.specials += Instance("myCounter",
i_clk_i = ClockSignal("sys"),
i_clk_en_i = clk_en_i,
i_aclr_i = ResetSignal("sys"),
o_q_o = q_o
)
Litex SPI Master with FIFO
#
# This file is part of LiteSPI
#
# Copyright (c) 2020 Antmicro <www.antmicro.com>
# SPDX-License-Identifier: BSD-2-Clause
from migen import *
from litex.gen import *
from litex.soc.interconnect import stream
from litex.soc.interconnect.csr import *
from litex.soc.interconnect.csr_eventmanager import *
from litespi.common import *
class LiteSPIMaster(LiteXModule):
"""Generic LiteSPI Master
The ``LiteSPIMaster`` class provides a generic SPI master that can be controlled using CSRs.
It supports multiple access modes with help of ``width`` and ``mask`` registers which can be used to configure the PHY into any supported SDR mode (single/dual/quad/octal).
Parameters
----------
fifo_depth : int
Depth of the internal TX/RX FIFO.
cs_width : int
Number of CS lines to support.
Attributes
----------
source : Endpoint(spi_phy2core_layout), out
Data stream.
sink : Endpoint(spi_core2phy_layout), in
Control stream.
cs : Signal(), out
Slave CS signal.
"""
def __init__(self, cs_width=1, tx_fifo_depth=1, rx_fifo_depth=1, with_irq=False):
self.sink = stream.Endpoint(spi_phy2core_layout)
self.source = stream.Endpoint(spi_core2phy_layout)
self.cs = Signal(cs_width)
assert self.sink.data.nbits == self.source.data.nbits
self._cs = CSRStorage(cs_width)
self._phyconfig = CSRStorage(fields=[
CSRField("len", size=len(self.source.len), offset=0, description="SPI Xfer length (in bits)."),
CSRField("width", size=4, offset=8, description="SPI Xfer width (1/2/4/8)."),
CSRField("mask", size=8, offset=16, description="SPI DQ output enable mask (set bits to ``1`` to enable output drivers on DQ lines)."),
], description="SPI PHY settings.")
self._rxtx = CSR(self.source.data.nbits)
self._status = CSRStatus(fields=[
CSRField("tx_ready", size=1, offset=0, description="TX FIFO is not full."),
CSRField("rx_ready", size=1, offset=1, description="RX FIFO is not empty."),
])
# Clock Divider.
self._clk_divisor = CSRStorage(len(self.source.clk_div))
# # #
# FIFOs.
self.tx_fifo = tx_fifo = stream.SyncFIFO(spi_core2phy_layout, depth=tx_fifo_depth)
self.rx_fifo = rx_fifo = stream.SyncFIFO(spi_phy2core_layout, depth=rx_fifo_depth)
self.comb += self.sink.connect(rx_fifo.sink)
self.comb += tx_fifo.source.connect(self.source)
# SPI CS.
self.comb += self.cs.eq(self._cs.storage)
# SPI TX (MOSI).
self.comb += [
tx_fifo.sink.valid.eq(self._rxtx.wr_stb),
self._status.fields.tx_ready.eq(tx_fifo.sink.ready),
tx_fifo.sink.data.eq(self._rxtx.wr_data),
tx_fifo.sink.len.eq(self._phyconfig.fields.len),
tx_fifo.sink.width.eq(self._phyconfig.fields.width),
tx_fifo.sink.mask.eq(self._phyconfig.fields.mask),
tx_fifo.sink.clk_div.eq(self._clk_divisor.storage),
]
# SPI RX (MISO).
self.comb += [
rx_fifo.source.ready.eq(self._rxtx.rd_stb),
self._status.fields.rx_ready.eq(rx_fifo.source.valid),
self._rxtx.rd_data.eq(rx_fifo.source.data),
]
if with_irq:
self.ev = EventManager()
self.ev.rx_ready = EventSourceProcess(edge="rising")
self.ev.finalize()
self.comb += [
self.ev.rx_ready.trigger.eq(rx_fifo.source.valid),
]
Litex Setting for Radiant Setting
In BaseSOC
platform.add_platform_command(
"ldc_set_sysconfig {{JTAG_PORT=ENABLE MCCLK_FREQ=14.1 DONE_PORT=ENABLE INITN_PORT=ENABLE PROGRAMN_PORT=ENABLE DONE_OD=ON WAKE_UP=ENABLE_DONE_SYNC MASTER_SPI_PORT=SERIAL}}"
)
platform.add_platform_command(
"ldc_set_sysconfig {{MASTER_SPI_PORT=SERIAL BOOTMODE=SINGLE CONFIGIO_VOLTAGE_BANK0=1.8 CONFIGIO_VOLTAGE_BANK1=1.8 CONFIG_IOSLEW=FAST}}"
)
In Build main()
Creating LiteX wrappers
Migen Simulation
Counter
from migen import *
class DPLL(Module):
def __init__(self):
self.count = Signal(4)
self.sync += self.count.eq(self.count + 1)
def dpll_test(dut):
for i in range(20):
print((yield dut.count))
yield
if __name__ == "__main__":
dut = DPLL()
run_simulation(dut, dpll_test(dut), vcd_name="dpll.vcd")
Migen Selection of Signal from Signal as Index
shiftout = Array({} for i in range(REG_Number))
for i in range(16):
shiftout[0][i] = [self.spi_miso1.eq(Regsiters[0][i] & ~self.spi_cs)]
shiftout[1][i] = [self.spi_miso2.eq(Regsiters[1][i] & ~self.spi_cs)]
for i in range(REG_Number):
self.comb += [
Case(shift_count, shiftout[i])
]
Migen Case
self.comb += Case(word_cound,{
0: self.uart_tx.eq(start_b0),
1: self.uart_tx.eq(start_b1),
2: self.uart_tx.eq(timestamp_b0),
3: self.uart_tx.eq(timestamp_b1),
4: self.uart_tx.eq(timestamp_b2),
5: self.uart_tx.eq(timestamp_b3),
"default": self.uart_tx.eq(0),
})
Migen Module
Migen Reset FSM
fsm = FSM(reset_state="WAIT")
fsm = ClockDomainsRenamer("icap")(fsm)
fsm = ResetInserter()(fsm)
self.submodules += fsm
self.comb += fsm.reset.eq(~(self.write | self.read))
IceStorm toolset for ICE40 FPGA
# Project setup
PROJ = blinky
BUILD = ./build
DEVICE = 8k
FOOTPRINT = ct256
# Files
FILES = top.v
.PHONY: all clean burn timing
all $(BUILD)/$(PROJ).asc $(BUILD)/$(PROJ).bin:
# if build folder doesn't exist, create it
mkdir -p $(BUILD)
# synthesize using Yosys
yosys -p "synth_ice40 -top top -blif $(BUILD)/$(PROJ).blif -json $(BUILD)/$(PROJ).json" $(FILES)
# Place and route using arachne
#arachne-pnr -d $(DEVICE) -P $(FOOTPRINT) -o $(BUILD)/$(PROJ).asc -p pinmap.pcf $(BUILD)/$(PROJ).blif
nextpnr-ice40 --hx$(DEVICE) --json build/$(PROJ).json --pcf pinmap.pcf --asc build/$(PROJ).asc
# Convert to bitstream using IcePack
icepack $(BUILD)/$(PROJ).asc $(BUILD)/$(PROJ).bin
burn: $(BUILD)/$(PROJ).bin
iceprog $(BUILD)/$(PROJ).bin
timing: $(BUILD)/$(PROJ).asc
icetime -tmd hx$(DEVICE) $(BUILD)/$(PROJ).asc
clean:
rm build/*
Lattice Radiant and Propel
Lattice Propel and Radiant Install IP or Module
Chisel FPGA開発日記
https://msyksphinz.hatenablog.com/
Agile Hardware Design Video 2024

Amaranth
Verilog
https://verilogguide.readthedocs.io/en/latest/
The Art of FPGA Design - element14 Community
The Art of FPGA Design - element14 Community
Digital Signal Processing, from Algorithm to FPGA Bitstream - element14 Community
Digital Signal Processing, from Algorithm to FPGA Bitstream
Xilinx Petalinux
使用Buildroot编译AMD/Xilinx Zynq ZC702 单板 Linux (内核和文件系统)
🌐使用Buildroot编译AMD/Xilinx Zynq ZC702 单板 Linux (内核和文件系统)
ZCU104_MPSoC Development - Petalinux 2024.2 Basic Tutorial
🌐ZCU104_MPSoC Development - Petalinux 2024.2 Basic Tutorial
Xillinux
🌐Xillinux: A Linux distribution for Z-Turn Lite, Zedboard, ZyBo and MicroZed
The Xillinux distribution is a software + FPGA code kit for running a full-blown graphical desktop on the Z-Turn Lite, Zedboard and (non-Z7) ZyBo, attaching a monitor, keyboard and mouse to the board itself. Xillinux also supports MicroZed without the graphics.
UltraZed-EG PCIe Carrier Card 開發紀錄
🌐UltraZed-EG PCIe Carrier Card 開發紀錄 使用 PetaLinux 建立系統
Petalinux Demo
🎬Xilinx Zynq & PetaLinux Project Demo
🎬PetaLinux SPI Device Control LCD Panel
🎬Creating Multi-Boot Bitstream In Xilinx FPGA
🎬Xilinx HLS Project Demo - SHA256 Calculation
Perfecting PetaLinux Workshop
💾Perfecting PetaLinux Workshop
🎬Perfecting PetaLinux Workshop
📚PetaLinux Tools Documentation: Reference Guide (UG1144)
Vivado Vitis Petalinux 2024 on Ubuntu 2024
🌐Vivado Vitis Petalinux 2024.2
🌐Hardware acceleration in FPGA with Vivado and Vitis

Zynq PetaLinux and Vitis
🌐Fixed Platform Design on Zynq-7000 in Vitis 2024.1