HomeFPGA from ScratchDay 9
DAY 9 · HDL FUNDAMENTALS

Counters & Clock Dividers

By EcrioniX · Updated Jun 11, 2026

You blinked an LED in Day 8 using a simple counter. Now let's go deeper: parameterized counters, modulo-N counters, the crucial difference between a clock divider and a clock enable (and why you should almost always use the latter on FPGAs), and a reusable clkdiv.v module that generates clean enable pulses at any rate.

1. Counter types

TypeBehaviourVerilog pattern
Up counter0 → MAX → 0 (wraps)cnt <= cnt + 1
Down counterMAX → 0 → MAX (wraps)cnt <= cnt - 1
Modulo-N counter0 → N-1 → 0if(cnt==N-1) cnt<=0; else cnt<=cnt+1
Loadable counterload a value, then countif(load) cnt<=d; else cnt<=cnt+1

2. Clock divider vs clock enable — why it matters

✅ Use clock enables on FPGAs, not divided clocks

Generating a new clock signal by toggling a register creates a gated clock — this bypasses the FPGA's dedicated clock distribution network, causes skew, and can fail timing analysis. The right approach: keep everything in the same clock domain, and generate a one-cycle enable pulse at the slower rate. Downstream logic checks if (en) before updating.

3. clkdiv.v — parameterized clock enable generator

PortDirWidthMeaning
clkinput1system clock (all logic runs here)
rstinput1synchronous reset
en_outoutput1one-cycle high pulse every DIV clock cycles
clkdiv.v — parameterized clock enable generator
// Clock enable generator: pulses en_out for one cycle every DIV clk cycles.
// Use en_out as a gate in downstream always blocks, NOT as a clock signal.
module clkdiv #(parameter DIV = 100) (
    input  wire clk,
    input  wire rst,
    output reg  en_out   // one-cycle enable pulse
);
    // Width must hold DIV-1. $clog2(DIV) bits is the minimum.
    // We use a generous 32-bit counter for clarity.
    reg [31:0] cnt;

    always @(posedge clk) begin
        if (rst) begin
            cnt    <= 32'd0;
            en_out <= 1'b0;
        end else if (cnt == DIV - 1) begin
            cnt    <= 32'd0;
            en_out <= 1'b1;   // pulse for exactly one cycle
        end else begin
            cnt    <= cnt + 1;
            en_out <= 1'b0;
        end
    end
endmodule

Example: using clkdiv in another module

slow_counter.v — counter enabled at 1/100 rate
module slow_counter (input clk, input rst, output reg [7:0] cnt);
    wire tick;
    clkdiv #(.DIV(100)) div0 (.clk(clk),.rst(rst),.en_out(tick));
    always @(posedge clk)
        if (rst)   cnt <= 8'd0;
        else if (tick) cnt <= cnt + 1;  // only increments every 100 cycles
endmodule

4. Testbench

tb_clkdiv.v — testbench (DIV=4)
`timescale 1ns/1ps
module tb_clkdiv;
    reg  clk=0, rst=1;
    wire en_out;
    clkdiv #(.DIV(4)) dut(.clk(clk),.rst(rst),.en_out(en_out));
    always #5 clk=~clk;
    integer errors=0, pulses=0;
    initial begin
        @(posedge clk); rst=0;
        repeat(20) begin
            @(posedge clk); #1;
            if(en_out) begin pulses=pulses+1; $display("pulse at t=%0t",$time);end
        end
        // Expect 5 pulses in 20 cycles (every 4th cycle)
        if(pulses==5) $display("ok   got %0d pulses in 20 cycles",pulses);
        else begin $display("FAIL: expected 5, got %0d",pulses);errors=errors+1;end
        if(errors==0) $display("ALL TESTS PASSED"); else $display("%0d FAILED",errors);
        $finish;
    end
endmodule
expected output
pulse at t=45
pulse at t=85
pulse at t=125
pulse at t=165
pulse at t=205
ok   got 5 pulses in 20 cycles
ALL TESTS PASSED

🎯 Day 9 takeaways

FAQ

Clock divider vs clock enable?

Clock divider generates a new (slower) clock signal — avoid on FPGAs. Clock enable keeps one clock but pulses an enable signal at the lower rate — the correct FPGA approach.

What is a modulo counter?

Counts 0 to N-1 then wraps to 0. Reset when cnt==N-1. Used to generate periodic pulses at non-power-of-2 rates.

Previous
← Day 8: Blink an LED

← Full roadmap