0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for Odd Frequency Divider: Simple Example

An odd frequency divider in Verilog can be implemented using a counter and a flip-flop to toggle the output at odd division ratios like 3 or 5. The code uses a counter to count input clock cycles and toggles the output clock when the count reaches half the division value, producing an output frequency that is an odd fraction of the input clock.
📐

Syntax

An odd frequency divider typically uses a counter and a flip-flop. The main parts are:

  • Input clock: The original clock signal.
  • Reset: To initialize the counter and output.
  • Counter: Counts clock cycles up to the division number.
  • Output clock: Toggles to create the divided frequency.

The counter resets after reaching the division number, and the output toggles at specific counts to achieve an odd division.

verilog
module odd_freq_divider(
    input wire clk_in,
    input wire rst,
    output reg clk_out
);

    parameter DIV = 3; // Odd division factor
    reg [$clog2(DIV)-1:0] count = 0;

    always @(posedge clk_in or posedge rst) begin
        if (rst) begin
            count <= 0;
            clk_out <= 0;
        end else begin
            if (count == DIV - 1) begin
                count <= 0;
                clk_out <= ~clk_out;
            end else begin
                count <= count + 1;
            end
        end
    end
endmodule
💻

Example

This example divides the input clock frequency by 3, an odd number. The output clock toggles every 3 input clock cycles, producing a frequency one-third of the input.

verilog
module odd_freq_divider_3(
    input wire clk_in,
    input wire rst,
    output reg clk_out
);

    parameter DIV = 3;
    reg [1:0] count = 0; // 2 bits to count up to 3

    always @(posedge clk_in or posedge rst) begin
        if (rst) begin
            count <= 0;
            clk_out <= 0;
        end else begin
            if (count == DIV - 1) begin
                count <= 0;
                clk_out <= ~clk_out;
            end else begin
                count <= count + 1;
            end
        end
    end
endmodule

// Testbench to simulate
module tb;
    reg clk = 0;
    reg rst = 1;
    wire clk_out;

    odd_freq_divider_3 uut(.clk_in(clk), .rst(rst), .clk_out(clk_out));

    always #5 clk = ~clk; // 10 time units period

    initial begin
        #12 rst = 0;
        #100 $finish;
    end

    initial begin
        $monitor($time, " clk_out=%b", clk_out);
    end
endmodule
Output
0 clk_out=0 10 clk_out=0 20 clk_out=1 30 clk_out=1 40 clk_out=0 50 clk_out=0 60 clk_out=1 70 clk_out=1 80 clk_out=0 90 clk_out=0 100 clk_out=1
⚠️

Common Pitfalls

Common mistakes when creating odd frequency dividers include:

  • Not toggling the output at the correct count, causing wrong frequency.
  • Using even division logic which doesn't work for odd numbers.
  • Incorrect counter width causing overflow or incorrect counting.
  • Not resetting the counter and output properly on reset.

Always ensure the counter counts from 0 to DIV-1 and toggles output only at the terminal count.

verilog
/* Wrong approach: toggling output every count, not at DIV-1 */
module wrong_odd_divider(
    input wire clk_in,
    input wire rst,
    output reg clk_out
);
    parameter DIV = 3;
    reg [1:0] count = 0;

    always @(posedge clk_in or posedge rst) begin
        if (rst) begin
            count <= 0;
            clk_out <= 0;
        end else begin
            count <= count + 1;
            clk_out <= ~clk_out; // toggling every clock - wrong
        end
    end
endmodule

/* Correct approach: toggle only when count reaches DIV-1 */
module correct_odd_divider(
    input wire clk_in,
    input wire rst,
    output reg clk_out
);
    parameter DIV = 3;
    reg [1:0] count = 0;

    always @(posedge clk_in or posedge rst) begin
        if (rst) begin
            count <= 0;
            clk_out <= 0;
        end else begin
            if (count == DIV - 1) begin
                count <= 0;
                clk_out <= ~clk_out;
            end else begin
                count <= count + 1;
            end
        end
    end
endmodule
📊

Quick Reference

Tips for odd frequency dividers in Verilog:

  • Use a counter that counts from 0 to DIV-1.
  • Toggle output clock only when counter reaches DIV-1.
  • Ensure counter width is enough to hold DIV-1.
  • Reset counter and output on reset signal.
  • Test with a testbench to verify output frequency.

Key Takeaways

Use a counter and toggle output only at the terminal count for odd frequency division.
Ensure the counter width matches the division factor to avoid overflow.
Reset logic is essential to initialize the divider correctly.
Test your design with a testbench to confirm correct frequency output.
Avoid toggling output every clock cycle; toggle only at the correct count.