Arbitrary Clock Division on FPGA

In digital logic design, clock dividers are fundamental building blocks used to derive lower-frequency clocks from a reference signal. While FPGAs often support dedicated clock management resources like PLLs or DLLs for high-quality clock generation, simple counter-based division remains useful for non-critical timing paths. This article explains how to implement even-integer, odd-integer, and fractional clock division using HDL.

Even-Integer Division

For an even division factor N, a straightforward approach uses a counter that toggles the output every N/2 input clock cycles, yielding a 50% duty cycle.

module even_divider (
    input        clk,
    input        rst_n,
    output reg   clk_out
);
    parameter DIV = 4; // Example: divide by 4

    reg [31:0] cnt;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            cnt <= 0;
        else if (cnt == DIV/2 - 1)
            cnt <= 0;
        else
            cnt <= cnt + 1;
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            clk_out <= 0;
        else if (cnt == DIV/2 - 1)
            clk_out <= ~clk_out;
    end
endmodule

Odd-Integer Division with 50% Duty Cycle

Achieving exact 50% duty cycle for odd N requires generating two phase-shifted clocks—one aligned to the rising edge and the other to the falling edge of the input clock—and combining them with a logical OR.

Each sub-clock toggles twice per full output period: once after (N-1)/2 cycles and again after N-1 cycles. The union of these signals produces a symmetrical waveform.

module odd_divider (
    input        clk,
    input        rst_n,
    output       clk_out
);
    parameter DIV = 5; // Example: divide by 5

    reg [31:0] cnt_rise, cnt_fall;
    reg clk_p, clk_n;

    // Rising-edge domain
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            cnt_rise <= 0;
        else if (cnt_rise == DIV - 1)
            cnt_rise <= 0;
        else
            cnt_rise <= cnt_rise + 1;
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            clk_p <= 1'b1;
        else if (cnt_rise == (DIV-1)/2 - 1 || cnt_rise == DIV - 1)
            clk_p <= ~clk_p;
    end

    // Falling-edge domain
    always @(negedge clk or negedge rst_n) begin
        if (!rst_n)
            cnt_fall <= 0;
        else if (cnt_fall == DIV - 1)
            cnt_fall <= 0;
        else
            cnt_fall <= cnt_fall + 1;
    end

    always @(negedge clk or negedge rst_n) begin
        if (!rst_n)
            clk_n <= 1'b1;
        else if (cnt_fall == (DIV-1)/2 - 1 || cnt_fall == DIV - 1)
            clk_n <= ~clk_n;
    end

    assign clk_out = clk_p | clk_n;
endmodule

Fractional Division

Fractional division (e.g., dividing by 3.5) typically employs techniques such as pulse swallowing or delta-sigma modulation to approximate non-integer ratios over multiple cycles. Implementation details depend on requierd jitter tolerance and frequency resolution, and are often better handled by FPGA-integrated clocking primitives when available.

Tags: Verilog FPGA Clock Division Odd Division Even Division

Posted on Tue, 26 May 2026 17:47:00 +0000 by shamilton