0
0
VerilogHow-ToBeginner · 3 min read

How to Design Clock Divider in Verilog: Simple Guide

To design a clock divider in Verilog, create a counter that increments on each clock pulse and toggles an output clock when it reaches a set value. This output clock runs at a slower frequency, effectively dividing the input clock frequency by a chosen factor.
📐

Syntax

A basic clock divider uses a reg counter and an output clock signal. The counter increments on every rising edge of the input clock. When the counter reaches a preset value, the output clock toggles and the counter resets.

Key parts:

  • input clk: The original fast clock signal.
  • output reg clk_out: The slower divided clock output.
  • reg [N:0] counter: A register to count clock cycles.
  • always @(posedge clk): Trigger block on clock rising edge.
verilog
module clock_divider(
    input clk,
    output reg clk_out
);

    reg [3:0] counter = 0; // 4-bit counter

    always @(posedge clk) begin
        if (counter == 9) begin
            counter <= 0;
            clk_out <= ~clk_out; // toggle output clock
        end else begin
            counter <= counter + 1;
        end
    end

endmodule
💻

Example

This example divides the input clock frequency by 20. The counter counts from 0 to 9, toggling the output clock every 10 input cycles, resulting in a clock output frequency that is 1/20th of the input.

verilog
module clock_divider_example(
    input clk,
    output reg clk_out
);

    reg [3:0] counter = 0;

    always @(posedge clk) begin
        if (counter == 9) begin
            counter <= 0;
            clk_out <= ~clk_out;
        end else begin
            counter <= counter + 1;
        end
    end

endmodule

// Testbench to simulate the clock divider
module testbench();
    reg clk = 0;
    wire clk_out;

    clock_divider_example uut(.clk(clk), .clk_out(clk_out));

    // Generate input clock with period 10 time units
    always #5 clk = ~clk;

    initial begin
        $dumpfile("clock_divider.vcd");
        $dumpvars(0, testbench);
        #200 $finish;
    end
endmodule
Output
Simulation waveform shows clk toggling every 10 input clock cycles, clk_out toggling every 20 input clock cycles.
⚠️

Common Pitfalls

Common mistakes when designing clock dividers include:

  • Not resetting the counter properly, causing incorrect frequency.
  • Using blocking assignments (=) inside always @(posedge clk) blocks instead of non-blocking (<=), which can cause timing issues.
  • Not initializing the output clock signal, leading to unknown startup state.
  • Choosing a counter size too small for the division factor, causing overflow.
verilog
/* Wrong way: blocking assignment and no reset */
always @(posedge clk) begin
    if (counter == 9) begin
        counter = 0; // blocking assignment - wrong
        clk_out = ~clk_out; // blocking assignment - wrong
    end else begin
        counter = counter + 1;
    end
end

/* Right way: non-blocking assignment and reset */
always @(posedge clk or posedge reset) begin
    if (reset) begin
        counter <= 0;
        clk_out <= 0;
    end else if (counter == 9) begin
        counter <= 0;
        clk_out <= ~clk_out;
    end else begin
        counter <= counter + 1;
    end
end
📊

Quick Reference

  • Use a counter to track input clock cycles.
  • Toggle output clock when counter reaches half the division factor.
  • Use non-blocking assignments (<=) inside clocked always blocks.
  • Initialize signals to avoid unknown states.
  • Choose counter width to cover the division range.

Key Takeaways

Use a counter to divide the input clock frequency by toggling output after a set count.
Always use non-blocking assignments inside clocked always blocks for correct timing.
Initialize your output clock and counter to avoid unknown startup states.
Choose the counter size based on the division factor to prevent overflow.
Reset logic helps keep the clock divider stable and predictable.