Johnson Counter Verilog Code (Twisted-Ring, Parameterized)

A Johnson counter — also called a twisted-ring or switch-tail counter — is a shift register whose last output is inverted and fed back to the first input. That single twist turns an N-bit register into a counter that steps through 2N unique states before repeating, exactly twice the length of a plain ring counter built from the same number of flip-flops.

This guide gives you working johnson counter verilog code: a parameterized design you can size to any width, a version with decoded one-hot outputs, and a self-checking testbench that proves the 2N-state sequence. Every block below compiles with Icarus Verilog using iverilog -g2005 -o sim FILE.v && vvp sim, and the simulation logs shown are the real output.

How the twist produces 2N states

In an ordinary ring counter the serial output loops straight back to the input, so a single 1 circulates and you only ever see N states. A Johnson counter inverts that feedback. Each clock edge shifts the register one position and injects the complement of the end bit. The register fills with ones from one side, then empties back to zeros, giving a clean, Gray-code-like walk of 2N states.

The whole behaviour reduces to one line of RTL: q <= {q[WIDTH-2:0], ~q[WIDTH-1]}. This shifts left and feeds the inverted most-significant bit into the least-significant position. A 4-bit counter therefore visits eight states:

Stepq[3:0]Stepq[3:0]
0000041111
1000151110
2001161100
3011171000

After step 7 the counter wraps back to 0000. Notice that only one bit changes between adjacent states — a property that makes Johnson counters attractive for low-noise state machines and glitch-free decoding.

Parameterized Johnson counter in Verilog

The design below uses a WIDTH parameter, so the same module becomes a MOD-6, MOD-8, MOD-10 or any other even-modulus counter just by changing one value. The testbench instantiates a 4-bit version and prints the full 2N sequence.

