# LUNA: an Amaranth HDL framework for building USB devices and protocol analysers in gateware

> LUNA is a Python and Amaranth HDL library that lets you implement a USB device in gateware rather than on a microcontroller, which makes passive protocol analysis and custom peripherals possible with an FPGA. It ships gateware, applets and examples, and the maintainers split the project into what works now, protocol analysis, device creation and SoC integration, and what is planned, USB proxying and security research tooling.

**greatscottgadgets/luna** — Amaranth HDL framework for monitoring, hacking, and developing USB devices

- Repository: https://github.com/greatscottgadgets/luna
- Website: https://greatscottgadgets.com/cynthion/
- Stars: 1,143 · Forks: 188
- Language: Python
- License: BSD-3-Clause
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/greatscottgadgets-luna

## What LUNA actually is: USB implemented in gateware

LUNA is a toolkit for working with USB using FPGA technology, providing gateware and software to enable USB applications. The primary language is Python, and the homepage is greatscottgadgets.com/cynthion.

The key idea is that the USB device is not a microcontroller running firmware, it is logic inside an FPGA. That is a different engineering trade-off from the usual one. Firmware gives you a CPU, a memory model and an easy edit cycle, at the cost of timing and bus-level control. Gateware gives you cycle-accurate behaviour and direct access to the bus, at the cost of writing state machines by hand and recompiling to see a change.

The framework is built on Amaranth HDL, a Python-based hardware description library. The project is a toolkit in the sense that it provides reusable components rather than one application.

The repository structure shows the layering. The luna/ directory is the primary Python toolkit, which generates gateware and provides USB functionality, and luna/gateware/ holds the core gateware components along with utilities for stitching them together. The examples/ directory holds simple LUNA-related examples, described as mostly gateware-targeted currently. The docs/ directory holds the sources for the Sphinx documentation, contrib/ holds contributed and non-core components such as udev rules, and applets/ holds pre-made gateware applications that provide useful functionality on their own and are more than examples.

That applets directory is worth calling out, because it is the difference between a library and a toolkit. A library gives you parts; applets are finished, useful gateware programs you can flash and use, which is what makes the project approachable to someone who wants protocol analysis rather than gateware authorship.

The project is Great Scott Gadgets', the same organisation behind Cynthion, and the licence is BSD-3-Clause with a Development Status of 4 - Beta in the package classifiers. The distribution is named luna-usb and the package version is dynamic, derived from git through setuptools-git-versioning starting at 0.1.0. The recent releases are 0.2.3 on 2025-08-22, 0.2.2 on 2025-08-01 and 0.2.1 on 2025-06-10.

## What works now: analysis, device creation, SoC integration

The project makes an unusual distinction that is worth reading carefully, because it tells you exactly where the boundaries are. It separates what you can use LUNA for currently from what you will be able to use it for in the future.

Three things are in the current category.

Protocol analysis for Low-, Full- or High-speed USB. LUNA provides gateware that allows passive USB monitoring when combined with Cynthion and Packetry. Passive is the operative word: the device observes the bus without participating in it, which is the requirement for safe analysis of somebody else's hardware, and it means the FPGA is not driving the USB lines at all. Cynthion is the hardware, an open source USB test instrument, and Packetry is the software for USB analysis.

Creating your own Low-, Full-, High- or, experimentally, Super-speed USB device. This is the collection of Amaranth gateware that allows you to easily create USB devices in gateware, software, or a combination of the two. The split between gateware, software and a mix is a real design axis, and the combination case is the interesting one, where the FPGA handles timing critical parts and the software layer handles configuration.

Building USB functionality into a new or existing System-on-a-Chip. LUNA is capable of generating custom peripherals targeting the common Wishbone bus, which allows it to be integrated into SoC designs, and the luna-soc library provides simple automation for developing simple SoC designs. Wishbone is an open bus specification, and choosing it rather than a vendor specific interconnect is what makes the output portable between SoC projects.

Note the Super-speed caveat, which is attached to the device creation item and marked experimental. Super-speed is the USB 3.x and later link speed, and the forward-looking section does not mention it at all, which suggests the support is partial.

The two future items are more security oriented. Man-in-the-middle'ing USB communications, where the toolkit will be able to act as a USB proxy, transparently modifying USB data as it flows between a host and a device. And USB reverse engineering and security research, where the toolkit is intended to serve as a backend for tools like Facedancer, allowing easy emulation and rapid prototyping of compliant and non-compliant USB devices.

