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
endmoduleExample
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
endmoduleOutput
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
resetin 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
| Concept | Description |
|---|---|
| reg [N-1:0] ring | Register vector holding the ring bits |
| reset | Initializes 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 |
| Output | Shows 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.