USB host
USB low/full-speed host (HID keyboards, mice, gamepads).
| Core | Repository | Language | License | FPGA | Used by |
|---|---|---|---|---|---|
| Ultra-Embedded USB FS host (ulx3s-misc copy) ★ | emard__ulx3s-misc | Verilog, VHDL | GPL-2.0-or-later | any | 12 |
| circuit-killer minimal USB HID host | circuit-killer__fpga-usbhid-host | VHDL | none found | ECP5 | 1 |
| emard standalone USB1.1 host PHY/SIE (usb_host repo) | emard__usb_host | Verilog | none found | any | 0 |
| emard USB host + gamepad report decoders | emard__nes_ecp5 | Verilog | GPL-2.0-or-later | any | 4 |
| guh USB2 HS/FS host SIE + enumerator | apfaudio__guh | Python (Amaranth) | BSD-3-Clause | ECP5 | 0 |
| hdl4fpga USB 1.1 host core | hdl4fpga__hdl4fpga | VHDL | MIT (LICENSE, Miguel Angel Sagreras) | any | 4 |
| hurra-fpga bounded USB FS mouse host | voltcyclone__hurra-fpga | Python (Amaranth) | MIT (repo LICENSE; no per-file header) | ECP5 | 0 |
| HurricaneFPGA plain-Verilog USB host engine | voltcyclone__hurricanefpga | Verilog | MIT (repo LICENSE; no per-file header) | any | 0 |
Cores
Ultra-Embedded USB FS host (ulx3s-misc copy) (best)
Ultra-Embedded’s full-speed USB host SIE plus a HID-report host driver; the most reused USB-host core in the collection, copied into emard’s NES/Apple-1/Minimig/Next186/Papilio-Arcade/Phoenix/Apple2fpga cores for keyboard/gamepad input.
| Repository | emard__ulx3s-misc: ULX3S misc/advanced examples: EMARD’s building-block library |
| Files | examples/usb/usbhost/usbh_sie.v, examples/usb/usbhost/usbh_host_hid.v |
| Top module | usbh_sie |
| Language | Verilog, VHDL (usbh_sie_vhdl.vhd, usbh_host_hid.vhd variants also present) |
| License | GPL-2.0-or-later (file header, Ultra-Embedded.com, Copyright 2015-2019) |
| FPGA / primitives | any: none (portable) |
| Tests | none found in this copy |
On ULX3S: Drop-in on ULX3S US2 pins; pair with a report_decoder for the target gamepad/keyboard (see emard__nes_ecp5/usb/report_decoder).
Full review: emard__ulx3s-misc.
Used by 12 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):
- cheyao__nes_ecp5 (instantiates
top.v) - dan-rodrigues__icestation-32 (instantiates
hardware/usb/gamepads/usb_gamepad_reader.v) - emard__apple2fpga (instantiates
rtl_emard/lattice/top/ulx3s_v20_apple2.vhd) - emard__minimig_ecs (instantiates
rtl_emard/usb/usbhost/usbh_host.v) - emard__nes_ecp5 (instantiates
top.v) - emard__vhdl_phoenix (instantiates
rtl_emard/usb/usbhost/usbh_host.v) - ironsteel__nes_ecp5 (instantiates
top.v) - lawrie__ulx3s_examples (instantiates
usbemard/ulx3s_usbhost_test.v) - lawrie__ulx3s_zx_spectrum (instantiates
src/spectrum.v) - linuxjedi__minimig_ecs (instantiates
rtl_emard/usb/usbhost/usbh_host.v) - machdyne__nes_ecp5 (instantiates
top.v) - ulx3s__apple2fpga (instantiates
rtl_emard/usb/usbhost/usbh_sie_vhdl.vhd)
circuit-killer minimal USB HID host
Minimal single-file USB HID host state machine with CRC5/CRC16 helper functions, built for ULX3S 45F/85F (saitek/dragonrise-oled projects) with dedicated OLED demo tops.
| Repository | circuit-killer__fpga-usbhid-host: Minimal FPGA USB-HID host |
| Files | usbhid_host.vhd, usb_req_gen_func_pack.vhd |
| Top module | usbhid_host |
| Language | VHDL |
| License | none found (no LICENSE/COPYING file) |
| FPGA / primitives | ECP5: none (portable) |
| Tests | none found |
On ULX3S: No license file: get owner clearance before reuse.
Used by 1 other catalogued repo (file copies or module instances found by scan_core_usage.py; heuristic):
emard standalone USB1.1 host PHY/SIE (usb_host repo)
Standalone USB1.1 host PHY + SIE + register block, packaged as its own small ULX3S 12F demo with a BRAM firmware loader (ucmem/), separate from the ulx3s-misc/nes_ecp5 usbh_sie lineage.
| Repository | emard__usb_host: USB host core |
| Files | usb11/phy.v, usb11/sie.v, usb11/regs.v |
| Top module | SIE |
| Language | Verilog |
| License | none found |
| FPGA / primitives | any: none (portable) |
| Tests | 1 tb file in ./tb (not confirmed self-checking) |
On ULX3S: Demo bitstream targets ULX3S 12F (soc/build.sh –12k).
emard USB host + gamepad report decoders
Same usbh_sie host core as the ulx3s-misc copy, plus five ready HID report decoders for specific gamepads (NES-style, Saitek, Darfon, Xbox 360), the piece usually missing when reusing the bare host core.
| Repository | emard__nes_ecp5: NES (MiST core) on ULX3S: DVI, SDRAM, ESP32 OSD, USB gamepads |
| Files | usb/usbhost, usb/report_decoder |
| Top module | usbh_sie |
| Language | Verilog |
| License | GPL-2.0-or-later (same Ultra-Embedded usbh_sie.v core) |
| FPGA / primitives | any: none (portable) |
| Tests | none found |
On ULX3S: Use report_decoder/usbh_report_decoder_xbox360.v (or another pad’s file) to parse usbh_host_hid’s output into button state.
Used by 4 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):
- cheyao__nes_ecp5 (copies
usb/report_decoder/usbh_report_decoder_saitek.v) - ironsteel__nes_ecp5 (copies
usb/report_decoder/usbh_report_decoder_saitek.v) - lawrie__ulx3s_zx_spectrum (copies
src/usb/report_decoder/usbh_report_decoder_saitek.v) - machdyne__nes_ecp5 (copies
usb/report_decoder/usbh_report_decoder_saitek.v)
guh USB2 HS/FS host SIE + enumerator
USB host Serial Interface Engine (token packet generation, SOF controller, transfer engine) plus a full enumerator, layered on LUNA’s UTMITranslator/ULPI; backs class-specific host engines (HID keyboard, MIDI, mass-storage) in guh/engines/.
| Repository | apfaudio__guh: guh: Amaranth USB2 HS/FS host engine library |
| Files | guh/usbh/sie.py, guh/usbh/enumerator.py |
| Top module | USBSIE |
| Language | Python (Amaranth) |
| License | BSD-3-Clause (per-file SPDX header) |
| FPGA / primitives | ECP5: none (portable) |
| Tests | self-checking: tests/test_integration.py, tests/test_protocol.py (amaranth.sim.Simulator), via pdm run test = pytest |
On ULX3S: Runs directly on Cynthion via LUNA_PLATFORM=cynthion.gateware.platform:CynthionPlatformRev1D4 (README); primary target is the Tiliqua SoM, whose platform.py aliases pin names to match Cynthion’s (target_phy, control_vbus_en).
hdl4fpga USB 1.1 host core
Portable USB 1.1 host core, no vendor primitives, sharing a PHY with the device core (usbdev.vhd) via a build-time role switch; used on real ULX3S hardware in boards/ULX3S/apps/ser_debug.vhd.
| Repository | hdl4fpga__hdl4fpga: hdl4fpga: portable VHDL library, ScopeIO oscilloscope, SDRAM graphics, eth/USB links |
| Files | library/usb/usbhost.vhd, library/usb/usbphy.vhd |
| Top module | usbhost |
| Language | VHDL |
| License | MIT (LICENSE, Miguel Angel Sagreras) |
| FPGA / primitives | any: none (portable) |
| Tests | waveform tb in boards/ULX3S/testbenches |
On ULX3S: Set usb_device=false to select host mode in a ser_debug-style top.
Full review: hdl4fpga__hdl4fpga.
Used by 4 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):
- apfaudio__guh (instantiates
guh/usbh/types.py) - lawrie__spinalulx3s (instantiates
src/main/scala/mylib/UsbHidTest.scala) - spinalhdl__saxonsoc (instantiates
hardware/deprecated/ulx3s/peripheral/UsbHostHid.scala) - voltcyclone__hurra-fpga (instantiates
src/hurra_cynthion/control.py)
hurra-fpga bounded USB FS mouse host
Amaranth USB1.1/FS host core (USBHostTransactionArbiter + BoundedMouseHost) that enumerates a bounded HID mouse on Cynthion’s TARGET-A ULPI PHY and polls its interrupt-IN endpoint; part of a working host+device-clone relay with amaranth.sim test coverage.
| Repository | voltcyclone__hurra-fpga: hurra-fpga: Amaranth bounded USB FS mouse host+device-clone relay for Cynthion r1.4, with report injection… |
| Files | src/hurra_cynthion/host.py |
| Top module | BoundedMouseHost |
| Language | Python (Amaranth) |
| License | MIT (repo LICENSE; no per-file header) |
| FPGA / primitives | ECP5: none (portable) |
| Tests | self-checking: tests/test_host.py + related (amaranth.sim.Simulator), part of 24 sim-backed files run via pytest |
On ULX3S: Needs a real CynthionPlatform (via the external cynthion package) for platform.request(‘target_phy’); nextpnr needs –placer-heap-timingweight 60 to close timing on the 60MHz ULPI domain (see build_env.py).
HurricaneFPGA plain-Verilog USB host engine
Plain synthesizable Verilog USB1.1 host stack (bus reset, enumeration state machine, token/SOF generation, transaction engine) arbitrated for a Cynthion USB PHY port; drives raw D+/D- pins directly, no vendor primitives.
| Repository | voltcyclone__hurricanefpga: HurricaneFPGA: plain-Verilog Cynthion gateware - USB FS/LS sniffer/passthrough, USB host mode |
| Files | HDL/hardware/rtl/usb_interface/usb_host_arbiter.v, HDL/hardware/rtl/usb_interface/usb_enumerator.v, HDL/hardware/rtl/usb_interface/usb_transaction_engine.v, HDL/hardware/rtl/usb_interface/usb_token_generator.v, HDL/hardware/rtl/usb_interface/usb_sof_generator.v |
| Top module | usb_host_arbiter |
| Language | Verilog |
| License | MIT (repo LICENSE; no per-file header) |
| FPGA / primitives | any: none (portable) |
| Tests | HDL/hardware/testbenches/*.v (iverilog+vvp via HDL/hardware/testbenches/Makefile) - not self-checking, only $display trace |
On ULX3S: Portable logic in principle, but the lpf’s own comment admits its Cynthion pin LOCATEs are placeholders mapped to ULPI data pins (not real D+/D-), and top.v’s PLL is an unimplemented pass-through - treat as unverified/simulation-only, not a proven working host.
Other catalogued projects
Catalogued repos tagged usb-host (31) are listed in the full catalogue.