The distinction matters for planning. If your project needs to sit in the middle of a USB link and rewrite packets, that is not available yet, and the words will be able to in that section are the project's own.

## The Python package and its dependency stack

The pyproject.toml describes a package with a small, specific dependency set, and each one tells you something about the architecture.

The direct dependencies are libusb1, pinned above 1.9.2, for talking to USB devices through the native library rather than through a kernel driver; pyserial at 3.5 or newer, for the serial link to an FPGA board; pyusb above 1.1.1 as the Python USB API; and pyvcd above 0.2.4, which is a Value Change Dump writer, used to write waveforms out of the gateware for inspection in a waveform viewer.

Then the two that define the project. amaranth is pinned to the 0.5 series, with the ~= compatible release operator, and usb-protocol to 0.9.2 or newer. The amaranth constraint is a compatible release pin rather than a floor, which means the project tracks a specific minor line of the HDL library rather than allowing drift into a new major version. usb-protocol is the separate package holding the USB protocol definitions, which is why the dependency list includes a package that is not about hardware or USB host APIs at all but about the specification itself.

The build system is setuptools with setuptools-git-versioning, and the version is dynamic. The package discovery is scoped with where set to the repository root and include set to luna*, so the examples, applets, contrib and tests directories are not installed as importable packages.

The optional dev group adds two things. apollo_fpga, which is the FPGA support for the Apollo debug controller firmware, and prompt-toolkit above 3.0.16, which is a terminal UI library and therefore points at the interactive tools in the project. The Apollo dependency is the giveaway that LUNA is not standalone: the firmware that configures the FPGA on the Cynthion is a separate project, and LUNA drives it.

The test command is configured as a PDM script, running python -m unittest discover with the tests directory and the verbose flag. So the test suite is the standard library unittest runner, not pytest, which is consistent with a project that wants minimal tooling on top of a hardware dependency stack.

## The Docker image: a full FPGA toolchain and the Cynthion board

The Dockerfile is the clearest statement of what it takes to work on this project, and it is heavier than a typical Python package.

The base is ubuntu:22.04 with USER root, and the first thing done is creating a user with the uid and gid 1000 to match the host system, with a jenkins user and home directory. The comment explains why, and it is the same reason the container exposes 8080 at the end, this is a build and test environment rather than an application image.

The apt-get list is where the real cost shows. bison, build-essential, clang, cmake, curl, dfu-util, flex, gawk, gcc-arm-none-eabi, git, jq, libboost-all-dev, libeigen3-dev, libreadline-dev, openocd, pkg-config, python3, python3-pip, python3-venv, tcl, tcl-dev and zlib1g-dev.

Four of those deserve a note. gcc-arm-none-eabi is the bare metal ARM toolchain, needed because the Apollo firmware on the debug controller is itself embedded code. openocd is the on-chip debugger used with the debug probe. dfu-util is for the device firmware update mode. And bison and flex are the parser generators, which for a USB stack means the descriptors and the protocol layer are parsed at build time.

Then the synthesis toolchain. The image fetches the latest release of the YosysHQ oss-cad-suite build, filters the assets for linux-x64, and unpacks it into the image, with an ARG CACHEBUST=1 to defeat layer caching. That is a large download, and the CACHEBUST argument is a deliberate way to say this layer must be rebuilt on every build rather than served from cache.

A pip install of the CapableRobot_USBHub_Driver from GitHub follows, which is the driver for a USB hub used in the test setups.

The last two environment variables are what tie the container to specific hardware. The PATH is extended with the oss-cad-suite bin directory, and LUNA_PLATFORM is set to cynthion.gateware.platform:CynthionPlatformRev0D4, which names the Cynthion board revision 0D4 as the target platform for the gateware. That is a concrete detail worth knowing, because it means the container is configured for one specific board revision, and a different revision means a different platform string.

The container is also a Jenkins environment, given the user and the exposed port.

## The related projects, and where the ecosystem boundaries are

The related projects section is really a map of the toolchain, and it shows that LUNA is one piece of a set rather than a standalone product.

