Tuesday, September 29, 2015

FPGAs and VHDL on a budget

The Beagle Bone Black (BBB) and its PRU go a long way to building non-trivial projects (e.g. all of the boards in gallery1 and gallery2 including a  Level controlled RF synthesizer10MSPS ADC, and multistage SDRs.)  Having a simple, flexible, low-cost FPGA available started to become very appealing.  In looking around at various FPGA boards the XuLA2 Spartan6 LX9 caught my attention for several reasons. First the pin out is extremely simple (40 pin DIN at 900x100 mil spacing), second it has enough IO pins to be usable with ADCs, DACs, and an SPI but not so many as to be cumbersome, third it includes an SDRAM which could come in handy, and finally the cost is low enough that I could afford to purchase multiples and not worry about loosing one due to mistakes on the bench.
The near term goal was to interface the FPGA to an ADC and a BBB and the longer term goal being to eventually incorporate an NCO, digital mixer and filters.  I am also not a VHDL expert so things needed to progress incrementally.  Given this, I created a simple board as a carrier for the XuLA2 that included an SPI interface, LEDs and an ADC.  The schematic of that board is below.
XuLA2 and ADC carrier board schematic.
The idea is that there is enough on the board to develop and test an SPI interface and then populate the rest of the board with a 12 bit ADC.  The ADC and sample clock oscillator are pin compatible from 10MSPS up to 66MSPS (depending on how much you want to spend and can use).  Below is a picture of the first unit partially populated with only LEDs, SPI interface, and XuLA2. It is connected to a BBB via an SPI interface using the GPIOs through an Beagle Bone Black interface board.
Beagle Bone Black with interface cape at left.  XuLA2 w/ Spartan 6 LX9 on ADC carrier on right.

The first FPGA image developed included an SPI interface with an internal control register and a couple of counters (block diagram below).
Block diagram of VHDL for LX9 digital interface.

The SPI block serializes data into SI and out from SO.  The port controller is a finite state machine that uses the SI as a 16 bit command. The low 4 bits specify whether the transaction is a read or write and which port to read and write from while the upper 12 bits serve as the data.  Reads and writes with port 0 always go to register 0 (R0).  This is the primary control register which includes settings for the LEDS, ADC sampling enable and selecting what hardware is multiplexed to port 1.  Reads and writes with port 1 can be to a secondary set of control registers (R1 and R2), a set of counters, or a FIFO which crosses the system clock and ADC sample clock domains.  The overall programming model then becomes writing a command (and reading the results from the previous command since the serial data is clocked out concurrent with clocking in the write data).  For streaming operations, the port 1 selector is first configured to connect to the FIFO and then a stream of read-port-1 commands are issued.

This approach worked well.  It has enough complexity to serve as a non-trivial, applied learning exercise yet is simple enough to be tractable to debug without lots of test equipment and tools.  The SPI programming can be easily driven by and changed in the BBB user space C code. This means you can slow down transactions to seconds and verify things on the target hardware with the LEDs. The counters allow pattern verification of reads at all speeds and check the integrity of the interface.

Prj141 Schematic
Prj141 Overview
Prj141 Digital Down Converter
Prj141 Digital Interface
Prj141 Software
Prj141 Filter Design
Prj141 Filter Evaluation
Prj141 LX9 Utilization
Prj141 Higher Sampling Rates

No comments:

Post a Comment