格雷码

格雷码(Gray code)是一个数列集合,相邻两数间只有一个位元改变,为无权数码,且格雷码的顺序不是唯一的。

传统的二进制系统例如数字3的表示法为011,要切换为邻近的数字4,也就是100时,装置中的三个位元都得要转换,因此于未完全转换的过程时装置会经历短暂的,010,001,101,110,111等其中数种状态,也就是代表着2、1、5、6、7,因此此种数字编码方法于邻近数字转换时有比较大的误差可能范围。格雷码的发明即是用来将误差之可能性缩减至最小,编码的方式定义为每个邻近数字都只相差一个位元,因此也称为最小差异码,可以使装置做数字步进时只更动最少的位元数以提高稳定性。

数字0~15的格雷码编码如下:

DecimalBinaryGray
000000000
100010001
200100011
300110010
401000110
501010111
601100101
701110100
810001100
910011101
1010101111
1110111110
1211001010
1311011011
1411101001
1511111000

二进制数据转格雷码公式

$G:$格雷码
$B:$二进制码
$n:$正在计算的位

$$ G(n) = B(n+1) \oplus B(n) $$

使用verilog描述如下:

module bin2gray #(
   parameter WIDTH=10
) (
  input  [WIDTH-1:0] bin_i,
  output [WIDTH-1:0] gray_o
);
  assign gray_o = bin_i ^ (bin_i>>1);
 
endmodule

格雷码转二进制数据公式

$G:$格雷码
$B:$二进制码
$n:$正在计算的位

$$ B(n) = B(n+1) \oplus G(n) $$

使用verilog描述如下:

module gray2bin #(
  parameter WIDTH=10
) (
  input  [WIDTH-1:0] gray_i,
  output [WIDTH-1:0] bin_o
);
  /*
  	assign bin_o[0] = gray_i[3] ^ gray_i[2] ^ gray_i[1] ^ gray_i[0];
  	assign bin_o[1] = gray_i[3] ^ gray_i[2] ^ gray_i[1];
  	assign bin_o[2] = gray_i[3] ^ gray_i[2];
  	assign bin_o[3] = gray_i[3];
  */
  genvar i;
  generate
    for(i=0;i<WIDTH;i++) begin
      assign bin_o[i] = ^(gray_i >> i);
    end
  endgenerate
endmodule