Radio (FM/RDS, SDR)

FM/RDS transmitters, SDR receive chains, radio front ends.

Cores

1-bit AM transceiver chain (ULX3S-proven) (best)

Complete 1-bit AM transmit+receive chain (NCO, mixer, AM generator/demodulator, CIC decimation) with a real ULX3S top-level and LPF, taking RF in/out on GPIO pins and I2S audio out.

   
Repository jamesrosssharp__1_bit_am: jamesrosssharp/1_bit_AM: 1-bit oversampling-ADC AM radio transceiver experiment, targets ULX3S
Files src/am_gen.v, src/am_demod.v, src/mixer.v, src/nco.v, src/cic.v, impl/ulx3s/top.v, impl/ulx3s/ulx3s_v316.lpf
Top module top
Language Verilog
License MIT (LICENSE.txt)
FPGA / primitives ECP5: none (portable)
Tests none found (no tb/ directory found in this pass)

On ULX3S: impl/ulx3s/top.v is a direct ULX3S build target (gp9 RF in, gp8 RF out, gp1-4 I2S); impl/ulx3s/Makefile builds it as-is.

Used by 2 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

CORDICDemod I/Q amplitude/frequency/phase demodulator (Amalthea)

Pipelined multi-iteration CORDIC rotator that converts a streamed I/Q sample into amplitude, frequency and phase output streams; iteration count is parametrised (default 9), with a precomputed CORDIC angle table and gain correction.

   
Repository greatscottgadgets__amalthea: Amalthea: experimental Amaranth SDR gateware
Files amalthea/gateware/demod.py, amalthea/gateware/stream.py
Top module CORDICDemod
Language Python (Amaranth)
License BSD-3-Clause (LICENSE)
FPGA / primitives any: none (portable)
Tests none found (no test_demod.py in tests/; only test_complex.py, test_fft.py, test_fixed_point.py exist)

On ULX3S: Pure Amaranth, no vendor primitives, feeds from an IQStream (amalthea/gateware/stream.py); pairs with amalthea’s radio.py IQReceiver (which does use ECP5-only DELAYG/IDDRX1F for the AT86RF215 link, not needed if you supply I/Q another way).

DDS local oscillator

Generic phase-accumulator DDS core with a sine lookup table, intended as a local-oscillator source for an RF mixer front-end.

   
Repository nicocavallu__rf-dds-lo: Direct Digital Synthesizer
Files src/dds_top.v, src/phase_accumulator.v, src/sine_lut.v
Top module dds_top
Language Verilog
License none found (no LICENSE file)
FPGA / primitives any: none (portable)
Tests none found

On ULX3S: Board-independent; repo ships a ulx3s.lpf but no explicit nextpnr device size was found.

Used by 1 other catalogued repo (file copies or module instances found by scan_core_usage.py; heuristic):

FM stereo transmitter with RDS

Stereo FM transmitter with RDS (DBPSK) subcarrier generation, FIR/lowpass filters and RDS message RAM; demonstrated in the ULX3S fm example.

   
Repository emard__ulx3s-misc: ULX3S misc/advanced examples: EMARD’s building-block library
Files examples/fm/hdl/fm.vhd, examples/fm/hdl/fmgen.vhd, examples/fm/hdl/rds.vhd, examples/fm/hdl/fir.vhd, examples/fm/hdl/lowpass.vhd, examples/fm/hdl/bram_rds.vhd, examples/fm/hdl/message_ps.vhd, examples/fm/hdl/message_ps_rt.vhd
Top module fm
Language VHDL
License BSD (-- (c) Marko Zec / -- LICENSE=BSD on fmgen.vhd; other files in the set not individually re-checked)
FPGA / primitives any: none (portable)
Tests hdl/test/fmgen_test.vhd (VHDL testbench, waveform-only; not individually re-run here)

On ULX3S: examples/fm/top/top_fm.v is the ULX3S-ready top; has its own hdl/test/fmgen_test.vhd (VHDL testbench, waveform-only per repo convention).

Full review: emard__ulx3s-misc.

