Maia SDR

I’m happy to announce the release of Maia SDR, an open-source FPGA-based SDR project focusing on the ADALM Pluto. The first release provides a firmware image for the Pluto with the following functionality:

  • Web-based interface that can be accessed from a smartphone, PC or other device.
  • Real-time waterfall display supporting up to 61.44 Msps (limit given by the AD936x RFIC of the Pluto).
  • IQ recording in SigMF format, at up to 61.44 Msps and with a 400 MiB maximum data size (limit given by the Pluto RAM size). Recordings can be downloaded to a smartphone or other device.

Here is a short demo.

Maia SDR is formed by the following components:

  • maia-hdl, the FPGA design, which is written in Amaranth. It has a custom FFT implementation with low resource usage.
  • maia-httpd, an async Rust application that runs on the Pluto ARM CPU.
  • maia-wasm, a Rust web application using wasm and WebGL2.

Here are some technical details about the FPGA design. The block design shows the Maia SDR IP core in blue, the ADI axi_ad9361 interface IP core, a Xilinx AXI interconnect block to control both IP cores from the PS GP0 port, and some auxiliary blocks. Compared to the default ADI firmware, the axi_ad9361 core has been configured to reduce its resource usage.

Maia SDR Vivado block design

Even though the Pluto Zynq 7010 FPGA is rather small compared to other Xilinx FPGAs, our utilization is quite reasonable, and there is plenty of space to fit more ideas.

Maia SDR Vivado utilization summary

The utilization report shows that the axi_ad9361 and the AXI interconnect comprise a relatively large part of the total. Specially the AXI interconnect uses a lot of logic for no good reason. The utilization would be reduced by replacing these with custom alternatives.

On the other hand, the Maia SDR IP has been designed with low resource utilization in mind. Its custom 4096-point pipelined FFT with Blackman-harris window uses only 2.2 kLUTs, 9.5 BRAM and 6 DSPs.

Maia SDR Vivado utilization report

Here is the device view, showing the Maia SDR IP in blue, the axi_ad9361 in yellow, and the AXI interconnect in salmon.

Maia SDR Vivado device view

This is how the clocking looks like. The AD9631 CMOS interface clock runs at the sample rate, anywhere between a couple MHz to 61.44 MHz. Most of the Maia SDR IP core runs at a fixed 62.5 MHz, so there is always less than one sample per clock cycle. There are are also clocks at 2x and 3x this frequency (125 and 187.5 MHz). They are used in some DSP48E1’s, in order to perform 2 or 3 multiplications in a single 62.5 MHz cycle. These three clocks are generated from the 100 MHz FCLK0, which is also used for the AXI4-Lite interfaces connecting to the PS. There is also a 200 MHz FCLK1 used by the axi_ad9361 for delay control, and a 25 MHz SPI clock.

Maia SDR Vivado clock summary

Flashing the Maia SDR firmware is as easy as flashing the default ADI Pluto firmware. The user interface can run on a web browser on a PC or mobile device connected to the Pluto by USB Ethernet. See the installation instructions for more details.


  1. Excellent work. I have been eyeing a Plutosdr for a long time, Maiasdr convinced me to finally press the order button.

    Would it be feasible to add support for recording to a UHS-II micro sdxc card? (Are there enough gpio and other resources in the fpga?). Being able to record tens or even hundreds of gigabytes would be interesting.

    1. No idea. There are 10 FPGA pins that are routed to a pin header. You would need some kind of expansion board to plug in there, and have enough signal integrity. Plus you’d need completely custom design for the SDXC controller to be implemented in the FPGA.

      1. Thanks. Might be a project for next lockdown 🙂
        Open source sdhc ip cores do exist, and proprietary cores for sdxc. Not sure if they would fit though.

        1. Another way to increase storage could be to implement CCSDS 121.0-B compression. But the gain would probably only be 2-5x (depending on the recorded signal).

  2. Hi Daniel,

    very well done! Do you see a chance to implement TX, too? Some interpolation needed in the FPGA, but overall far less effort than for RX…

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.