Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Clocks, flip-flops and counters in Verilog

After this lesson: I can describe a counter that changes on a clock edge.

55 min lesson4 commandsDigital design lab: Verilog, VHDL and yosys on one private Ubuntu VM

How a chip counts with a clock

A counter in Verilog is a circuit that adds one to a stored number every time a clock signal rises. The clock is what turns a pile of gates into a machine that does one step at a time.

A stopwatch, a traffic light and a processor all rely on the same trick. Something remembers a value, and the clock says when it may change.

By the end of this lesson

Note

I can describe a counter that changes on a clock edge.

Key words

WordWhat it meansExample
Clocka signal that goes up and down at a steady beatclk
Rising edgethe instant the clock goes from 0 to 1
Flip-flopa part that remembers one bit between edges
Registerseveral flip-flops that hold one number
Reseta signal that puts the stored value back to 0rst
Countera register that adds one on each edge

The cells students fill in are left blank in this preview.

A clock tells a circuit when to change

Gates alone change the moment their inputs change. A clock is a signal that goes 0, 1, 0, 1 at a steady beat.

A flip-flop looks at its input only at the rising edge, the instant the clock goes from 0 to 1. It stores what it saw and holds it until the next edge.

always at the rising edge describes a register

In Verilog, always @(posedge clk) means: do this at every rising edge of clk. The signals assigned inside it become flip-flops.

Inside it, <= means: take this new value at the edge. It is not the same as less than or equal. A reset sets the value back to 0, and a counter is a register that adds one each time.

The lab's 4-bit counter with a reset

Code: c
// counter.v, given in the lab: a 4-bit counter with a reset.
module counter(input clk, input rst, output reg [3:0] q);
  always @(posedge clk)
    if (rst) q <= 4'd0;
    else q <= q + 4'd1;
endmodule

A counter can wrap at any number

A 4-bit register holds 0 to 15, but a design can wrap earlier. Here a counter named count6 goes 0, 1, 2, 3, 4, 5 and back to 0.

Four Runs write it and a testbench into /tmp, compile them and run eight clock edges. The line initial q = 0; only gives the simulation a starting value. A chip would use a reset instead.

Write the counter

Command
echo 'module count6(input clk, output reg [2:0] q); initial q = 0; always @(posedge clk) if (q == 5) q <= 0; else q <= q + 1; endmodule' > /tmp/count6.v

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Write the testbench

Command
echo 'module count6_tb; reg clk = 0; wire [2:0] q; count6 dut(clk, q); always #5 clk = ~clk; initial begin repeat (8) begin @(posedge clk); #1 $display("after edge, q = %0d", q); end $finish; end endmodule' > /tmp/count6_tb.v

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Compile both files

Command
iverilog -o /tmp/count6 /tmp/count6.v /tmp/count6_tb.v

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Run eight clock edges

Command
vvp /tmp/count6

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

The same counter as a Python model

Code: python
# A counter that runs from 0 to 5 and wraps, one step for each clock edge.
q = 0
for edge in range(8):
    if q == 5:
        q = 0
    else:
        q = q + 1
    print("after edge", edge + 1, "q =", q)
# Change 5 to 3 and run again.

A common mistake

Warning

Many people think a counter counts the whole time the clock is 1. It counts once, at the rising edge. A clock that stays at 1 for a long time still adds only one. Count edges, not time.

Going further

Edit a copy of count6.v so it counts only while a new input en is 1. Add input en to the ports and test it.

Write down first what q should do at an edge when en is 0. Then check the simulation agrees.

About this lab and its source: Digital design lab: Verilog, VHDL and yosys on one private Ubuntu VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.