It turns out that "future" arrived faster than expected. A new gateware/ subdirectory has landed in the smiSDR repository, and it is not a proof-of-concept sketch — it is a fully-verified, Verilator-simulated, multi-vendor-portable Verilog core that does exactly what the roadmap promised. This article is a technical dive into that gateware: the in-band signaling scheme that lets control and data share a single bus, and the DUC pipeline that turns a 250 ksps–1.25 Msps baseband stream into a spectrally clean 50 Msps RF signal.
1. Why Offload Mixing to an FPGA at All?
In the original architecture, any frequency translation (shifting a baseband signal up to an RF carrier) had to happen in software on the host PC before the samples ever hit the network. That works, but it wastes the one resource that made osmo-fl2k-style transmitters attractive in the first place: cheap, high-bandwidth raw sample throughput. Streaming already-upconverted RF samples at, say, 50 Msps over Ethernet or PARLIO consumes far more bus and network bandwidth than streaming baseband I/Q at a few hundred ksps and letting the hardware do the up-conversion locally.
The gateware README frames the motivation succinctly: move the Numerically Controlled Oscillator (NCO), the mixer, and the rate conversion into the FPGA, and you get three things at once:
- Bandwidth relief on the smiBus/PARLIO link — only compact baseband I/Q needs to cross the wire.
- Hardware-native DUC for TX and DDC for RX — the same generalized core is designed to run in both directions, which is the structural prerequisite for turning this into a full transceiver rather than a transmit-only toy.
- A wider usable RF span, since the mixer is no longer limited by host CPU cycles but by DAC sample rate and FPGA clock budget.
The published block diagram is refreshingly symmetric: a host system feeds baseband I/Q across the smiBus into a "Generalized Verilog FPGA Core," which contains an I/Q interface, a shared hardware NCO, a DUC path toward an external DAC, and a DDC path from an external ADC back to the host. Only the DUC half is implemented and hardware-verified today — but the DDC entry points are already drawn into the architecture, not bolted on as an afterthought.
Target Silicon
The core was explicitly written to avoid vendor lock-in and to stay within the reach of hobbyist budgets. Three FPGA families have already been used for testing:
| Vendor | Confirmed Families | Notes |
|---|---|---|
| Intel/Altera | Cyclone IV, Cyclone 10, MAX 1000 | Classic low-cost families; MAX 1000 is a particularly compact dev board |
| Lattice | "Various mid-class boards" | Popular with fully open-source toolchains |
| Gowin | Sipeed Tang Nano / Tang Primer series | Extremely cheap ($10–$30), good OSS toolchain support |
This spread matters editorially: it means a maker isn't locked into a single, possibly discontinued board to reproduce the project — a lesson the community learned the hard way with the FL2000 chipset.
2. Sharing One Bus for Data and Control: The In-Band Signaling Protocol
Both the SMI bus on the Raspberry Pi and the PARLIO peripheral on the ESP32-P4 expose a 16-bit-wide parallel word, clocked by a continuous CLOCK line and qualified by a VALID_DATA/write-enable strobe. The DAC/ADC front-ends the project targets (referred to as "Steamlab"-class parts in the documentation) are natively 14-bit devices, which leaves exactly two spare bits per word — and the designers used them cleverly instead of adding a second control bus (I²C/SPI) that would have needed extra wiring and synchronization logic.
2.1 The 16-Bit Word Map
Bits [15:14] act as a two-bit packet-type tag that the receiver decodes on every single clock:
| Word Type | Bit 15 | Bit 14 | Bits [13:8] | Bits [7:0] |
|---|---|---|---|---|
| I-Sample | 0 | 0 | — | 14-bit I data |
| Q-Sample | 0 | 1 | — | 14-bit Q data |
| Command Init | 1 | 0 | 111111 (sync) | 8-bit ASCII command |
| Param Chunk | 1 | 0 | 6-bit counter (0, 1, …) | 8-bit parameter byte |
| Command End | 1 | 1 | ignored | ASCII 'E' |
Streaming I/Q data therefore costs nothing extra — the two tag bits ride along with every sample, and...
Read more »
thomaswust79