Spartan-6 Microboard: 16-bit R-2R DAC! [Part One]

So how do you produce a usable, somewhat analog signal out of a purely digital device? Well it’s actually simple; use a R-2R ladder and a bunch of digital pins. Basically we’re turning a dearth of extremely high speed digital IO pins into one high-resolution analog output. Oh, also necessary for this circuit (go ahead and crack out the protoboard and soldering iron) is 3 matched resistor per bit of resolution; so in our case, 48.

A 16-bit R-2R Ladder Schematic

A 16-bit R-2R Ladder Schematic

Fun! Here’s a diagram. So how’s it work? When we drive our 16 outputs with digital logic, each pin has half the voltage range of its leftwards neighbor — due to it being a stacked  voltage divider. This is exactly how you  convert from binary to decimal; each digit has twice the value of one neighbor, and half that of the other (discounting the Most and Least Significant Bits) so we can  convert 1s and 0s into a wide numeric  range of values.

This is probably confusing: I know how it works, and I just confused myself. For a *much* better explanation, refer to this previous post of mine.

We’ve got a  circuit, we know conceptually how it works, how do we make it do? Make…make it do right? This is where my brain started screeching to a halt. Hell, I must be driving with the E-brake on, because this is actually super easy, and explaining why helps to understand VHDL/Verilog.

Firstly, in programming languages, things happen sequentially: A, then B, then conditionally C, for example. In Hardware Description Languages, things happen simultaneously: A <= a and B <= b and C <= c all happen simultaneously. Secondly, all of our analog values we’d want to output, such as 62101 is actually represented in a variable, described thusly:

wire [15:0] our_var

It’s actual designation in the chip is in the form 0b1111001010010101.
This means all we have to do to convert our digital data to our analog output at full clock speed is this:

always @(*) begin
pin15 <= our_var[15]
pin14 <= our_var[14]
pin1 <= our_var[1]
pin0 <= our_var[0]

These all update at the same time, and our output is produced thusly. So, I’ve been dismissing the most major disadvantage? Speed. Lets say we want to make a 16b sine wave. Our speed is limited to f_clk/number_of_levels. So FM is out of the question with this particular implementation (I’m not ruling it out completely, let me know if you know more than I do) but it’s the perfect speed for audio applications.

With a 350MHz DCM, and using 16,384 distinct levels, I can generate a f_max of around 21kHz, well above the range of human hearing. So let me work on getting that code finished, and I’ll return tomorrow. I’ve got my wheels pointed towards the curb, and my E-brake on, and I need a break for the night.

Spartan-6 Microboard: Firing It Up!

S6 Microboard powered via USB Mintyboost

S6Microboard powered via USB Mintyboost

I promised this article 4 days ago. I apologize. I’ve made it worth it.

Getting this project running was a bit of a beast. Not the development or implementation, those are based on public code, previously tested on this device. No, the trouble was in figuring out exactly how to program/load this board, driver issues, and how to code for this board. That is all now figured out.

I started by finding this set of articles by this Duane Benson fellow (they are topically listed at the bottom). He gives good, fairlyunderstandable instruction, but some aspects are just plain incorrect. In one article, he explains how you must use exclusively the micro-USB for programming, when in reality, you must use the full size USB port.

You will need the CP210x driver, but don’t bother trying to get it from Avnet’s malignant tumor of a website. Download it directly from Silicon Labs. (by the way, the CP210x series chips are extremely interesting, they have a USB-to-I2S adapter I’d like to experiment with…) Once you have the drivers squared away, plug it in, we’re cookin’ with gas now!

Okay, so how do you actually get information into the board: enter Matthew Galloway, or his site at least. This is what you need, and pretty much everything you need to get this thing blinking: his Blinkenlights tutorial. You’ll also want to download a copy (me not trusting the site) of the S6Microboard Manual which gives the names of the physical locations on the board.

Got blinkenlights? Good. Now were ready for the next project: tomorrow.

I promise.

Discovering FPGAs Series by Duane Benson:

*This is not yet a complete listing of this series, and this series is continuing

What’s This All About?
Opening the Package
Sorting Out the Pins
Flashing the LEDs
More About the UCF
Adding LEDs & Modifying the Verilog
Bringing Up the IDE
Creating the .BIT File
Loading the .BIT File
Playing With LEDs & Switches
Adding in the Switches
Driving a 7-Segment Display
The ChipScope Virtual Logic Analyzer
Alternative Latching Strategies
Getting to Grips With ChipScope
Observing Switch Bounce With ChipScope
Modules in Modules
Creating a Logic Analyzer
Selecting a Syntax
Building a Two-Stage Synchronizer
My Logic Analyzer Takes Shape
Debugging a Motor Driver
Becoming a Clock Wizard
I See Clocks Everywhere!

MQ3 (or MQ303a) Alcohol Sensor Arduino Guide

This little device is wonderful, for parties at least. Accuracy wise, it’s not much more than a toy (without some opamps for signal amplification and filtering) but I digress. Just plugged right straight into an Arduino will be plenty of fun, assuming you read the datasheet.

To wire this properly, check out this diagram, which will get further explanation after the break.
Continue reading

Create a free website or blog at

%d bloggers like this: