PCIe, SATA and SERDES links
Designs using the SERDES (DCU) of ECP5-5G / ECP5UM parts: PCIe PHY and link layers, SATA (LiteSATA), SGMII, USB3 PIPE and raw 8b10b links. The standard LFE5U parts (ULX3S 12F–85F) have no SERDES.
Cores
LiteSATA ECP5 SATA PHY + core (best)
Gen1/Gen2 SATA host: ECP5LiteSATAPHY (ecp5sataphy.py) does OOB gen/detection and CRG on top of liteiclink’s SerDesECP5 (DCUA), feeding LiteSATACore’s link/transport/command layers. Validated with IDENTIFY + 16 MiB write/verify BIST on ECPIX-5 (LiteX 2026.08 CHANGES).
| Repository | enjoy-digital__litesata: LiteSATA: Migen/LiteX SATA host core |
| Files | litesata/phy/ecp5sataphy.py, litesata/phy/__init__.py, litesata/core/__init__.py, bench/ecpix5.py |
| Top module | LiteSATAPHY |
| Language | Python (Migen/LiteX) |
| License | BSD-2-Clause (LICENSE) |
| FPGA / primitives | ECP5-5G: none (portable) |
| Tests | test/test_phy.py, test/test_command.py etc. (migen run_simulation + unittest, self-checking); hardware BIST claim in README/CHANGES, not reproduced in this clone |
On ULX3S: ULX3S (LFE5U) has no SERDES: only runs on LFE5UM/LFE5UM5G parts (e.g. ECPIX-5) with a SATA-wired DCU channel + 100 MHz refclk.
blazra TDR pulse driver/sampler on the ECP5 SERDES (liteiclink-derived)
Repurposes the liteiclink SerDesECP5PLL/SerDesECP5 DCUA wrapper (no PCS/8b10b framing) to drive and sample a raw pulse for time-domain reflectometry on a custom PCB, plus a small Wishbone/CSR sample-and-store RX FSM (daq.py). Working status unverified (1-line README).
| Repository | blazra__tdr: TDR (time-domain reflectometry) prototype driving/sampling a pulse over the ECP5 SERDES/DCU, LiteX SoC on an… |
| Files | gateware/versa_ecp5-litex/tdr/serdes_ecp5.py, gateware/versa_ecp5-litex/tdr/daq.py |
| Top module | SerDesECP5 |
| Language | Python (Migen) |
| License | BSD (file header: Copyright (c) 2018-2020 Florent Kermarrec, Copyright (c) 2020 Radovan Blazek) |
| FPGA / primitives | ECP5: DCUA |
| Tests | none found |
On ULX3S: ULX3S (LFE5U) has no SERDES; needs an ECP5 UM/UM5G part such as the Versa board this targets (litex_boards.platforms.versa_ecp5). daq.py’s simple sample buffer is reusable as a generic SERDES bit-capture block independent of the TDR use case.
ECP5-PCIe Amaranth PCIe PHY/LTSSM/DLL/TLP stack
PCIe Gen1 x1 endpoint: LatticeECP5PCIeSERDES wraps DCUA+EXTREFB (1:1 or 1:2 gearing), feeding an LTSSM/DLL/TLP stack with config space. Reaches L0 and captures DLLPs on an ECP5-5G EVN + custom PCIe adapter; no enumeration/TLP traffic shown in the README.
| Repository | ecp5-pcie__ecp5-pcie: ECP5-PCIe: PCIe Gen1 x1 endpoint PHY/LTSSM/DLL/TLP stack for the ECP5 SERDES, written in Amaranth HDL |
| Files | Gateware/ecp5_pcie/ecp5_serdes.py, Gateware/ecp5_pcie/ecp5_phy_x1.py, Gateware/ecp5_pcie/ltssm.py, Gateware/ecp5_pcie/dll.py, Gateware/ecp5_pcie/tlp.py |
| Top module | LatticeECP5PCIePhy |
| Language | Python (Amaranth HDL) |
| License | none found (no LICENSE file; Gateware/setup.py leaves license=’’ as a TODO) |
| FPGA / primitives | ECP5: DCUA, EXTREFB |
| Tests | Tests/*.py drive Amaranth’s built-in simulator (sim_scrambler.py, sim_crc_x2.py, sim_align.py, …) and hardware capture scripts (test_pcie_phy.py); no self-checking pytest/formal harness found, results are read by eye from captured DLLPs or gtkwave |
On ULX3S: ULX3S (LFE5U) has no SERDES; needs an ECP5 UM/UM5G part (e.g. ECP5-5G Evaluation Board, LFE5UM5G-85F) with a 100 MHz PCIe reference clock on the DCU pins.
Used by 2 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):
- whitequark__yumewatari (instantiates
yumewatari/gateware/platform/lattice_ecp5.py) - zyp__katsuo-pcie (copies
katsuo/pcie/phy/ecp5_serdes.py)
katsuo.pcie ECP5 SERDES PHY + PCIe endpoint stack
Amaranth ECP5SerDes (DCUA+EXTREFB, code reused from Yumewatari under 0BSD) drives an abbreviated LTSSM, DLL and TL (config space, MSI, mem-to-TileLink). Working PoC: enumerates as a PCIe Gen1 x1 device most of the time, no retransmit/flow control, SERDES sometimes fails to lock.
| Repository | zyp__katsuo-pcie: katsuo.pcie: Amaranth PCIe Gen1 x1 endpoint |
| Files | katsuo/pcie/phy/ecp5_serdes.py, katsuo/pcie/mac/ltssm.py, katsuo/pcie/dll, katsuo/pcie/tl |
| Top module | ECP5SerDes |
| Language | Python (Amaranth) |
| License | MIT (pyproject.toml; no LICENSE file in repo) |
| FPGA / primitives | ECP5-5G: DCUA, EXTREFB |
| Tests | tests/test_ltssm.py, test_dll.py, test_lane_aligner.py (pytest + amaranth sim, self-checking); no hardware CI, README documents hardware lspci behaviour |
On ULX3S: ULX3S (LFE5U) has no SERDES: needs an LFE5UM/LFE5UM5G board (e.g. Versa ECP5) with a PCIe-wired DCU channel and PCIe-rate refclk.
Used by 3 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):
- antoinevg__cynthion-tutorials (instantiates
src/gateware/platform/ecpix5_luna.py) - ecp5-pcie__ecp5-pcie (instantiates
Gateware/ecp5_pcie/ecp5_serdes.py) - greatscottgadgets__luna (instantiates
luna/gateware/interface/serdes_phy/ecp5.py)
kazkojima LiteEth SGMII PHY over ECP5 DCU (GBE mode)
SGMII (1000BASE-X) PHY built from Instance(‘DCUA’, CHX_PROTOCOL=’GBE’), a reduction of liteeth pcs_1000basex.py plus liteiclink serdes_ecp5.py for the DCU’s Gigabit-Ethernet mode. Used on an ECP5-5G Evaluation Board with a TI DP83867S add-on to run a LiteX/linux-on-litex-vexriscv SoC over Ethernet.
| Repository | kazkojima__litex-lattice-ecp5-evn: LiteEth SGMII PHY |
| Files | liteeth/ecp5sgmii.py |
| Top module | SGMIIECP5 |
| Language | Python (Migen) |
| License | BSD-2-Clause (file header: Copyright (c) 2019-2021 Florent Kermarrec, LiteEth) |
| FPGA / primitives | ECP5: DCUA |
| Tests | none found |
On ULX3S: ULX3S (LFE5U) has no SERDES; needs an ECP5 UM/UM5G part. Author calls the whole setup ‘experimental’; validated only with a home-brewed DP83867S daughterboard, not a stock module.
LiteICLink ECP5 SERDES (DCUA) wrapper
Generic ECP5 DCU wrapper: SerDesECP5PLL configures the channel PLL, SerDesECP5 wraps the DCUA primitive for 1.25-5 Gb/s 8b10b links with PRBS built in; base of LiteSATA’s ECP5 PHY and kazkojima’s SGMII port.
| Repository | enjoy-digital__liteiclink: LiteICLink: Migen/LiteX inter-chip link cores - generic ECP5 SerDes |
| Files | liteiclink/serdes/serdes_ecp5.py, bench/serdes/versa_ecp5.py |
| Top module | SerDesECP5 |
| Language | Python (Migen/LiteX) |
| License | BSD-2-Clause (LICENSE) |
| FPGA / primitives | ECP5-5G: DCUA |
| Tests | test/test_serdes_ecp5.py (migen run_simulation + unittest, checks 8b10b encode/decode round trip); bench/serdes/*.py are PRBS hardware benches, not self-checking sim |
On ULX3S: ULX3S (LFE5U) has no SERDES: needs an LFE5UM/LFE5UM5G part. For plain ULX3S, use liteiclink’s SerWB (bench/serwb/ulx3s.py) bit-banged link instead.
Used by 2 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):
- blazra__tdr (instantiates
gateware/versa_ecp5-litex/tdr/serdes_ecp5.py) - enjoy-digital__litesata (instantiates
litesata/phy/ecp5sataphy.py)
LitePCIe on ECP5 via katsuo.pcie (proof of concept)
ECP5PCIePHY (LiteXModule) adapts katsuo.pcie’s PIPE datapath to LitePCIe’s PHYTXDatapath/PHYRXDatapath; ecp5_pcie.v is a pregenerated Verilog snapshot of katsuo.pcie containing the DCUA/EXTREFB instances. README shows the device enumerating in lspci at 2.5 GT/s x1 on real Versa ECP5 hardware.
| Repository | zyp__litepcie-katsuo-poc: LitePCIe-on-ECP5 PoC: katsuo.pcie PHY under LitePCIe on Lattice Versa ECP5 |
| Files | ecp5_pcie.py, ecp5_pcie.v, lattice_versa_ecp5.py |
| Top module | ECP5PCIePHY |
| Language | Python (Migen/LiteX), Verilog (pregenerated ecp5_pcie.v) |
| License | MIT (pyproject.toml; no LICENSE file in repo) |
| FPGA / primitives | ECP5-5G: DCUA, EXTREFB |
| Tests | none found (no test files in this repo); README’s lspci output is the only evidence, on real hardware |
On ULX3S: Same SERDES requirement as katsuo.pcie: needs an LFE5UM/LFE5UM5G Versa-class board; ecp5_pcie.v is pregenerated for that board’s pin mapping, not portable as-is.
PavlenkoG ECP5 PCS-block PCIe protocol analyzer (Diamond)
Uses the ECP5UM(G) PCS block (Diamond-generated PCIe/EXTREF IP cores) to deserialize and 8b10b-decode PCI-Express lanes for protocol capture, streamed out over SPI and logged by a Raspberry Pi script. Built for a custom PCIe adapter on the ECP5-5G Evaluation Board.
| Repository | pavlenkog__ecp5_pcie_analyzer: ECP5_PCIE_Analyzer: uses the ECP5UM(G) |
| Files | fpga_logic/src/pcs_pci_rx.vhd, fpga_logic/src/pcs_pci_tx.vhd, fpga_logic/src/top.vhd |
| Top module | top |
| Language | VHDL |
| License | none found (no repo LICENSE; unrelated fpga_logic/src/lfsr_scrambler.vhd carries an OutputLogic.com 2009 permissive header) |
| FPGA / primitives | ECP5: PCSA (via Lattice Diamond Clarity Designer PCIe/EXTREF IP, fpga_logic/src/cores/{pcie,extref}/*.lpc) |
| Tests | fpga_logic/sim/vunit/analyzer_tb.vhd – VUnit testbench with self-checking asserts (e.g. ‘assert cnt /= addr_wr report …’), but run.py hardcodes Windows Aldec Active-HDL paths and Lattice sim libraries, so it needs a proprietary simulator to actually run |
On ULX3S: ULX3S (LFE5U) has no SERDES; this design is also tied to proprietary Lattice Diamond + Synplify and Clarity Designer IP (.lpc), so it cannot be rebuilt with the open toolchain without regenerating those cores.
Yumewatari ECP5 PCIe PHY (DCUA)
LatticeECP5PCIeSERDES wraps the DCUA/EXTREFB primitives (1:2 gearing) for a Versa ECP5-5G board; PCIePHY builds a PIPE-like PCIe Gen1 PHY on top (phy_rx/phy_tx, 8b10b alignment). Dormant since 2019; predecessor of the ECP5-PCIe project, code later reused (0BSD) inside katsuo.pcie’s ecp5_serdes.py.
| Repository | whitequark__yumewatari: Yumewatari: Migen PCIe Gen1 PHY for ECP5 |
| Files | yumewatari/gateware/phy.py, yumewatari/gateware/platform/lattice_ecp5.py, yumewatari/gateware/serdes.py |
| Top module | PCIePHY |
| Language | Python (Migen) |
| License | 0BSD (LICENSE-0BSD.txt) |
| FPGA / primitives | ECP5-5G: DCUA, EXTREFB |
| Tests | yumewatari/test/test_phy_rx.py, test_phy_tx.py, test_align.py (migen sim + unittest, self-checking); yumewatari/testbench/ltssm.py is an interactive/manual testbench, not self-checking |
On ULX3S: Needs an LFE5UM/LFE5UM5G Versa ECP5-5G board (EXTREF0/DCU0 wired to PCIe) plus the ispclock/*.jed refclk config; not usable on stock ULX3S.
Used by 1 other catalogued repo (file copies or module instances found by scan_core_usage.py; heuristic):
- ecp5-pcie__ecp5-pcie (instantiates
Gateware/ecp5_pcie/ecp5_phy_x1.py)
Other catalogued projects
Catalogued repos tagged serdes-pcie-sata (11) are listed in the full catalogue.