0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for Ring Counter: Syntax and Example

A ring counter in Verilog is a shift register with a single '1' circulating through its bits. You can implement it using a reg vector and a clocked always block that shifts the '1' bit around. The code initializes one bit high and shifts it on each clock cycle.
📐

Syntax

A ring counter uses a reg vector to hold the bits. The always @(posedge clk or posedge reset) block updates the register on each clock rising edge or resets it. Inside, the bits shift circularly, moving the '1' to the next position.

  • reg [N-1:0] ring;: holds the ring bits.
  • if (reset): sets initial state with one bit high.
  • else: shifts the bits circularly.
verilog
module ring_counter(
    input wire clk,
    input wire reset,
    output reg [3:0] ring
);

always @(posedge clk or posedge reset) begin
    if (reset) begin
        ring <= 4'b0001; // Initialize with one bit high
    end else begin
        ring <= {ring[2:0], ring[3]}; // Circular shift left
    end
end

endmodule
💻

Example

This example shows a 4-bit ring counter that cycles a single '1' through four bits on each clock pulse. The reset input sets the initial position. The output ring shows the circulating bit.

verilog
module testbench();
    reg clk = 0;
    reg reset = 1;
    wire [3:0] ring;

    ring_counter uut(
        .clk(clk),
        .reset(reset),
        .ring(ring)
    );

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

    initial begin
        $monitor($time, " ns: ring = %b", ring);
        #10 reset = 0; // Release reset after 10 time units
        #100 $finish; // Stop simulation after 100 time units
    end
endmodule

module ring_counter(
    input wire clk,
    input wire reset,
    output reg [3:0] ring
);

always @(posedge clk or posedge reset) begin
    if (reset) begin
        ring <= 4'b0001;
    end else begin
        ring <= {ring[2:0], ring[3]};
    end
end

endmodule
Output
10 ns: ring = 0001 20 ns: ring = 0010 30 ns: ring = 0100 40 ns: ring = 1000 50 ns: ring = 0001 60 ns: ring = 0010 70 ns: ring = 0100 80 ns: ring = 1000 90 ns: ring = 0001 100 ns: ring = 0010
⚠️

Common Pitfalls

Common mistakes include:

  • Not initializing the ring counter properly, causing it to stay at zero.
  • Using a simple shift without circular wrap, which loses the circulating '1'.
  • Forgetting to include reset in the sensitivity list, causing unpredictable startup.
verilog
/* Wrong: No circular shift, bit lost */
always @(posedge clk or posedge reset) begin
    if (reset) begin
        ring <= 4'b0001;
    end else begin
        ring <= ring << 1; // Shifts left but loses the leftmost bit
    end
end

/* Right: Circular shift keeps the '1' moving */
always @(posedge clk or posedge reset) begin
    if (reset) begin
        ring <= 4'b0001;
    end else begin
        ring <= {ring[2:0], ring[3]};
    end
end
📊

Quick Reference

ConceptDescription
reg [N-1:0] ringRegister vector holding the ring bits
resetInitializes ring with one bit set to 1
always @(posedge clk or posedge reset)Triggers on clock rising edge or reset
ring <= {ring[N-2:0], ring[N-1]}Circular left shift to rotate bits
OutputShows the circulating '1' bit

Key Takeaways

Initialize the ring counter with one bit set to 1 on reset.
Use circular shifting to rotate the '1' bit through the register.
Include reset in the sensitivity list for predictable startup.
Avoid simple shifts that lose the circulating bit.
A ring counter is a simple way to cycle a single active bit through multiple outputs.