0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for Gray Code Counter: Syntax and Example

A Gray code counter in Verilog is a sequential circuit that counts in Gray code, where only one bit changes at a time. You can implement it by converting a binary counter to Gray code using gray = binary ^ (binary >> 1) inside a clocked process.
📐

Syntax

The basic syntax for a Gray code counter in Verilog involves a binary counter and a conversion to Gray code. The key parts are:

  • reg [N-1:0] binary_count; - holds the binary count value.
  • wire [N-1:0] gray_count; - holds the Gray code output.
  • always @(posedge clk or posedge reset) - updates the binary count on clock edge or resets it.
  • gray_count = binary_count ^ (binary_count >> 1); - converts binary to Gray code.
verilog
module gray_counter(
    input wire clk,
    input wire reset,
    output reg [3:0] gray_count
);

    reg [3:0] binary_count;

    always @(posedge clk or posedge reset) begin
        if (reset)
            binary_count <= 4'b0000;
        else
            binary_count <= binary_count + 1;
    end

    always @(*) begin
        gray_count = binary_count ^ (binary_count >> 1);
    end

endmodule
💻

Example

This example shows a 4-bit Gray code counter that increments on each clock pulse and resets asynchronously. The output gray_count changes only one bit at a time, following Gray code sequence.

verilog
module gray_counter(
    input wire clk,
    input wire reset,
    output reg [3:0] gray_count
);

    reg [3:0] binary_count;

    always @(posedge clk or posedge reset) begin
        if (reset)
            binary_count <= 4'b0000;
        else
            binary_count <= binary_count + 1;
    end

    always @(*) begin
        gray_count = binary_count ^ (binary_count >> 1);
    end

endmodule

// Testbench to simulate the gray_counter
module tb_gray_counter();
    reg clk = 0;
    reg reset = 1;
    wire [3:0] gray_count;

    gray_counter uut(.clk(clk), .reset(reset), .gray_count(gray_count));

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

    initial begin
        #10 reset = 0; // release reset
        #100 $finish;
    end

    initial begin
        $monitor("Time=%0t binary_count in Gray code = %b", $time, gray_count);
    end
endmodule
Output
Time=10 binary_count in Gray code = 0000 Time=20 binary_count in Gray code = 0001 Time=30 binary_count in Gray code = 0011 Time=40 binary_count in Gray code = 0010 Time=50 binary_count in Gray code = 0110 Time=60 binary_count in Gray code = 0111 Time=70 binary_count in Gray code = 0101 Time=80 binary_count in Gray code = 0100 Time=90 binary_count in Gray code = 1100 Time=100 binary_count in Gray code = 1101
⚠️

Common Pitfalls

Common mistakes when writing a Gray code counter include:

  • Trying to increment Gray code directly instead of converting from binary.
  • Forgetting to reset the binary counter properly.
  • Using blocking assignments (=) inside clocked always blocks instead of non-blocking (<=).
  • Not handling asynchronous reset correctly.

Always increment a binary counter and then convert it to Gray code to ensure only one bit changes per count.

verilog
/* Wrong approach: incrementing Gray code directly (incorrect) */
/*
always @(posedge clk or posedge reset) begin
    if (reset)
        gray_count <= 4'b0000;
    else
        gray_count <= gray_count + 1; // This does not produce Gray code sequence
end
*/

/* Correct approach: increment binary counter and convert */
always @(posedge clk or posedge reset) begin
    if (reset)
        binary_count <= 4'b0000;
    else
        binary_count <= binary_count + 1;
end

always @(*) begin
    gray_count = binary_count ^ (binary_count >> 1);
end
📊

Quick Reference

Tips for writing a Gray code counter in Verilog:

  • Use a binary counter as the base.
  • Convert binary to Gray code with gray = binary ^ (binary >> 1).
  • Use non-blocking assignments (<=) in clocked always blocks.
  • Reset the binary counter asynchronously if needed.
  • Test with a simple testbench to verify the Gray code sequence.

Key Takeaways

Increment a binary counter and convert it to Gray code using XOR with shifted bits.
Use non-blocking assignments in clocked blocks and handle reset properly.
Gray code changes only one bit per count, reducing errors in hardware transitions.
Avoid incrementing Gray code directly; always convert from binary count.
Test your design with a testbench to verify correct Gray code output.