Source / Read the circuit

sar_controller.sv

lessons/adc_digital/rtl/sar_controller.sv

`timescale 1ns/1ps
// AD02: synchronous teaching SAR; comparator response belongs to current trial.
module sar_controller #(
    parameter integer BITS=10, SETTLE=2, TIMEOUT=8
)(input wire clk, rst_n, start,
  input wire cmp_valid, cmp_ge,
  output reg busy, done, error,
  output reg [BITS-1:0] trial, result,
  output wire cmp_req);
    localparam IDLE=0, APPLY=1, DAC_WAIT=2, COMP_WAIT=3;
    reg [1:0] state;
    reg [BITS-1:0] kept;
    integer bit_index, wait_count;
    assign cmp_req = busy && state==COMP_WAIT;
    always @(posedge clk) begin
        if (!rst_n) begin
            state<=IDLE; busy<=0; done<=0; error<=0;
            trial<=0; result<=0; kept<=0; bit_index<=0; wait_count<=0;
        end else begin
            done<=0; error<=0;
            case (state)
                IDLE: if (start) begin
                    busy<=1; kept<=0; bit_index<=BITS-1; state<=APPLY;
                end
                APPLY: begin
                    trial<=kept | ({{(BITS-1){1'b0}},1'b1} << bit_index);
                    wait_count<=0; state<=DAC_WAIT;
                end
                DAC_WAIT: begin
                    if (wait_count==SETTLE-1) begin
                        wait_count<=0; state<=COMP_WAIT;
                    end else wait_count<=wait_count+1;
                end
                COMP_WAIT: begin
                    if (cmp_valid) begin
                        if (cmp_ge) kept<=trial;
                        if (bit_index==0) begin
                            result<=cmp_ge ? trial : kept;
                            busy<=0; done<=1; state<=IDLE;
                        end else begin bit_index<=bit_index-1; state<=APPLY; end
                    end else if (wait_count==TIMEOUT-1) begin
                        busy<=0; error<=1; state<=IDLE;
                    end else wait_count<=wait_count+1;
                end
                default: begin busy<=0; error<=1; state<=IDLE; end
            endcase
        end
    end
endmodule