← All projects

RF · Signal Processing · FPGA

Spec-to-Hardware: an AI-Orchestrated RF Receiver

A single written specification driving three coupled deliverables — the RF front-end hardware, the signal-processing algorithm model, and the FPGA firmware — demonstrated on a 6-channel frequency-hopping CPFSK receiver. An AI agent drives a trusted deterministic toolchain (MATLAB, RF Toolbox, Simulink, HDL Coder, ModelSim/Vivado) to design, implement, and validate all three, collapsing a years-long, many-handoff process into weeks with an expert in the loop at every stage.

66 / 66
Frames CRC-valid
143.5 ns
Worst-case latency
11
Waveforms decoded
Bit-exact
vs MATLAB in ModelSim

The transmitted signal

A 6-channel FH-CPFSK burst. Each transmission is six dwells; within a dwell the transmitter sends one 96-symbol framed packet — an 8-bit 1010 preamble, a 5-bit SFD, a 3-bit sequence number, an 8-byte payload, and a CRC-16. The receiver must recover every frame under barrage jamming and ±5% symbol-timing variation simultaneously.

Figure 1 — Example transmitter output — accumulated phase with the PRE/SFD/HDR/PAYLOAD fields, the six frequency-hopped dwells in time, the transmitted spectrum over the six hop channels, and the spectrogram.
Figure 1Example transmitter output — accumulated phase with the PRE/SFD/HDR/PAYLOAD fields, the six frequency-hopped dwells in time, the transmitted spectrum over the six hop channels, and the spectrogram.

Architecture

The analog front end is built from the measured S-parameters of real, catalogue commercial parts — an 8-stage cascade feeding a 5 GSa/s RF-ADC. On the RFSoC FPGA, a digital down-converter mixes to complex baseband, low-passes, and decimates to 128 MSa/s. The decode kernel buffers one dwell at a time, measures that dwell's symbol period from its envelope, locks the hop channel, and lets the CRC arbitrate a short phase-offset search for the frame start — a two-pass approach that makes the chain robust to the jammer and the timing variation.

Figure 2 — RF front end and RFSoC FPGA logic — the measured-S-parameter parts feed a 5 GSa/s RF-ADC; the on-die FPGA runs the DDC, per-dwell buffer, and decode kernel.
Figure 2RF front end and RFSoC FPGA logic — the measured-S-parameter parts feed a 5 GSa/s RF-ADC; the on-die FPGA runs the DDC, per-dwell buffer, and decode kernel.
Figure 3 — Receiver signal chain — RF front end and DDC feed a per-dwell buffer; the decode kernel does channel-lock, period measurement, and a CRC-arbitrated offset search.
Figure 3Receiver signal chain — RF front end and DDC feed a per-dwell buffer; the decode kernel does channel-lock, period measurement, and a CRC-arbitrated offset search.

At a glance

ModulationBinary continuous-phase FSK (CPFSK)
Hopping6 channels, 18 MHz spacing, 2.0 GHz center
Occupied band1.58–2.20 GHz
Symbol / bit rate8 Msym/s (8 Mbit/s)
Converter14-bit RFSoC Gen3 RF-ADC, direct sampling @ 5 GSa/s
RF front end8-stage measured-S-parameter cascade (≈26 dB @ 2 GHz)
Latency budget≤ 400 ns (worst case achieved: 143.5 ns)
ImplementationFixed-point RTL, HDL-Coder synthesizable

Real measured RF front end

Not an idealized model: each stage is a real catalogue part, applied from its measured Touchstone S-parameters. The BFCN band-pass pair selects the 1.58–2.20 GHz band at ≈ +26 dB with deep out-of-band rejection, and the group delay used in the latency budget is read from the measured phase, not assumed.

Figure 4 — Each component's S21 (from its Touchstone file) and the total cascaded response; the band-pass pair selects the signal band (shaded) at ≈ +26 dB.
Figure 4Each component's S21 (from its Touchstone file) and the total cascaded response; the band-pass pair selects the signal band (shaded) at ≈ +26 dB.
Figure 5 — Front-end spectrum — the measured cascade selects the signal band from the direct-sampled input; the ADC code-stream spectrum follows the cascade S21 shape.
Figure 5Front-end spectrum — the measured cascade selects the signal band from the direct-sampled input; the ADC code-stream spectrum follows the cascade S21 shape.

