DLL_ChargePumpDLL8SOwithFLD_FalseLockDetector

DLL_ChargePumpDLL8SOwithFLD_FalseLockDetector : A false-lock detector (FLD) for a multi-phase delay-locked loop (DLL)

A false-lock detector (FLD) for a multi-phase delay-locked loop (DLL) detects if the DLL is locked or stuck at a false lock position. A false lock is possible when a DLL has a wide enough range encompassing multiple lock positions and when it starts from an initial condition that is far from the desired lock position. This particular FLD detects a false-lock condition based on the delay spacings between the multi-phase output clocks.

This FLD model consists of 8 D flip-flops followed by a combinational logic and a multiplexer. The eight D flip-flops sample the input clock clk_in at the rising edge of the 8 multi-phase output clocks clk_out, respectively, and the combinational logic processes the sampled values to decide whether the DLL is in a correct lock, harmonic lock, or stuck lock state. Based on this decision, the multiplexer either passes the up and dn signals from the phase detector to the charge pump as-is, or overrides them with values that can bring the DLL towards the correct lock.

Ref: S. Byun, C.-H. Park, Y. Song, S. Wang, C. S. G. Conroy, B. Kim, “A Low-Power CMOS Bluetooh RF Transceiver with a Digital Offset Cancelling DLL-based GFSK Demodulator,” IEEE J. Solid-State Circuits, October 2003.

module DLL_ChargePumpDLL8SOwithFLD_FalseLockDetector (
    output reg up_out,      // up output to CP
    output reg dn_out,      // dn output to CP
    input up_in,            // up input from PD
    input dn_in,            // dn input from PD
    input [7:0] clk_out,    // multi-phase output clocks
    input clk_in            // input clock
);

    reg [7:0] dff_out;
    reg up_flag, dn_flag, lock_flag;

    // D-flipflops
    genvar i;
    generate
        for (i=0; i<8; i++) begin
            always @(posedge clk_out[i]) begin
                dff_out[i] <= clk_in;
            end
        end
    endgenerate

    // combinational logic
    always @(dff_out) begin
        casex (dff_out)
            8'b1111_1111: begin
                up_flag   <= 1'b0;
                dn_flag   <= 1'b1;
                lock_flag <= 1'b0;
            end
            8'bxxxx_x011: begin
                up_flag   <= 1'b1;
                dn_flag   <= 1'b0;
                lock_flag <= 1'b0;
            end
            8'bxxxx_xx01: begin
                up_flag   <= 1'b1;
                dn_flag   <= 1'b0;
                lock_flag <= 1'b0;
            end
            8'bxxxx_xxx0: begin
                up_flag   <= 1'b1;
                dn_flag   <= 1'b0;
                lock_flag <= 1'b0;
            end
            default: begin
                up_flag   <= 1'b0;
                dn_flag   <= 1'b0;
                lock_flag <= 1'b1;
            end
        endcase
    end

    // multiplexer
    always @(*) begin
        case ({up_flag, dn_flag, lock_flag})
            3'b100: begin
                up_out <= 1;
                dn_out <= 0;
            end
            3'b010: begin
                up_out <= 0;
                dn_out <= 1;
            end
            3'b001: begin
                up_out <= up_in;
                dn_out <= dn_in;
            end
            default : begin
                up_out <= up_in;
                dn_out <= dn_in;
            end
        endcase
    end
endmodule

Input/Output Terminals

Name I/O Type Description
up_out output reg up output to CP
dn_out output reg dn output to CP
up_in input wire up input from PD
dn_in input wire dn input from PD
clk_out[7:0] input wire multi-phase output clocks
clk_in input wire input clock