1、前言
格雷码和二进制码有所不同,它是一种无权码,其在一组数的编码中,任意两个相邻的数码之间只有一位二进制数不同。在硬件电路中,当许多位同时发生跳变时,大量晶体管会发生翻转,导致电路中可能出现很大的尖峰脉冲,从而导致数据不稳定。格雷码的编码特征可以有效避免亚稳态而导致数据变化发生错误。实际很多场合也用到格雷码。(比如用格雷码实现FIFO的读写指针)
下表展示了四位格雷码、四位二进制码以及十进制码的对应关系:
格雷码 | 二进制 | 十进制 |
0000 | 0000 | 0 |
0001 | 0001 | 1 |
0011 | 0010 | 2 |
0010 | 0011 | 3 |
0110 | 0100 | 4 |
0111 | 0101 | 5 |
0101 | 0110 | 6 |
0100 | 0111 | 7 |
1100 | 1000 | 8 |
1101 | 1001 | 9 |
1111 | 1010 | 10 |
1110 | 1011 | 11 |
1010 | 1100 | 12 |
1011 | 1101 | 13 |
1001 | 1110 | 14 |
1000 | 1111 | 15 |
可以看出相邻的格雷码只相差1bit。
2、二进制码转格雷码(bin2gray)
转换规则:
(1)最高位保持不变
(2)二进制码当前bit位与高一bit位进行异或得到当前bit位格雷码
即:
i < n-1
eg.
所以输入bin[10110] = gray [11101]
RTL代码实现:
a for循环实现
module bin2gray (
input [size - 1 : 0] bin,
output[size - 1 : 0] gray,
);
always@(*)
begin
parameter size = 4;
interger i ;
for(i=0;i<size-1;i=i+1)
begin
if(i=size-1)
gray[i] = bin[i];
else
gray[i] = bin[i+1] ^ bin[i];
end
end
b 移位寄存器实现
module bin2gray (
input [size - 1 : 0] bin,
output[size - 1 : 0] gray,
);
parameter size = 4;
assign gray = (bin >> 1) ^ bin ;
2、格雷码转二进制码(gray2bin)
转换规则:
(1)最高位保持不变
(2)当前bit位格雷码与二进制的高一bit位进行异或得到当前bit位二进制码
即
i < n-1
eg.
所以gray[11101] = bin[10110]
RTL代码实现:
for循环实现
module gray2bin(
input [size - 1 : 0] bin,
output[size - 1 : 0] gray,
);
always@(*)
begin
parameter size = 4;
interger i ;
for(i=0;i<size-1;i=i+1)
begin
if(i = size-1)
bin[i] = gray[i];
else
bin[i] = gray[i] ^ bin[i+1];
end
end
// or
module gray2bin(
input [size - 1 : 0] bin,
output[size - 1 : 0] gray,
);
always@(*)
begin
parameter size = 4;
interger i ;
for(i=0;i<size-1;i=i+1)
begin
bin[i] = ^[gray >> i];
end
end