Cynthion is the open source hardware USB test instrument, and it is the physical thing you need. Apollo is the firmware that runs on the Cynthion debug controller and which is responsible for configuring its FPGA, so Apollo is the bridge between the software and the silicon. Saturn-V is a DFU bootloader created for Cynthion, which is how the firmware gets onto the device. Packetry is the software for USB analysis, and it is what turns the captured traffic into something readable. Facedancer is software to create USB devices in Python, and the project names it as the kind of tool the toolkit is intended to serve as a backend for.

The layering is coherent. LUNA generates gateware. Apollo loads and runs it on the debug controller. The debug controller drives the USB bus. Packetry decodes what was captured. Cynthion is the board that holds all of it together, and Saturn-V is how the firmware is updated.

That means adopting LUNA means adopting that chain. It is not a pip install and a Python script, it is a specific piece of hardware with specific firmware, and the Dockerfile confirms it by pinning LUNA_PLATFORM to one Cynthion board revision.

The examples directory mirrors the same shape. There is a blinky example, which is the minimal FPGA program and the natural first target for anyone new to gateware, a blinky_verilog variant, and then examples/debugging/, examples/phy/ and examples/usb/. The phy directory is the physical layer, which is where the electrical protocol lives, and the usb directory is where the bus logic sits. The debugging example is the one to look at if you want to know how the project expects you to work, because debugging gateware is the hard part and an example that demonstrates it is worth more than a paragraph.

The repository also carries a Jenkinsfile at the top level, alongside a Dockerfile and a ci-scripts/ directory, which tells you the CI is Jenkins based rather than GitHub Actions, with the Dockerfile providing the build environment. There is a .gitmodules file, so submodules are part of the checkout, and a .readthedocs.yaml for the documentation, plus a code_of_conduct.md and a CHANGELOG.md.

On maintenance, the repository is not archived and the last push was on 2026-08-19, while the most recent release is 0.2.3 from 2025-08-22. The topic tags are fpga, hardware and usb, which is a narrow and clear scope.

## Conclusion

LUNA fits a hardware engineer or security researcher who needs a USB device implemented in gateware, who has an FPGA and the Great Scott Gadgets toolchain to hand, and who is willing to work at the register and protocol level. It is the wrong tool if you want to build a USB peripheral in firmware, where a microcontroller is simpler and cheaper, and it is the wrong tool if you need Super-speed USB today, since that support is listed as experimental. Before adopting, read the docs directory sources and check the applets directory for something that already does what you need, and remember that the toolkit is at version 0.2.x with a BSD licence and a beta development status.

## FAQ

### What is LUNA and what can it do with USB?

LUNA is an Amaranth HDL framework that implements USB in FPGA gateware. It currently supports passive protocol analysis for Low-, Full- and High-speed USB, creation of your own Low-, Full-, High- or experimentally Super-speed USB device in gateware, software or a mix, and generating custom Wishbone bus peripherals for System-on-a-Chip designs.

### What hardware do I need to use LUNA?

A Cynthion, the open source hardware USB test instrument from Great Scott Gadgets, which runs the Apollo firmware responsible for configuring its FPGA. The project's Docker image sets LUNA_PLATFORM to cynthion.gateware.platform:CynthionPlatformRev0D4, so it targets a specific Cynthion board revision.

### Can LUNA act as a man in the middle on a USB link?

Not yet. The project lists man-in-the-middle'ing USB communications as something you will be able to use LUNA for in the future, where the toolkit acts as a USB proxy that transparently modifies USB data flowing between a host and a device. USB reverse engineering and security research are in the same future category.

### What does the LUNA project structure look like?

The luna/ directory holds the primary Python toolkit and the core gateware components in luna/gateware/, examples/ holds simple mostly gateware-targeted examples, docs/ holds the Sphinx documentation sources, contrib/ holds contributed components such as udev rules, and applets/ holds pre-made gateware applications that are more than examples.

## Sources

- [greatscottgadgets/luna on GitHub](https://github.com/greatscottgadgets/luna)
- [License: BSD-3-Clause](https://github.com/greatscottgadgets/luna/blob/main/LICENSE)
- [Project website](https://greatscottgadgets.com/cynthion/)
- [README](https://github.com/greatscottgadgets/luna/blob/main/README.md)
- [Releases](https://github.com/greatscottgadgets/luna/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/greatscottgadgets-luna
