The physical world doesn't operate in 1s and 0s. Variables like temperature, mechanical strain, or chemical composition generate continuous voltage and current signals. On the other side of the divide, a Field Programmable Gate Array (FPGA) is a rigid, discrete fabric of lookup tables and flip-flops. It cannot inherently comprehend a 1.74V signal; it only recognizes strict logic HIGH or logic LOW thresholds.
The Analog-to-Digital Converter (ADC) is the essential bridge that translates continuous analog phenomena into the discrete, binary words that an FPGA's data paths can process. But crossing this bridge requires a deep understanding of both analog physics and digital architecture.
The Physics of Sampling: The Nyquist Theorem
Before a signal even reaches the ADC, you must address the fundamental laws of signal processing. Digitizing an analog signal is not just a matter of capturing data; it is a matter of capturing enough data to reconstruct reality accurately.
This is governed by the Nyquist-Shannon sampling theorem, which states that the sampling rate (f_s) must be at least twice the highest frequency component (f_max) present in the analog signal to perfectly reconstruct it:
f_s ≥ 2f_max
If you fail to respect this mathematical boundary, you introduce aliasing. If a sensor picks up high-frequency noise that exceeds the Nyquist frequency f_s/2, that noise doesn't just disappear during sampling it "folds back" into the lower baseband frequencies. Once an aliased frequency is digitized, the digital data is permanently corrupted. The FPGA cannot distinguish between the true signal and the folded noise.
The Power of Determinism: Why Use an FPGA?
A common question in mixed-signal design is: Why not just use a microcontroller with a built-in ADC?
The answer lies in ruthless hardware-level timing. Microcontrollers rely on software loops and interrupts to trigger ADC reads. Software execution is inherently non-deterministic; an interrupt might be delayed by a few clock cycles if the CPU is handling another task, introducing jitter.
If a system requires deterministic streaming—such as sampling an industrial sensor precisely at 1 MSPS without a nanosecond of deviation—software-driven polling will fail. FPGAs allow you to dedicate a specific, custom piece of RTL logic exclusively to driving the ADC. This guarantees cycle-accurate timing that never drifts, regardless of what the rest of the chip is doing.

Architecting the RTL Pipeline: The SPI Master
Handling the digitized data inside the FPGA requires a deliberate architectural approach. Most precision ADCs communicate via the Serial Peripheral Interface (SPI).
Writing a custom SPI ADC master in Verilog involves managing the serial clock (sclk), the chip select line (cs_n), and precisely shifting in the data bits (sdata) according to the strict timing diagrams of the ADC's datasheet. This module acts as the rigid conductor, ensuring the data is pulled exactly when it is ready.
Here is a simplified Verilog state machine demonstrating how an FPGA controls an ADC to shift in a 16-bit word:
module spi_adc_master (
input wire clk, // System clock
input wire rst_n, // Active-low reset
input wire start, // Trigger to start ADC conversion
input wire sdata, // Serial data coming from the ADC (MISO)
output reg cs_n, // Active-low chip select
output reg sclk, // SPI clock generated by the FPGA
output reg [15:0] data, // 16-bit parallel output data
output reg data_valid // Flag indicating data is ready
);
// State Machine Encoding
localparam IDLE = 2'b00;
localparam CS_LOW = 2'b01;
localparam SHIFT_IN = 2'b10;
localparam DONE = 2'b11;
reg [1:0] state, next_state;
reg [4:0] bit_count;
reg [15:0] shift_reg;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
bit_count <= 0;
cs_n <= 1'b1;
sclk <= 1'b0;
data_valid <= 1'b0;
shift_reg <= 16'd0;
end else begin
// Default assignments
sclk <= ~sclk; // Simple sclk generation (clk / 2)
data_valid <= 1'b0;
case (state)
IDLE: begin
cs_n <= 1'b1;
if (start) begin
state <= CS_LOW;
sclk <= 1'b0;
end
end
CS_LOW: begin
cs_n <= 1'b0; // Pull CS low to initiate ADC
state <= SHIFT_IN;
bit_count <= 16;
end
SHIFT_IN: begin
// Sample data on the rising edge of sclk
if (sclk == 1'b1) begin
shift_reg <= {shift_reg[14:0], sdata};
bit_count <= bit_count - 1;
if (bit_count == 1) state <= DONE;
end
end
DONE: begin
cs_n <= 1'b1;
data <= shift_reg;
data_valid <= 1'b1;
state <= IDLE;
end
endcase
end
end
endmoduleNote: In a production environment, you would add clock dividers to ensure the sclk meets the specific maximum frequency rating of your chosen ADC.
Crossing Domains and Streaming the Output
Once the ADC outputs an N-bit word and pulses data_valid, that data needs a secure destination. A robust FPGA architecture pushes this incoming data directly into a synchronous FIFO buffer.
The FIFO is critical. It acts as an elastic shock absorber, absorbing the rigid, unrelenting timing of the ADC's sampling rate on the write side, and allowing slower downstream processing modules—like a UART transmitter or a digital filter to read the data out on the read side at their own pace without dropping samples.
Conclusion
An FPGA is rarely an isolated digital island. To interact meaningfully with the physical world, it relies on the ADC as a hardware gatekeeper. By combining careful analog front-end design, a deep respect for the mathematics of sampling, and disciplined RTL architecture, you can build systems that capture the continuous world with absolute digital precision.