R-2R Ladder Network (4-bit)
Each bit switch connects its 2R resistor to either Vref (bit=1) or GND (bit=0). The MSB (D3) contributes Vref/2, D2 contributes Vref/4, and so on — a binary-weighted sum using only two resistor values.
DAC Output Voltage & Resolution
DAC Types Compared
| Type | Resolution | Accuracy | Speed | Key Property | Used In |
|---|---|---|---|---|---|
| R-2R Ladder | 4–16 bit | Good | Moderate | Only 2 resistor values (R, 2R) — easy to match on-chip | Audio, general-purpose, FPGA GPIO networks |
| Weighted Resistor | 4–8 bit | Poor at high N | Fast | R, 2R, 4R, 8R… range grows as 2N−1, hard to match | Low-cost 4-bit, educational circuits |
| Current Steering | 12–16 bit | Excellent | Very fast (GHz) | Thermometer-coded current sources; fast switching, low glitch | RF/comms, arbitrary waveform generators |
| Sigma-Delta (ΣΔ) | 16–24 bit | Excellent | Low–medium | PWM-like 1-bit output + low-pass filter; oversampling reduces noise | Audio playback, medical imaging |
| PWM DAC | 8–16 bit (effective) | Moderate | Limited by fpwm | RC filter averages PWM duty cycle — no true DAC IC needed | MCU volume control, motor set-point, cheap sensors |
DAC Specs Explained
| Spec | Symbol | What It Means | Typical Value |
|---|---|---|---|
| Resolution | N bits | Number of distinct output levels (2N) | 8–24 bits |
| Settling Time | tsettle | Time to settle to ±½ LSB after code change | 1ns – 10µs |
| DNL | LSB | Deviation of each step from ideal 1 LSB; DNL > −1 = no missing codes | <±0.5 LSB |
| INL | LSB | Max deviation of output from ideal straight line | <±1 LSB |
| Glitch Energy | nV·s | Spike area at major carry transitions (0111→1000) | 1–200 nV·s |
| THD | dB | Total Harmonic Distortion for sinusoidal output | <−80dB (audio) |
| Monotonicity | — | Output always increases with code; requires DNL > −1 LSB | Guaranteed for good DAC |
| Output Impedance | Ω | Thevenin output resistance; must be buffered for loads | Varies; buffer adds ~0Ω |
8-bit DAC — Toggle Bits to Set Output
DAC Models in Verilog
Behavioral DAC (Simulation)
// Behavioral DAC — simulation only (uses real type)
module dac_model #(
parameter N = 12,
parameter real VREF = 3.3
)(
input wire [N-1:0] din, // digital input code
output real vout // analog output (simulation)
);
// Vout = (D / 2^N) * Vref
assign vout = ($itor(din) / $itor(1 << N)) * VREF;
endmodule
R-2R DAC on FPGA (GPIO Pin Network)
// R-2R DAC: FPGA drives N output pins into external resistor network
// No special IP — just N GPIO pins + external R/2R resistors
module r2r_dac_driver #(
parameter N = 8
)(
input wire clk,
input wire rst_n,
input wire [N-1:0] code, // digital value to output
output reg [N-1:0] dac_pins // connect MSB→D7 through external R-2R network
);
// Register the code to align with external network settling time
always @(posedge clk or negedge rst_n) begin
if (!rst_n) dac_pins <= '0;
else dac_pins <= code;
end
endmodule
// Usage note:
// dac_pins[7] (MSB) → 2R shunt to Vout, then R series to dac_pins[6] node
// dac_pins[0] (LSB) → 2R shunt, terminated with 2R to GND
// Vout taken before op-amp buffer for high impedance loads
PWM DAC with RC Filter
// PWM-based DAC: digital code → PWM duty → RC filter → analog Vout
// Effective resolution limited by PWM frequency vs ripple tradeoff
module pwm_dac #(
parameter N = 8 // 8-bit → 256 duty levels
)(
input wire clk,
input wire rst_n,
input wire [N-1:0] code, // 0=0V, 255=Vref (8-bit)
output wire pwm_out // connect to external RC low-pass filter
);
reg [N-1:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) cnt <= '0;
else cnt <= cnt + 1;
end
assign pwm_out = (cnt < code);
// External: pwm_out → 10kΩ → Vout → 100nF → GND
// f_pwm = f_clk/256; filter cutoff ≈ f_pwm/10 for <1% ripple
endmodule
SPI-Controlled DAC Interface
// SPI interface to drive external DAC (e.g. MCP4921 12-bit SPI DAC)
// Sends 16-bit frame: [4 config bits][12 data bits]
module spi_dac_ctrl (
input wire clk,
input wire rst_n,
input wire [11:0] dac_code, // 12-bit DAC value
input wire send, // pulse to trigger SPI transfer
output reg sck, // SPI clock
output reg mosi, // SPI data
output reg cs_n, // Chip select (active low)
output reg done // Transfer complete
);
reg [15:0] shift_reg;
reg [4:0] bit_cnt;
reg busy;
// MCP4921 frame: 0011 + 12-bit code (BUF=0, GA=1, SHDN=1)
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cs_n <= 1; sck <= 0; mosi <= 0; done <= 0; busy <= 0;
end else if (send && !busy) begin
shift_reg <= {4'b0011, dac_code}; // load frame
bit_cnt <= 15;
cs_n <= 0; // assert CS
busy <= 1;
done <= 0;
end else if (busy) begin
sck <= ~sck; // toggle clock
if (!sck) begin // output on falling edge
mosi <= shift_reg[15];
shift_reg <= shift_reg << 1;
if (bit_cnt == 0) begin
cs_n <= 1; busy <= 0; done <= 1;
end else bit_cnt <= bit_cnt - 1;
end
end else done <= 0;
end
endmodule
Frequently Asked Questions
What is a DAC and how does it work?
A DAC converts an N-bit digital code D into a proportional analog voltage: Vout = (D / 2N) × Vref. Code 0 → 0V, code 2N−1 → Vref × (1 − 2−N). An 8-bit DAC at 3.3V has 256 levels, each 12.9mV apart.
How does an R-2R ladder DAC work?
The R-2R ladder uses only two resistor values. Each bit switch connects a 2R shunt to either Vref (bit=1) or GND (bit=0). By Thevenin analysis, the MSB contributes Vref/2, next bit Vref/4, etc. Only R and 2R values needed regardless of N — easy to match on-chip.
Why not use weighted resistors for a DAC?
Weighted resistors (R, 2R, 4R, 8R…) work for 4 bits but the resistor range spans 2N−1×. For 12 bits: 2048:1 ratio — impossible to match accurately. R-2R limits the range to 2:1, making it practical for 16+ bit resolution on a chip.
What is glitch energy and why does it matter?
Glitch energy is the area of the voltage spike at the output during code transitions, worst at the half-scale crossing (0111→1000). Caused by switches not changing simultaneously. Measured in nV·s. Matters in audio (audible clicks) and RF (spectral spurs). Low-glitch DACs use thermometer coding or deglitching S&H circuits.
What is monotonicity in a DAC?
A monotonic DAC always increases its output when the code increases. Non-monotonicity (DNL < −1 LSB) causes the output to dip for a rising code — catastrophic in closed-loop control systems. Guaranteed monotonicity requires DNL > −1 LSB across all codes and all temperatures.
Can you build a DAC with just an FPGA and resistors?
Yes — drive N GPIO pins into an external R-2R resistor network. The FPGA sets the bit pattern, the resistors sum it into an analog voltage. This is popular for audio projects and cheap test setups. Accuracy is limited by resistor matching (0.1% resistors give ~10-bit effective accuracy). Add an op-amp buffer if driving a low-impedance load.
What is a PWM DAC?
A PWM DAC uses a PWM output filtered by an RC low-pass filter. The RC averages the duty cycle into an analog voltage: Vout = D% × Vcc. 8-bit PWM at 50kHz + RC filter (cutoff ~1kHz) gives ~8-bit resolution at audio rates. No true DAC IC needed — common in microcontrollers for volume control and motor set-points.