Used by 2 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

LoRa chirp-spread-spectrum modulator

Parametric LoRa chirp generator: phase accumulator + sin/cos LUT produce upchirp/downchirp/quarter-downchirp I/Q symbols for selectable BW (31.25-500kHz) and SF (6-12); the only LoRa modulator core in the collection.

   
Repository mehrdadh__lora-modulator: LoRa modulator: chirp-spread-spectrum LoRa TX
Files source/rtl/loRaModulator.v, source/rtl/chirpGenerator.v, source/rtl/accInc.v, source/rtl/phaseInc.v, source/rtl/initialPhase.v, source/rtl/sinIdeal.v, source/rtl/cosIdeal.v
Top module loraModulator
Language Verilog
License NC-AGPL-3.0 (custom Non-Commercial AGPL, LICENSE) - not an OSI/permissive license
FPGA / primitives any: none (portable)
Tests none found

On ULX3S: No vendor primitives; portable to ECP5/ULX3S as-is. Only built/tested on ECP5 25F (tinySDR board) via Lattice Diamond; needs a yosys/nextpnr-ecp5 top-level and .lpf for ULX3S.

rf-sdr-frontend digital downconverter

Full SDR DDC chain: 2-stage CDC, complex mixer against an 18-bit DDS LO, 3-stage CIC decimate-by-64, 31-tap FIR (Hamming), TPDF dither+truncate to 18-bit signed I/Q. Plain Verilog, no vendor primitives.

   
Repository nicocavallu__rf-sdr-frontend: RF-SDR-Frontend: LoRa-dechirp digital downconverter
Files src/digital_downconvert.v, src/complex_mixer.v, src/cic_filt.v, src/fir_filter.v, src/tpdf_dither.v, src/dither_truncate.v, src/sdr_frontend_top.v
Top module sdr_frontend_top
Language Verilog
License none found
FPGA / primitives any: none (portable)
Tests sim/sdr_frontend_top_tb.v (iverilog+gtkwave): waveform-only, no PASS/FAIL or assert found

On ULX3S: No board-level Makefile/lpf of its own; only the rf-dds-lo submodule ships an ulx3s.lpf. Sim-only in this clone (iverilog+gtkwave).

Standalone RDS DBPSK modulator

RDS modulator with DBPSK (by Davor Jadrijevic), circulates a memory address to fetch 8-bit RDS data words, MSB first.

   
Repository emard__rdsfpga: RDS FM transmitter
Files rds.vhd, fmgen.vhd
Top module rds
Language VHDL
License BSD in headers (-- LICENSE=BSD; no repo-level LICENSE file)
FPGA / primitives any: none (portable)
Tests none found

On ULX3S: Per project memory this repo’s board target is ULX2S-only; the rds.vhd/fmgen.vhd modules themselves are board-independent and match the ones bundled in ulx3s-misc’s fm/ example.

Superheterodyne AM/FM receive chain with per-block testbenches

Mixer, AM/FM demodulators, 19kHz pilot bandpass filter and DPLL for a superheterodyne receiver, built against an external RF mixer add-on PCB on the ULX3S.

   
Repository jamesrosssharp__ulx3s_mixer_pcb: 100MHz PLL + RF mixer/demodulator PMOD board, with matching ULX3S SDR receiver HDL
Files hdl/src/mixer.v, hdl/src/am_demod.v, hdl/src/fm_demod.v, hdl/src/dpll.v, hdl/src/bandpass_19khz.v, hdl/src/cic.v, hdl/src/aud_cic.v, hdl/src/nco.v, hdl/impl/ulx3s/top.v
Top module top
Language Verilog
License MIT (hdl/LICENSE.txt)
FPGA / primitives ECP5: none (portable)
Tests per-block testbenches under hdl/test/ (e.g. 001_NCO/tb.v, 008_DPLL/tb.v); waveform-dump only ($dumpvars/VCD), no self-checking assertions seen

On ULX3S: hdl/impl/ulx3s/top.v is a real ULX3S target; each DSP block has its own testbench under hdl/test//tb.v.

Used by 4 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

WSPR 4-FSK beacon codec (message/FEC/interleave/symbols/modulator)

Full WSPR protocol chain: packs callsign/locator/power to bits, convolutional-encodes, interleaves, maps to the 162 4-FSK symbols (with sync vector), then emits a continuous-phase 4-FSK tone stream with exact Bresenham-distributed symbol timing.

   
Repository agamez__whisperice: wspr-icebreaker: autonomous VHDL-93 WSPR
Files src/wspr/wspr_message.vhd, src/wspr/wspr_fec.vhd, src/wspr/wspr_interleave.vhd, src/wspr/wspr_symbols.vhd, src/wspr/wspr_sync.vhd, src/wspr/wspr_modulator.vhd
Top module wspr_modulator
Language VHDL-93
License MIT (repo LICENSE; no per-file header)
FPGA / primitives any: none (portable)
Tests make sim (ghdl –std=93): sim/tb_wspr_{message,fec,interleave,symbols,sync,modulator,top}.vhd - self-checking (VHDL asserts, –assert-level=error, Makefile:145)

On ULX3S: Pure VHDL-93, no vendor primitives; only needs a clock and a 1-bit rf_out pin plus external filtering. Built/tested for iCE40UP5K @ 12 MHz but portable to ECP5 at any clock (recompute NCO increments with tools/calculate_nco.py).

CORDIC-1 bit-serial CORDIC/DDS sine engine

Bit-serial 16-iteration CORDIC (rotate+vector modes) using a 20-bit shift-register datapath, 3 full adders and fixed-tap bit-muxing instead of barrel shifters; constant 359-cycle op, no vendor primitives.

   
Repository joaln27__cordic: CORDIC-1: bit-serial CORDIC engine
Files src/cordic.sv
Top module cordic
Language SystemVerilog
License Apache-2.0 (LICENSE; SPDX header in file)
FPGA / primitives ECP5: none (portable)
Tests cocotb, self-checking (test/test.py + unit_cordic.py vs a Python reference CORDIC/atan2 model); also exhaustive 65536-angle sim and SymbiYosys formal proof outside this repo’s test/ dir

On ULX3S: Instantiated unchanged in fpga/ulx3s_top.sv on a real ULX3S 85F; hardware output matches RTL sim bit-exact (389/389 CRC-32 signatures, fpga/meter/, 2026-09-25).

Used by 11 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

Digital down-converter + AM/FM demod chain (post-ADC)

Digital down-converter, tuner NCO, AM/FM demodulators plus CIC decimator and FIR filter, fed from an external fast ADC on OrangeCrab 25F; no vendor primitives seen.

   
Repository emeb__orangecrab_adc: OrangeCrab ADC FeatherWing: AD9203 10-bit/40MSPS ADC + audio board, gateware for SDR tuning/AM demodulation
Files gateware/verilog/src/ddc_14.v, gateware/verilog/src/demods.v, gateware/verilog/src/tuner_2.v, gateware/verilog/src/cic_dec_4.v, gateware/verilog/src/fir8dec_par.v
Top module ddc_14
Language Verilog
License none found (no LICENSE file in repo)
FPGA / primitives any: none (portable)
Tests none found

On ULX3S: Needs an external high-speed ADC on ULX3S (no onboard equivalent); the DSP chain itself (CIC/FIR/demod) is portable.

Used by 3 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

Gage1999/fpga-sdr-receiver 256-pt iterative radix-2 FFT

Iterative in-place 256-pt radix-2 FFT: one butterfly module reused across all 8 stages via a ping-pong BRAM bank, 128-entry inline cos/sin LUT, bit-reversed output; 16-bit signed I/Q in, 8-bit log-magnitude + 8-bit bin index out. Feeds an SDR spectrum/waterfall display in this repo.

   
Repository gage1999__fpga-sdr-receiver: fpga-sdr-receiver: ECP5 iCESugar-Pro SDR
Files icesugar_pro/src/fft256.sv, icesugar_pro/src/butterfly.sv, icesugar_pro/src/twiddle_rom.sv
Top module fft256
Language SystemVerilog
License MIT (LICENSE)
FPGA / primitives any: none (portable)
Tests icesugar_pro/Makefile:sim_fft (iverilog): tb/tb_fft256.sv - self-checking (PASS/FAIL, DC-bin and single-tone peak checks)

