1.什么是格雷码?
 对于做FPGA的来说,格雷码一般是用来定义状态机,有什么优势,我前面写的FSM中需注意事项一文中有提到。格雷码的特点:相邻的两个数之间只有一位不同。这就是格雷码存在的意义。
2.转换方法
 二进制转为格雷码方法有两个:方法1比较适用于笔试,考试等;方法二适用于代码编程,主要是为了做课程设计这类的。
方法一:递归法,我喊作:顺序逆序递归法
 1. 1位格雷码有2个码字:0和1
 2. (n+1)位格雷码中的前2^n(2的N次方)个字码等于n位格雷码的码字,按顺序书写,加前缀0.
3. (n+1)位格雷码中的后2^n(2的N次方)个字码等于n位格雷码的码字,但按逆序书写,加前缀1.
解释说明:

之所以称此方法为递归,是因为对于任意位的二进制的格雷码最终都将归结于1位二进制的格雷码的求解。上图就是根据已知的3bit二进制的格雷码,求4bit二进制的格雷码,此时的n为3,所以2^3=8,所以0-7 的格雷码为0+3bit格雷,8-15的格雷码为1+逆序3bit格雷码。
方法二:向左异或法
 1. 对n位二进制或格雷码的码字,将数位从右到左,从0到n-1编码。
 2. 如果二进制码字的第i位和第i+1位相同,则对应的格雷码码字的第i位为0,否则为1.
(当i+1=n,二进制码字的第n位被认为是0)
解释说明:
 就那四位二进制数4'b0010举例,二进制第0位为0,第1位为1,异或结果为1,所以格雷码的第0位为1;二进制第1位为1,第2位为0,异或为1,所以格雷码的第1位为1;二进制第2位为0,第3位为0,异或为0,所以格雷码的第2位为0;二进制的第3位为0,二进制没有第4位,所以第4位默认为0,异或为0,所以格雷码第3位为0。。。结果4'b0010的格雷码为0011。
verilog代码实现:
//pro : binary to gray
//data: 2014-04-23 kb129
//info: this is a pro exe that change the binary data to gray
module binary_gray(
 binary,
 gray
);
parameter n = 4;
input [n-1:0] binary;
output [n-1:0] gray;
reg [n-1:0] data_reg;
always@(binary)
begin
 data_reg[0] = binary[0]^binary[1];
 data_reg[1] = binary[1]^binary[2];
 data_reg[2] = binary[2]^binary[3];
 data_reg[3] = binary[3];
end
assign gray = data_reg;
endmodule
测试代码(testbench):
`timescale 1ns / 1ps
//Module Name: gray_tb.v
module gray_tb;
reg [3:0] binary;
wire [3:0] gray;
initial
begin
  binary = 0;
 #5  binary =4'b0001;
 #10 binary =4'b0010;
 #15 binary =4'b0011;
#20 binary =4'b0100;
#25 binary =4'b0101;
#30 binary =4'b0110;
 #35 binary =4'b0111;
 #40 binary =4'b1000;
 #45 binary =4'b1001;
 #50 binary =4'b1010;
 #55 binary =4'b1011;
 #60 binary =4'b1100;
 #65 binary =4'b1101;
 #70 binary =4'b1110;
 #75 binary =4'b1111;
 #80 binary =4'b1111;
end
binary_gray u_binary_gray(
 .binary(binary),
 .gray(gray)
);
endmodule
仿真结果:

3.解码实现
 解码的方法为编码中法二的逆过程,我称之为:向右异或法。
 360百科:最左边一位不变,从左边第二位起,将每一位与左边一位解码后的值进行异或。
值得注意的是:这里是同解码后的值异或。
解码代码:
//pro : gray to binary
//data: 2014-04-23 kb129
//info: this is a pro exe that change the gray data to binary
module binary_gray(
 binary,
 gray
);
parameter n = 4;
input [n-1:0] gray;
output [n-1:0] binary;
reg [n-1:0] data_reg;
always@(gray )
begin
 data_reg[3] = gray[3];
 data_reg[2] = gray[2]^data_reg[3];
 data_reg[1] = gray[1]^data_reg[2];
 data_reg[0] = gray[0]^data_reg[1];
end
assign binary = data_reg;
endmodule
测试代码(testbench):
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
//Engineer:LYC
//Create Date: 2014.4.23
//Module Name:gray_tb.v
////////////////////////////////////////////////////////////////////////////////
module gray_tb;
reg [3:0] gray;
wire [3:0] binary;
initial
 begin
 gray = 0;
 #5  gray =4'b0001;
 #10  gray =4'b0011;
 #15  gray =4'b0010;
 #20  gray =4'b0110;
 #25  gray =4'b0111;
 #30  gray =4'b0101;
#35  gray =4'b0100;
#40  gray =4'b1100;
 #45  gray =4'b1101;
#50  gray =4'b1111;
#55  gray =4'b1110;
 #60gray =4'b1010;
 #65  gray =4'b1011;
 #70  gray =4'b1001;
 #75  gray =4'b1000;
 #80  gray =4'b0000;
end
binary_gray u_binary_gray(
 .binary(binary),
 .gray(gray)
 );
endmodule
仿真结果:
