Verilog Implemented Gray Code to Binary Code Conversion

1. What is Gray Code

         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 Code

         The 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;


3. 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;
	for(i = 0; i <= N-2; i = i + 1) 
		begin: gray										//Need a name
			assign bin[i] = bin[i + 1] ^ gray[i];


4. 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>--------------------------------------------------------------------------------------------------------------------------------------
	.data_width	(data_width)
    .bin		(bin_in		),  	
	.gray		(gray		)		

	.data_width	(data_width)
    .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		
//Print Output
initial	$monitor("bin_in:%b,	gray:%b,	bin_out:%b",bin_in,gray,bin_out);


        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.






Tags: Verilog FPGA FIFO

Posted on Wed, 03 Nov 2021 12:05:27 -0400 by spellbinder