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:
| Step | q[3:0] | Step | q[3:0] |
|---|---|---|---|
| 0 | 0000 | 4 | 1111 |
| 1 | 0001 | 5 | 1110 |
| 2 | 0011 | 6 | 1100 |
| 3 | 0111 | 7 | 1000 |
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
endmodulestep | 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
endmodulestep | 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
endmodulePASS: 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 onlyNstates — and from an all-zero reset it never leaves0. - 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.
Share your question in comments or talk to our mentor team for batch guidance.
Open this design in the free in-browser simulator — edit, compile and see the waveform/log instantly.
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