Gray code counters
While designing modules with asynchronous clock transfers, one may encounter the problem of transferring multi-bit data bus from one clock domain to another. To dual synchronize these bits and hope that all the bits are latched on the same clock is problematic. To eliminate this problem, we use Gray code counters where only one bit changes during each clock transition.
The most common Gray code is where the lower half of the sequence is exactly the mirror image of first half with only the MSB inverted. We illustrate the 3-bit binary Gray code as an example.
Gray code counter schematic (from Cliff Cumming's paper)
Gray code to equivalent binary conversion is simple and is as shown below
bin[2] = gray[2];
bin[1] = gray[2] ^ gray[1] (XOR function)
bin[0] = gray[2] ^ gray[1] ^ gray[0]
Verilog module is as below
-
module gray2binary_converter (binary, gray);
-
-
parameter NUM_BITS = 3;
-
output [NUM_BITS-1:0] binary;
-
input [NUM_BITS-1:0] gray;
-
-
reg [NUM_BITS-1:0] binary;
-
integer i;
-
-
always @(gray) begin
-
for (i=0; i<NUM_BITS; i=i+1)
-
binary[i] = ^(gray>> i); // Add padded 0's for the significant bits
-
end
-
-
endmodule
Similarly, the Binary to Gray conversion is achieved by
gray[2] = binary[3];
gray[1] = binary[2] ^ binary[1];
gray[0] = binary[0] ^ binary[1];
Verilog code is
-
module binary2gray_converter (gray, binary);
-
-
parameter NUM_BITS = 3;
-
output [NUM_BITS-1:0] gray;
-
input [NUM_BITS-1:0] binary;
-
-
assign gray = (binary>> 1) ^ binary; // Right shift binary vector and XOR
-
-
endmodule
The gray code counter can be implemented using these functions - please refer to Cliff Cumming's excellent paper on asynchronous clock domains.
Sphere: Related Content