Capturing Data From a Wearable Microphone Array


Constructing a microphone array is a challenge of its own, but how do we actually process the microphone array data to do things like filtering and beamforming? One solution is to store the data on off-chip memory for later processing. This solution is great for experimenting with different microphone arrays since we can process the data offline and see what filter combinations work best from the data that we collected. This solution also avoids having to make changes to the hardware design any time we want to change filter coefficients or what algorithm is being implemented.

Overview of a basic microphone array system

Here’s a quick refresher of the DE1-SoC, the development board we use to process the microphone array.

The main components in this project that we utilize are the GPIO pins, off-chip DDR3 memory, the HPS, and the Ethernet port. The microphone array connects to the GPIO port of the FPGA. The digital I2S data is interpreted on the FPGA by deserializing the data into samples. The 1-GB off-chip memory is where the samples will be stored for later processing. The HPS that is running linux will be able to grab the data from memory and store it on the SD card. Connecting the Ethernet port on a computer gives us the ability to grab the data from the FPGA seamlessly using shell and python scripts.

Currently the system is setup to stream the samples from the microphone array to the output of the audio codec. The microphones on the left side are summed up and output to the left channel, and the microphones on the right side are summed up and output to the right channel. The microphones are not processed before being sent to the CODEC. Here is a block diagram of what the system looks like before we add a DMA interface to the system.

Continue reading

Tutorial 1: Simple Accumulator


In this first tutorial we will create a design that will be able to increment or decrement a value by pushing buttons on the FPGA and displaying the hex value on the hex display on the board. This will cover combinational logic design, sequential logic design, and how to interface some of the peripherals on the FPGA as well as loading the design on the board.

Sequential vs parallel programming languages

Solving this problem with a microprocessor that executes instructions sequentially (like an Arduino) is pretty trivial to do. The code might look something like this…

/* PSEUDO CODE (will not compile on Arduino's IDE) */
   if (button1){
      accumulator = accumulator + 1;
      while (button1) {}
   } else if (button2){
      accumulator = accumulator - 1;
      while (button2) {}

Solving this problem in a hardware description language might not be so obvious. In SystemVerilog we are describing a digital circuit that will execute code in parallel. In order to achieve the same functionality as the sequential code from above we have to create a combinational and sequential logic circuit.

What is a combinational logic circuit?

A combinational logic circuit has a defined output based on all different combinations of its inputs – it’s kind of similar to a math function. Let’s consider an example of a familiar math function: f(x) = x^2. This function always has an output for any real value that is fed to this function: f(0) = 0, f(2) = 4, f(3) = 9, f(3.14159) = 9.8690, etc. In the digital world we can also have functions like this, but our inputs and outputs either have the value of 0 or 1. These functions are called boolean functions, and they are made up logic gates like AND, OR, NOT, NAND, etc. The link below covers the functionality of these logic gates with diagrams and truth tables.

We can piece these logic gates together to create a combinational logic circuit and represent it with a function. Let’s create an XOR (exclusive or) circuit using AND, OR, and NOT gates. We will first create a truth table for XOR.

x  y | z
0  0 | 0
0  1 | 1
1  0 | 1
1  1 | 0

This function’s output is 1 when X is 0 and Y is 1 (X’Y), OR when X is 1 and Y is 0 (XY’). If they are both 1 or both 0 the output is 0. We can write this function as z = x’y + xy’. The concatenation of two variables ‘xy’ represents the AND operation, the ‘ represents the NOT operation, and the ‘+’ represents the OR operation. Our combinational circuit looks like this.

That’s pretty neat, but how do we apply this to the problem we are trying to solve?

So now we know how to create a logic circuit, but how would we make a circuit that can increment and decrement a variable? We can start to think of what our inputs to this circuit would be: two different buttons on the FPGA – where one button will be the signal to increment and the other to decrement. We also need to think about how we can create something like a variable in hardware and how we can control what values it takes on. More specifically, we need to be able to have a way where we can remember what value our accumulator had and how our inputs to this circuit can control what values it takes on. To accomplish this we have to understand how sequential logic works.

What is sequential logic?

* Fill in detailed description *

Finite state machine design

Transferring your design into functional code

Quartus Tutorial

Actual FSM Behavior in hardware