Audio Bare-bones FPGA
This project continues the treatment of the DIY approach to soundcards - as an example of an overall approach to PC-based digital audio hardware development - started with ExtendingISASoundcard, and continued in AudioArduino. This is a project that demonstrates the use of a DIY bare-bones board for the
XC3S50A FPGA (field-programmable gate array) chip (the smallest from the Xilinx Spartan-3A family), interfaced to a PC through a DIY FTDI
FT245-based board - as a 44.1 kHz, 8-bit, mono, full-duplex soundcard; by implementing corresponding, open-source:
- audio card driver for the Advanced Linux Sound Architecture (ALSA) - the same driver as for AudioArduino
- matching HDL code - which defines the audio reproduction engine on the FPGA, synthesizable in the proprietary
xsttool, part of the freeware Xilinx ISE WebPACK suite.
The above arrangement will cause the operating system to generate audio output as a 97.6 kHz pulse-width modulated (PWM) signal on FPGA chip's P93 pin as a mono audio output; and the streaming audio output data to be digitally copied and fed back to the PC as a mono audio input. In this manner, high-level audio software such as Audacity can be used to directly interface with the bare-bones
XC3S50A FPGA +
FT245 USB boards' assembly.
Nothing more than a ~10μF electrolytic capacitor on the output is required, in order to attach a small loudspeaker (such as one from heaphones) for the ability to hear sound played on the PC audio software; however, since the FPGA can only output up to 3.3V, headphones will play sound back with modest volume at best.
- AudioMostly AM2011 - 6th Conference on Interaction with Sound (full paper, 8pg) version - available for download courtesy of ACM:
Find link to schematics and PCB layout below.
There are separate Kicad projects for the
XC3S50A FPGA bare-bones board, and for the
FT245 USB interface board:
XC3S50AFPGA bare-bones board:
The connection between the
XC3S50A FPGA bare-bones board and the
FT245 USB board is implemented as shown on the diagram below: (note that
VCC of the USB board should also be connected to
+3.3V_AUX nets of the FPGA board, which is not shown on the diagram below)
FPGA development boards typically include plenty of additional hardware; and typically have the schematics available. As the typical expectation in the community is that: if you need a minimal FPGA board schematic, you can derive it from existing ones - the bare-bones FPGA here is, essentially, an extraction of a minimal configuration from s3astarter and fes2. The shown version of the board uses a 50 MHz crystal oscillator as a clock. The USB board is essentially an implementation of the "Self-powered configuration" from the FT245R Datasheet. These projects make use of Kicad part definitions found in library.oshec.org, per.launay.free.fr, opendous and micropendous projects.
Instructions for obtaining the source for, and building the
AudioArduino ALSA soundcard driver for Linux PCs can be found on the AudioArduino page.
Otherwise, the AudioFPGA related source code can be browsed here, or checked out from svn (see below).
It consists of several HDL (hardware description language) projects; each of which may contain a mix of both VHDL and Verilog language files:
svn co https://sdaaubckp.svn.sourceforge.net/svnroot/sdaaubckp/audfpga-bb/src-hdl/XS3A-FT245-an8m-B
svn co https://sdaaubckp.svn.sourceforge.net/svnroot/sdaaubckp/audfpga-bb/src-hdl/XS3A-FT245-duplex-B
svn co https://sdaaubckp.svn.sourceforge.net/svnroot/sdaaubckp/audfpga-bb/src-hdl/XS3A-FT245-an8m
svn co https://sdaaubckp.svn.sourceforge.net/svnroot/sdaaubckp/audfpga-bb/src-hdl/XS3A-FT245-duplex
- "-an8m" refers to a core (engine) capable of both PWM analog playback and duplex loopback;
- while "-duplex" refers to a core capable of digital duplex loopback only.
Almost all of these projects make use of Versatile FIFO :: OpenCores Verilog core.
Building and running
The boards - both bare-bones FPGA and USB - have been implemented on a UV-photosensitive double-sided PCBs. The board designs follows a 'surface-mounted' philosophy: that is, where possible, both standard through-hole and SMD elements are soldered on surface, and vias and holes are avoided; where that cannot be avoided, terminals of through-hole elements are reused as vias; otherwise dedicated holes are drilled, and unbraided wire soldered, to act as via and connect the PCB layers. The TQ144 Thin Quad Flat Pack IC package of the
XC3S50A FPGA chip is, possibly, the smallest that can still be reliably soldered "by hand" (using a soldering iron) by a non-professional; however, it also commands significantly thin PCB traces - therefore, use of a 1200 dpi laser printer for PCB transparent film photomask is recommended.
The via holes have been drilled with a 0.5 mm drill, and filled with 0.4 mm hard wire; the rest of the through-hole element holes have been drilled with 0.8 mm drill (and 1 mm, where required). The FPGA board needs an external power supply, and can be powered with a stabilized 9V DC power supply; and it delivers (through its
+3.3V_AUX net) power for the USB board as well. The USB board provides pads for both "Type B" and "Mini-B (5-pin)" USB receptacles (here only the mini-B was used).
The HDL source projects are synthesized and implemented in the proprietary ISE WebPack software, which results with a
.bit file, which is used to program the FPGA. Note that:
- The older versions of the projects ("-duplex", "-an8m") have been developed in ISE WebPack 9.2 under Ubuntu 9.04;
- The rewritten versions of the projects ("-duplex-B", "-an8m-B") have been developed in ISE WebPack 13.2 under OpenSuse 11.2.
Since Xilinx only supports Red Hat Enterprise Linux, neither Ubuntu nor OpenSuse are supported, and may require hacks to get running as described.
iMPACT from the ISE WebPack suite is then used to transfer the .bit file to the FPGA through a programming cable. As a programming cable, Amontec JTAGkey-Tiny was used here; it connects to the FPGA board through its JTAG connector (parallel wire can be soldered to implement this connection). While the JTAGkey-Tiny is actually connected to a PC using a USB cable - using the open-source libusb-driver.so driver it is recognized as a "parallel port" cable by iMPACT; still, the programming (but not the verification) of the FPGA can proceed with success. Here iMPACT as part of ISE WebPack version 9.2, with libusb-driver.so under Ubuntu 9.04, has been used to program the FPGA in all cases (regardless of which version was used to generate the .bit file). Proper operation of this FPGA programming chain can be verified without the use of the USB board, by implementing simple HDL "blinking LED" programs for the FPGA.
Note that the Spartan 3A generation of Xilinx FPGA chips (along with the
XC3S50A used here) does not retain it's programming after power is turned off (i.e. they are volatile); therefore, upon each power up, the FPGA needs to be programmed anew (most of the videos show this part of the process). However, the Spartan-3AN family chips do retain their programs after power down, given that the contain built-in Flash memory - making them non-volatile technology; thus, one may prefer to use the pin-compatible
XC3S50AN with this bare-bones board instead.
Once the FPGA board is powered (and by extension, the USB board as well), and programmed with a given HDL core - it can be connected via USB to a Linux PC (here Ubuntu 10.04) which has the AudioArduino soundcard kernel driver preloaded; the FPGA+USB boards will be recognized as a soundcard, and high-level audio software like Audacity can be used to play back and record data from the device (note that only the "-an8m" versions provide analog PWM playback). [see AudioArduino for obtaining source code and building instructions for the driver]
While the main discussion is in the paper, a few additional notes are included below.
HDL approach and workflow
We can perceive a microcontroller to be a prefabricated collection of connected digital logic electronic circuits on a chip, which implements a Turing machine (a computer); a program for a microcontroller in a high-level language essentially gets compiled to a sequential list of commands (assembly/machine code instructions). In contrast, an FPGA represents a prefabricated collection of unconnected digital logic; a "program" for an FPGA in a HDL (hardware description language) essentially results with the definition of the connections between the unconnected logic - and thus, the implementation of a given digital logic hardware. In example, an FPGA can be "programmed" to implement an Atmel microcontroller hardware, which would then make the FPGA chip capable of executing programs (as lists of machine code instructions) for that microcontroller architecture.
This, essentially, means that both the engine implemented by discrete 74xx logic in ExtendingISASoundcard; and the Arduino's Atmel microcontroller engine in AudioArduino - can, in principle, be implemented on an FPGA chip. In this project, however, only the minimal configuration that can perform as a soundcard is pursued.
In computers/microcontrollers, high-level language code goes through a process of compilation and linking steps, which generates the final, executable file as list of machine instructions. Similarly, in FPGAs, high-level HDL code goes through a process of several steps, which generates the final .bit file as a specification of digital logic connections. These steps are usually specific to the manufacturer, and for the Xilinx design flow in the ISE WebPack tool, these steps are: Synthesis and Implementation (Translate, Map, and Place & Route); Generate Programming File (the .bit file) is the final step before actual programming of the chip. In between these steps, simulation (which renders logic signal waveforms in the time domain) can be performed as a way to verify that the HDL engine performs as intended, before 'burning' it on the chip. Behavioral simulation can be performed even before synthesis.
In AudioArduino, a fully open-source development toolchain can be used to implement and test the open-source deliverables (microcontroller code and PC driver). That is not the case with FPGAs - since the implementation of FPGAs is highly manufacturer specific, all major FPGA manufacturers typically keep their development software tools proprietary. Furthermore, even the freeware versions require registration with a full name, email verification for a license file, and may be subject to export regulations - beyond the built-in limitations expected of freeware. ISE WebPack requires freeware licenses to renewed each year; and allows only work on low to medium density devices; furthermore, each time a .bit file is generated, ISE WebPack will "ring home" with usage statistics (which are, however, fairly easy to read).
That being said, manufacturers do put an effort to provide Linux versions of their tools - albeit with support only for commercial versions like Red Hat Enterprise. That, however, does not make running under other Linux environments impossible (although, note that while in this project, ISE 9.2 was used under Ubuntu 9.04, ISE 13.2 couldn't be made to work (in entirety) on Ubuntu 11.04 - only on OpenSuse 11.2). In addition, Xilinx have also accepted the use of the open-source libusb-driver as an alternative on Linux.
Currently, there exist certain open source packages, that can assist in HDL development: GHDL can be used for behavioral simulation of VHDL code, and GTKWave can be used to observe the simulation results as signal waveforms - this is, however, no guarantee that the code will synthesize and actually run as intended, under a given manufacturer's technology. In all, given the tight coupling between the technology and the manufacturer, a fully open-source development toolchain for FPGA (akin to that in AudioArduino for Atmel microcontrollers) cannot be expected to occur anytime soon. However, high-level HDL source code can meaningfully be shared as open-source hardware design, an approach already taken by establishments like OpenCores.org - and applied in this project as well (even if the design on that level, cannot be expected to be fully portable between different manufacturer technologies).
Notes about versions/videos
In essence, the "-an8m" versions of the HDL code, implement a minimal soundcard engine in the FPGA, which consists of:
- An engine for handling the interaction process with the FT245 bidirectional bus,
- RAM memory to implement an input array (a circular/ring buffer) + registers/counters to implement pointers
- Counters to generate the audio (CD, 44.1 kHz) and PWM (97.6 kHz) rate pulses, as well as 'output compare' unit to generate the PWM output
- (LED drivers to extend the very short FTDI pulses and have them visible on LEDs)
The "-duplex" versions of the code are intended to provide "digital duplex loopback" only: an incoming byte from the PC is stored in memory; then read back from memory and sent back again to the PC. As such, they do not implement the CD and PWM counters, and cannot reproduce analog sound - and can be used only for testing the process of interaction with FT245's bidirectional bus (as in AudioArduino#Analysis_Tools - by using either Audacity itself, or other tools like the command line writeread_bonus.c). Otherwise, the same perspective on analog-to-digital and digital-to-analog interfacing is applicable as in AudioArduino (and AudioArduino-AnalogBoard).
At this point, it should be noted that here, there may be several limitations imposed on the timing. Assuming that we talk about interleaved read/write (where each byte read from the PC is written back by the FPGA while the read process is idle), these limitations are:
- The minimal timing of the FT245 device, noted in the datasheet - the minimal read/write period would then be T1+T7+T12 = 50+50+80 = 180 ns (corresponding to 1/180e-9 = 5.55 MHz).
- The limitation of communication speed to 2 Mbps by the AudioArduino FTDI Linux driver (corresponding to 200 kHz)
- Limitation of data transfer rate to 44.1 kHz by ALSA, as requested by audio programs.
Note that since (in this case) one sample is equivalent to one byte (8 bits) - the "Hz" above can be taken to be equivalent to "Byte/s". The FT245 minimal timings do not impose a maximum limit, and the device can be driven slower (with longer periods) than that. Not achieving the 2 Mbps limitation may likely result with PC software or kernel driver crashes/segfaults; while not achieving the 44.1 kHz rate will result with drops in reproduced and/or captured audio.
The reason for the difference between newer (-B) and older versions, is the existence of a bug in the older version - which caused distorted analog playback (as evident in the MVI_4453_audiofpga_firstsound.ogv video). The older versions were using two separate HDL components, "bus" and "process", to implement interaction with the FT245 bidirectional bus (which were mostly based on ixo.de USB JTAG pod and FT245R [MyHDL]). Assuming that this was the cause of the reproduction bug, the entire FT245 interaction process was rewritten so it is defined solely in the top level module (without using of distinct components), and with additional delays for the read/write operations - and this represents the newer, "-B" version. Additionally, a small logic analyzer with software running under Linux, Saleae Logic, was used to observe the communication between the FPGA and the USB boards; while it cannot capture the signals precisely (given it captures at 24 MHz, while the FPGA clock is at 50 MHz) - it still provided valuable insight in the operation of the device.
In the end, it turned out the cause of the bug is a hardware one - the D4 line of the parallel cable connecting the FPGA and the USB boards had been cut; after a fix, both the old (-an8m) and the new (-an8m-B) versions show themselves capable of clean audio reproduction - the -an8m-B is the one demonstrated in MVI_5421-6_audiofpga_fix_video.ogv. A particular difficulty in the debugging of the problem is the fact that -duplex-B tended to consistently pass the digital duplex test (meaning that the data sent to the board, came back uncorrupted to the PC), even with a cut cable (which implies that this cut didn't completely sever the connection).
Furthermore, the -B versions implement certain recommendations (for more, see VHDL/FPGA/Xilinx related links during Oct/Nov 2011 in Computing), such as:
- Avoiding the use of two-process state machines
- Use of a state machine to perform single sampling of the bidirectional bus
- Use of a
.filterfile to suppress the massive ammount of warning messages from ISE, which may appear even if the outcome is the intended by the designer (this is a feature not available in ISE 9.2)
Also, note that in order for the old versions to synthesize in ISE 9.2, the individual modules need to be "partitioned" in the ISE project:
... in order to complete the build process; however, newer versions of ISE (like 13.2) dispensed with this concept altogether (and approaches like relative location constraints in the *.ucf file are recommended instead; which have not been utilized here). Also, ISE 9.2 used a binary
.ise project file, which is not included with the source files; ISE 13.2 uses a human-readable, XML-formatted text
.xise project file, which has been included with respective source files.
Finally, a brief overview of the main videos follows:
- MVI_5421-6_audiofpga_fix_video.ogv - test and demo of the XS3A-FT245-an8m-B core, after the cable fix (clean reproduction), 2011-11-16.
- MVI_4453_audiofpga_firstsound.ogv - test and demo of the XS3A-FT245-an8m (r 197) core (audio and digital duplex loopback test, using the AudioArduino ALSA driver: first playback (starts 02:43), and then (digital) duplex test; finally, a playback on the PC soundcard of original and capture for comparison. (Note this version displays the audio reproduction bug), 2011-03-31)
- HDL and MVI_4440_audiofpga_duplex_loopback_dataud.ogv - test and demo of the XS3A-FT245-duplex core (digital duplex loopback test, using the AudioArduino ALSA driver: first data only @ 2 Mbps data rate [not completely succesful, as it locks at end]; then mono 44.1 kHz / 8 bit audio through Audacity [with only few drops at beginning of capture], 2011-03-20)