ADC_SuccApproxADC_FSM

ADC_SuccApproxADC_FSM : A finite-state machine for a successive approximation register ADC

A finite-state machine for a successive approximation register analog-to-digital converter (SAR-ADC) performs the necessary sequencing for the successive approximation algorithm and digital output generation.

This finite-state machine model for a SAR ADC is described in pure Verilog and has two parts: an internal sequencing clock generator and a 6-bit successive approximation register. The internal sequencing clock generator produces an internal clock to perform the successive approximation process. The successive approximation register performs the binary search and collects the output from the comparator and produces the final digitized output.

In more detail, when the external clock clk goes low, the logic toggles the internal clock comp_clk total of 7 times. At its first cycle, the logic resets the state of the successive approximation register sel_dac. And for the next 6 cycles, the logic incrementally updates this register value starting from its MSB to LSB based on the comparator output of each comp_clk cycle. When clk goes high, the logic drives the output out with the final value of sel_dac.

module ADC_SuccApproxADC_FSM (
    output reg [5:0] out,       //digital output
    output reg [5:0] sel_dac,   //successive approximation register
    output reg comp_clk,        //internal clock
    input comp_out,             //comparator output
    input clk                   //sample-and-hold clock
);

    int i, pos;

    // internal sequencing clock generation
    always @(clk) begin
        if (clk) begin          // tracking phase
            comp_clk = 1;
        end
        else begin              // hold-and-decision phase
            for (i=0; i<7; i++) begin
                comp_clk = 0;
                #(500ps);
                comp_clk = 1;
                #(500ps);
            end
        end
    end
    
    // successive approximation register
    always @(negedge comp_clk or posedge clk) begin
        if (clk) begin          // clk acts as an asynchronous reset
            #(1ns) sel_dac = 6'b111111;
            pos = 6;
        end
        else begin
            if (pos == 6) sel_dac = 6'b100000;
            else begin
                sel_dac[pos] = ~comp_out;
                if (pos > 0) sel_dac[pos-1] = 1;
            end
            pos--;
        end
    end
    
    // final ADC output
    always @(posedge clk) begin
        out = sel_dac;
    end
    
endmodule

Input/Output Terminals

Name I/O Type Description
out[5:0] output reg digital output
sel_dac[5:0] output reg successive approximation register
comp_clk output reg internal clock
comp_out input wire comparator output
clk input wire sample-and-hold clock