Sending data from a computer to an FPGA is often required. This might be FPGA configuration data, register settings, or streaming data. An easy solution is to use a USB-connected microcontroller instead of a dedicated interface chip, which allows you to offload certain tasks into the microcontroller.
Often your FPGA-based project will require computer communication and some housekeeping tasks. A popular solution is the use of a dedicated USB interface chip, and a soft-core processor in the FPGA for housekeeping tasks.
For an open-source hardware project I recently launched, I decided to use an external USB microcontroller instead of a dedicated interface chip. I suspect you’ll find a lot of useful design tidbits you can use for yourself—and, because it’s open source, getting details of my designs doesn’t involve industrial espionage!
The design is called the ChipWhisperer-Lite (see Photo 1). This device is a training aid for learning about side-channel power analysis of cryptographic implementations. Side-channel power analysis uses measurements of small power variations during execution of the cryptographic algorithms to break the implementation of the algorithm.
Photo 1: This shows the ChipWhisperer-Lite, which contains a Xilinx Spartan 6 LX9 FPGA and Atmel SAM3U2C microcontroller. The remaining circuitry involves the power supplies, ADC, analog processing, and a development device which the user programs with some cryptographic algorithm they are analyzing.
In a previous article, “Build a SoC Over Lunch” (Circuit Cellar 289, 2014), I made the case for using a soft-core processing in an FPGA. In this article I’ll play the devil’s advocate by arguing that using an external microcontroller is a better choice. Of course the truth lies somewhere in between: in this example, the requirement of having a high-speed USB interface makes an external microcontroller more cost-effective, but this won’t always be the case.
This article assumes you require computer communication as part of your design. There are many options for this. The easiest from a hardware perspective is to use a USB-Serial converter, and many projects use such a system. The downside is a fairly slow interface, and the requirement of designing a serial protocol.
A more advanced option is to use a USB adapter with a parallel interface, such as the FTDI FT2232H. These can achieve very high-speed data rates—basically up to the limit of the USB 2.0 interface. The downside of these options is that it still requires some protocol implemented on your FPGA for many applications, and it has limited extra features (such as if you need housekeeping tasks).
The solution I came to is the use of a USB microcontroller. They are widely available from most vendors with USB 2.0 high-speed (full 480 Mbps data rate) interfaces, and allow you to perform not only the USB interface, but the various housekeeping tasks that your system will require. The USB microcontroller will also likely be around the same price (or possibly cheaper) than the equivalent specialized interface chip.
When selecting a microcontroller, I recommend finding one with an external memory bus interface. This external memory bus is normally designed to allow you to map devices such as SRAM or DRAM into the memory space of the microcontroller. In our case we’ll actually be mapping FPGA registers into the microcontroller memory space, which means we don’t need any protocol for communication with the FPGA.
Figure 1: This figure shows the basic connections used for memory-mapping the FPGA into the microcontroller memory space. Depending on your requirements, you can add some additional custom lines, such as a flag to indicate different FPGA register banks to use, as only a 9-bit address bus is used in this example.
I selected an Atmel SAM3U2C microcontroller, which has a USB 2.0 high-speed interface. This microcontroller is low-cost and available in TQFP package, which is convenient if you plan on hand assembling prototype boards. The connections between the FPGA and microcontroller are shown in Figure 1.
On the FPGA, it is easy to map this data bus into registers. This means that to configure some feature in the FPGA, you can just directly write into a register. Or if you are transferring data, you can read from or write to a block-RAM (BRAM) implemented in the FPGA.