Binary to Gray Code Conversion in Hardware
Gray code is commonly used in FIFO pointers due to its property that successive values differ by only one bit. This minimizes switching activity and enhances noise immunity compared to standard binary counters.
The conversion from binary to Gray code follows a simple rule: the most signifciant bit (MSB) remains unchanged, and each susbequent bit is derived by XORing the corresponding binary bit with the bit immediately to its left.
This relationship can be compactly expressed as:
gray = binary ^ (binary >> 1)
Below is a Verilog implementation of a Gray code counter that incremnets on each clock cycle when enabled:
module bin_to_gray_counter (
input clk,
input rst_n,
input increment,
output reg [7:0] gray_val
);
reg [7:0] binary_count;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
binary_count <= 8'h00;
else if (increment)
binary_count <= binary_count + 1'b1;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
gray_val <= 8'h00;
else
gray_val <= binary_count ^ (binary_count >> 1);
end
endmodule
A basic testbench to verify the module behavior:
module tb_bin_to_gray;
reg clk;
reg rst_n;
reg inc;
wire [7:0] gray_out;
bin_to_gray_counter uut (
.clk(clk),
.rst_n(rst_n),
.increment(inc),
.gray_val(gray_out)
);
initial clk = 0;
always #10 clk = ~clk;
initial begin
rst_n = 0;
inc = 0;
#22;
rst_n = 1;
#22;
inc = 1;
#500;
inc = 0;
#100;
$finish;
end
endmodule