Gray code is a cyclic binary code, or reflex binary code. Gray codes are characterized by a jump in only one data bit when changing from one number to an adjacent number. Because of this feature, metastable states in binary coded count combinational circuits can be avoided. Gray codes are often used in communication, FIFO, or RAM address addressing counters.
The following table gives the comparison of 4 bit natural binary code, 4 bit typical gray code (no special description, typical gray code) and 4 bit decimal integer:
You can see that the Gray Code in the table above has only one digit per change, which effectively avoids the possibility of metastable problems in the case of CDC (cross-clock domain). For example, when a number changes from 7 to 8, all 4-bit binary numbers jump. If these digital signals are sampled directly using an asynchronous clock, metastability or data sampling errors are likely to occur. Gray codes can avoid the simultaneous jump of 4-bit binary numbers, resulting in metastability, even if metastability occurs, at most one error will occur.
However, since Gray codes are variable weight codes, each bit code has no fixed size, so it is difficult to directly compare size and arithmetic operations.
2. Binary to Gray CodeThe principle of converting binary code to grey code is as follows:
The highest bit of the binary is the highest bit of the gray code, and the second-highest bit of the gray code is either different from or obtained from the second-highest bit of the binary, while the other bits are similar to the second-highest bit. The conversion process is as follows:
If it's 4bit binary data converted to Gray Code, then:
- gray[3] = 0 ^ bin[3];----gray[3] = bin[3] XOR 0 equals itself
- gray[2] = bin[3] ^ bin[2];
- gray[1] = bin[2] ^ bin[1];
- gray[0] = bin[1] ^ bin[0];
It is not difficult to deduce a general formula from the above formula: gray = (bin > > 1) ^ bin. Verilog code that converts binary code to gray code is easy to write according to the formula:
//Binary to Gray Code module bin2gray #( parameter data_width = 'd4 //Data Bit Width ) ( input [data_width - 1 : 0] bin , //Binary output [data_width - 1 : 0] gray //Gray Code ); assign gray = (bin >> 1) ^ bin; endmodule3. Gray code to binary
Gray codes are converted to binary codes by the following principles:
Using the highest bit of the gray code as the highest bit of the binary, the binary secondary high bit generation process uses the binary high and secondary high bit gray codes to be different or derived, and the values of other bits are similar to the secondary high bit generation process. The conversion process is as follows:
If a 4-bit Grey code is converted to binary, then:
- bin[3] = gray[3] ;
- bin[2] = gray[2] ^ bin[3];
- bin[1] = gray[1] ^ bin[2];
- bin[0] = gray[0] ^ bin[1];
You can see that the highest bit does not need to be converted, and binary high and low gray codes are different from or from the second highest bit, then generate--for can be used to construct a duplicate assignment with the following code:
//Gray code to binary module gray2bin #( parameter data_width = 'd4 //Data Bit Width ) ( input [data_width - 1 : 0] gray, //Gray Code output [data_width - 1 : 0] bin //Binary ); assign bin[data_width - 1] = gray[data_width - 1]; //Top Bit Direct Equality //From sub-high to 0, binary high and sub-high Grey codes differ or genvar i; generate for(i = 0; i <= N-2; i = i + 1) begin: gray //Need a name assign bin[i] = bin[i + 1] ^ gray[i]; end endgenerate endmodule4. Testing
Build a test script to test two modules: generate 4-bit binary data of 0-15, convert bin2gray to gray code, and observe the output of gray code; The converted gray code output is converted to binary code through gray2bin, and then the three sets of data are compared to see if they conform to the conversion rules.
`timescale 1ns/1ns //Time Unit/Precision //----------------<Module and Port Statement>-------------------------------------------------------------------------------------------------------------------------------- module gray_code(); parameter data_width = 'd4; //Data Bit Width reg [data_width - 1 : 0] bin_in; //Generated Binary Code wire [data_width - 1 : 0] gray; //Converted Gray Code wire [data_width - 1 : 0] bin_out; //Converted Binary Code //----------------<Instantiate tested modules>-------------------------------------------------------------------------------------------------------------------------------------- bin2gray #( .data_width (data_width) ) bin2gray_inst( .bin (bin_in ), .gray (gray ) ); gray2bin #( .data_width (data_width) ) gray2bin_inst( .bin (bin_out ), .gray (gray ) ); //---------------- <Set Initial Test Conditions>---------------------------------------------------------------------------------------------------------------------------- initial begin bin_in = 4'd0; forever #20 bin_in = bin_in + 1; // Add 1 every 20ns end //Print Output initial $monitor("bin_in:%b, gray:%b, bin_out:%b",bin_in,gray,bin_out); endmodule
The simulation results are as follows:
You can see that the results of both conversions are correct. Next, look at the output printed by the command window:
You can see that the result of this conversion is consistent with the reference table in Chapter 1.