// johnson_counter.v - parameterized Johnson (twisted-ring) counter
module johnson_counter #(
    parameter WIDTH = 4
)(
    input  wire             clk,
    input  wire             rst_n,
    output reg  [WIDTH-1:0] q
);
    // Twisted ring: shift left, feed the complement of the MSB into the LSB.
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            q <= {WIDTH{1'b0}};
        else
            q <= {q[WIDTH-2:0], ~q[WIDTH-1]};
    end
endmodule

module tb_johnson_counter;
    localparam WIDTH = 4;
    reg              clk;
    reg              rst_n;
    wire [WIDTH-1:0] q;
    integer          i;

    johnson_counter #(.WIDTH(WIDTH)) dut (
        .clk   (clk),
        .rst_n (rst_n),
        .q     (q)
    );

    // 10 ns clock
    initial clk = 1'b0;
    always #5 clk = ~clk;

    initial begin
        rst_n = 1'b0;            // assert reset
        @(negedge clk);
        rst_n = 1'b1;            // release reset between edges
        $display("step |  q");
        for (i = 0; i < 2*WIDTH; i = i + 1) begin
            #1 $display(" %2d  | %b", i, q);  // sample just after the edge
            @(posedge clk);
        end
        #1 $display("next | %b  (wrapped back to start)", q);
        $finish;
    end
endmodule
step |  q
  0  | 0000
  1  | 0001
  2  | 0011
  3  | 0111
  4  | 1111
  5  | 1110
  6  | 1100
  7  | 1000
next | 0000  (wrapped back to start)
/var/folders/l0/gs5hnkm56g54bmxg32r6nnwr0000gn/T/tmpoyggqd68/johnson_counter.v:45: $finish called at 86 (1s)

Two details make this synthesizable and safe. The register uses a non-blocking assignment (<=) inside a clocked always block, which models flip-flop behaviour correctly. The asynchronous active-low reset (rst_n) forces a known starting value of all zeros — important, as the next section explains.

Decoding the states into one-hot outputs

Often you do not want the raw register value — you want a separate active-high line for each state, for example to drive six phases of a stepper or a timing sequencer. Because a Johnson counter only ever visits its 2N valid codes, each state is uniquely identified, so the decode is clean. The module below is a MOD-6 counter (three flip-flops) with a 6-bit one-hot output y.

// johnson_decoded.v - Johnson counter with one-hot decoded outputs (MOD-6)
module johnson_decoded (
    input  wire       clk,
    input  wire       rst_n,
    output reg  [2:0] q,       // 3 flip-flops -> 6 unique states
    output wire [5:0] y        // one-hot: exactly one line high per state
);
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            q <= 3'b000;
        else
            q <= {q[1:0], ~q[2]};
    end

    // Decode the six valid Johnson states into a one-hot bus.
    assign y[0] = (q == 3'b000);
    assign y[1] = (q == 3'b001);
    assign y[2] = (q == 3'b011);
    assign y[3] = (q == 3'b111);
    assign y[4] = (q == 3'b110);
    assign y[5] = (q == 3'b100);
endmodule

module tb_johnson_decoded;
    reg        clk;
    reg        rst_n;
    wire [2:0] q;
    wire [5:0] y;
    integer    i;

    johnson_decoded dut (
        .clk   (clk),
        .rst_n (rst_n),
        .q     (q),
        .y     (y)
    );

    initial clk = 1'b0;
    always #5 clk = ~clk;

    initial begin
        rst_n = 1'b0;
        @(negedge clk);
        rst_n = 1'b1;
        $display("step |  q  |   y");
        for (i = 0; i < 6; i = i + 1) begin
            #1 $display(" %2d  | %b | %b", i, q, y);
            @(posedge clk);
        end
        $finish;
    end
endmodule
step |  q  |   y
  0  | 000 | 000001
  1  | 001 | 000010
  2  | 011 | 000100
  3  | 111 | 001000
  4  | 110 | 010000
  5  | 100 | 100000
/var/folders/l0/gs5hnkm56g54bmxg32r6nnwr0000gn/T/tmp38u81tci/johnson_decoded.v:50: $finish called at 65 (1s)

The log shows a single bit walking across the 6-bit bus, one hot line per state. Here the decode is written as explicit equality comparisons for readability, but a classic property of Johnson counters is that each state can be detected with a simple two-input gate on an adjacent flip-flop pair. Synthesis tools recognise the mutually exclusive states and reduce the comparators accordingly, which is why Johnson decoding is prized for being glitch-free.

A self-checking testbench

Printing values is fine for eyeballing, but a testbench that verifies the behaviour scales better. This one captures one full lap, then asserts two things automatically: the counter wraps exactly to its start value after 2N steps, and all 2N captured states are unique. It prints PASS only if both hold.

// johnson_selfcheck.v - self-checking testbench for a Johnson counter
module johnson_counter #(
    parameter WIDTH = 4
)(
    input  wire             clk,
    input  wire             rst_n,
    output reg  [WIDTH-1:0] q
);
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            q <= {WIDTH{1'b0}};
        else
            q <= {q[WIDTH-2:0], ~q[WIDTH-1]};
    end
endmodule

module tb_johnson_selfcheck;
    localparam WIDTH = 4;
    localparam STATES = 2*WIDTH;          // expected period
    reg              clk;
    reg              rst_n;
    wire [WIDTH-1:0] q;
    reg  [WIDTH-1:0] seen [0:STATES-1];   // record one full lap
    integer          i, j, errors;

    johnson_counter #(.WIDTH(WIDTH)) dut (
        .clk(clk), .rst_n(rst_n), .q(q)
    );

    initial clk = 1'b0;
    always #5 clk = ~clk;

    initial begin
        errors = 0;
        rst_n  = 1'b0;
        @(negedge clk);
        rst_n = 1'b1;

        // Capture one full lap of STATES values.
        for (i = 0; i < STATES; i = i + 1) begin
            #1 seen[i] = q;
            @(posedge clk);
        end

        // Check 1: the counter wrapped exactly to its start value.
        #1 if (q !== seen[0]) begin
            errors = errors + 1;
            $display("FAIL: period != %0d (did not wrap to start)", STATES);
        end

        // Check 2: all STATES captured values are unique.
        for (i = 0; i < STATES; i = i + 1)
            for (j = i + 1; j < STATES; j = j + 1)
                if (seen[i] === seen[j]) begin
                    errors = errors + 1;
                    $display("FAIL: duplicate state %b at steps %0d and %0d",
                             seen[i], i, j);
                end

        if (errors == 0)
            $display("PASS: %0d unique states, wraps correctly", STATES);
        else
            $display("TOTAL ERRORS: %0d", errors);
        $finish;
    end
endmodule
PASS: 8 unique states, wraps correctly
/var/folders/l0/gs5hnkm56g54bmxg32r6nnwr0000gn/T/tmp54h3k_nw/johnson_selfcheck.v:64: $finish called at 86 (1s)

Change WIDTH in both the design and the localparam and the checks still hold — the testbench derives the expected period from 2*WIDTH rather than hard-coding it.

Common mistakes

  • Dropping the inversion. If you feed back q[WIDTH-1] instead of ~q[WIDTH-1], you build a plain ring counter with only N states — and from an all-zero reset it never leaves 0.
  • No reset, or forgetting to reset. An N-bit register has 2^N codes but a Johnson counter uses only 2N of them. The unused codes form a separate parasitic loop. Without a reset the counter can power up inside that illegal cycle and never reach a valid state, so always drive a known value at start-up (or add self-correcting feedback that forces an illegal code back onto the main ring).
  • Blocking assignments in the clocked block. Using = instead of <= for the shift creates simulation races and does not model the pipeline of flip-flops. Keep sequential logic non-blocking.
  • Mixed shift direction and feedback bit. Shifting left but inverting the LSB (instead of the MSB), or shifting right while inverting the wrong end, produces a sequence that is not a clean 2N walk. Pick a direction and keep the feedback bit on the opposite end.
  • Over-wide decoders. Decoding every state with full-width comparators wastes logic. Because Johnson states are mutually exclusive, each decode line needs at most a two-input gate on an adjacent flip-flop pair.

Quick check

How many unique states does an N-bit Johnson counter produce?

2N states. An N-bit register normally has 2^N codes, but the twisted-ring feedback restricts it to a 2N-state cycle — twice as many as a ring counter of the same width.

What single change turns a ring counter into a Johnson counter?

Invert the feedback. Instead of looping the end output straight back, feed the complement of the last stage into the first input, e.g. q <= {q[WIDTH-2:0], ~q[WIDTH-1]}.

Why must a Johnson counter be reset to a known state?

The 2^N minus 2N unused codes form a separate illegal loop. A reset (or self-correcting logic) guarantees the counter starts on the valid 2N-state ring rather than getting stuck in the parasitic cycle.

For a 4-bit Johnson counter, how many flip-flops are used and what is the modulus?

Four flip-flops, and the modulus is 8 (2 x 4). It cycles through eight unique states before repeating.

Have questions about this topic?
Share your question in comments or talk to our mentor team for batch guidance.
▶ Try it in the ChipXpert Lab

Open this design in the free in-browser simulator — edit, compile and see the waveform/log instantly.

Run it in the Lab

Learn Verilog with mentors, labs and placement support

This free series is maintained by the ChipXpert training team in Hyderabad & Bengaluru. Go deeper with instructor-led courses on real EDA tools.

Explore VLSI Courses
Next batch starts 18th November 2026
Start your VLSI career with ChipXpert

Live online and classroom batches in Hyderabad & Bengaluru. Fill in your details and a counsellor will call you back.

  • Real EDA tools in your browser: industry-standard EDAReal EDA tools in your browser
  • Recorded sessions on the elearn portalRecorded sessions
  • Placement assistance: resume, mock interviewsPlacement assistance
  • Merit scholarship up to 60% · EMI optionsScholarship up to 60%
Hi! Ask me about courses, fees, batches or discounts. ×
BENGALURU
HYDERABAD