The decode kernel, dwell by dwell

Worked through one barrage-jammed transmission (tx_20260808_111143): the kernel locks each hop channel, recovers the drifting symbol period, confirms per-symbol timing, syncs on the SFD, and decodes all six frames CRC-valid.

Figure 6 — Per-dwell channel lock — 6-channel matched-filter energy; the whole-dwell argmax recovers the hop sequence under the barrage jammer.
Figure 6Per-dwell channel lock — 6-channel matched-filter energy; the whole-dwell argmax recovers the hop sequence under the barrage jammer.
Figure 7 — Symbol-timing recovery — the recovered per-dwell period tracks the ±5% drift via envelope segmentation and a period-refine search.
Figure 7Symbol-timing recovery — the recovered per-dwell period tracks the ±5% drift via envelope segmentation and a period-refine search.
Figure 8 — Early-late timing discriminant — bounded across every dwell, confirming stable per-symbol timing.
Figure 8Early-late timing discriminant — bounded across every dwell, confirming stable per-symbol timing.
Figure 9 — Frame synchronization — the sync correlation locks at every dwell SFD (red = frameValid).
Figure 9Frame synchronization — the sync correlation locks at every dwell SFD (red = frameValid).
Figure 10 — Full-record decode — all six frames CRC-valid.
Figure 10Full-record decode — all six frames CRC-valid.

Fixed-point core & HDL

The floating-point reference is converted to a fixed-point datapath and handed to HDL Coder. The generated Verilog is bit-exact against the reference across the whole record.

Figure 11 — Fixed-point decode datapath with word sizes — int16 I/Q → NCO/mix/integrate → channel energy → argmax → correlators + offset search → bit decision → frame back-end (CRC-16, payload).
Figure 11Fixed-point decode datapath with word sizes — int16 I/Q → NCO/mix/integrate → channel energy → argmax → correlators + offset search → bit decision → frame back-end (CRC-16, payload).

Results

Every waveform decodes all six frames CRC-valid through the full chain — 3 clean and 8 barrage-jammed / ±5%-timing files, 66/66 frames — with worst-case acquisition latency of 143.5 ns against the 400 ns budget.

WaveformJammedFrames CRC-validLatency (ns)
rf_waveform.matNo6 / 6137.6
tx_20260730_150936.matNo6 / 6139.6
tx_20260730_151052.matNo6 / 6141.6
tx_20260808_110530.matYes6 / 6137.6
tx_20260808_110557.matYes6 / 6143.5
tx_20260808_110631.matYes6 / 6137.6
tx_20260808_110941.matYes6 / 6139.6
tx_20260808_111034.matYes6 / 6139.6
tx_20260808_111055.matYes6 / 6141.6
tx_20260808_111119.matYes6 / 6143.5
tx_20260808_111143.matYes6 / 6137.6
Figure 12 — End-to-end propagation budget — LNA input to first demodulated bit, well inside the 400 ns budget.
Figure 12End-to-end propagation budget — LNA input to first demodulated bit, well inside the 400 ns budget.

ModelSim verification — live session

The generated Verilog was simulated live in ModelSim on one barrage-jammed dwell. The self-checking testbench streams the I/Q samples and compares every DUT output against the MATLAB reference sample-by-sample — zero mismatches, with the payload resolving to "RADOME24".

Figure 13 — Live ModelSim session — frameValid and crcOK assert high; payloadOut bytes resolve to "RADOME24". Run completed to $stop at 20530 ns.
Figure 13Live ModelSim session — frameValid and crcOK assert high; payloadOut bytes resolve to "RADOME24". Run completed to $stop at 20530 ns.

Read the full write-up

The complete technical report and the source code cover the specification, front end, digital down-converter, decode kernel, fixed-point core, HDL, and the live ModelSim verification session.