On ULX3S: Built for ECP5 (iCESugar Pro LFE5U-25F) but no vendor primitives instantiated in these 3 files; drop-in on ULX3S ECP5 designs.

Used by 1 other catalogued repo (file copies or module instances found by scan_core_usage.py; heuristic):

HackRF Amaranth CIC/FIR/NCO/mixer DSP chain

Amaranth CIC interpolator/decimator (cic.py), half-band FIR decimator/interpolator (fir.py), a 1/8-wave-LUT NCO (nco.py) and a complex mixer built on 4 iCE40 SB_MAC16 DSP blocks (mixer.py) forming the HackRF Pro baseband RX/TX chain. Unit-tested against numpy reference models.

   
Repository greatscottgadgets__hackrf: HackRF firmware/fpga: Amaranth DSP gateware for the HackRF Pro
Files firmware/fpga/dsp/cic.py, firmware/fpga/dsp/fir.py, firmware/fpga/dsp/nco.py, firmware/fpga/dsp/mixer.py, firmware/fpga/dsp/dc_block.py, firmware/fpga/dsp/sb_mac16.py
Top module n/a
Language Python (Amaranth)
License BSD-3-Clause (SPDX header in each file, e.g. dsp/nco.py); repo-wide COPYING is GPL-2.0
FPGA / primitives iCE40: SB_MAC16
Tests firmware/fpga/test/test_{cic,fir,fir_mac16,mixer,fixed}.py (Amaranth Simulator + numpy models): self-checking (assertEqual/assert against a Python reference model)

On ULX3S: cic.py/fir.py/nco.py/dc_block.py instantiate no vendor primitives and elaborate to plain Verilog via Amaranth+yosys, so they are portable to ECP5 with the standard Amaranth ECP5 platform. mixer.py’s ComplexMultiplier instantiates SB_MAC16 directly (dsp/sb_mac16.py) and needs an ECP5 MULT18X18D rewrite to reuse there.

ZipCPU SDR CORDIC + CIC + AM/FM demodulator chain

Sequential (one sample/cycle) CORDIC vector rotator feeding a CIC integrate-and-dump decimator and a generic filter-then-downsample block; amdemod.v and fmdemod.v compose these into AM and FM demodulators (fmdemod recovers phase via an I+Q PLL then differentiates it). No vendor primitives, formally-flavoured ZipCPU coding style.

   
Repository zipcpu__sdr: ZipCPU/sdr: ‘Gateware Defined Radio’ - AM/FM/QPSK transmitter and receiver designs for an iCEBreaker + SX1257…
Files rtl/seqcordic.v, rtl/cicfil.v, rtl/subfildown.v, rtl/amdemod.v, rtl/fmdemod.v
Top module fmdemod
Language Verilog
License GPL-3.0-or-later (file headers, e.g. rtl/cicfil.v; no LICENSE file in this clone)
FPGA / primitives any: none (portable)
Tests sim/ (Verilator, main_tb.cpp): builds an interactive simulator, no automated pass/fail check found (README: ‘isn’t very useful at present’ without the -d VCD switch)

On ULX3S: Board-independent Verilog, originally paired with an SX1257 RF PMod on an iCEBreaker. Good reference for a CORDIC-based FM discriminator or AM envelope detector on ECP5.

Used by 2 other catalogued repos (file copies or module instances found by scan_core_usage.py; heuristic):

Other catalogued projects

Catalogued repos tagged radio-tx (9), radio-rx (15), fm-transmitter (1), dsp-sdr (41) are listed in the full catalogue.


Back to top

Generated from the JSON in data/ by the scripts in .claude/skills. Facts cite the upstream file at the reviewed commit; verify before reuse.

This site uses Just the Docs, a documentation theme for Jekyll.