1、什么是格雷码?
依次递增的连续格雷码只有一个比特位不一样,常用于异步FIFO的读写地址跨时钟,进行二进制格雷码间的相互转换以降低亚稳态发生概率,确保异步FIFO的功能正常。
十进制 | 二进制 | 格雷码 | 备注 |
0 | 000 | 000 | 只有1比特变化 |
1 | 001 | 001 | |
2 | 010 | 011 |
|
3 | 011 | 010 |
|
4 | 100 | 110 |
|
5 | 101 | 111 |
|
6 | 110 | 101 | 只有1比特变化 |
7 | 111 | 100 |
那么二进制与格雷码间的转换是如何实现的呢?
2、二进制转格雷码
二进制转格雷码: 数据左移1位,高位补0之后与原数据进行异或。
reg [5:0] data ;
reg [5:0]gray;
always@(posedge clk or negedge rst_n)
if(!rst_n)
gray=6'b0;
else
gray=data^{1'b0,data[5:1]};
3、格雷码转二进制
由gray[5:0]得到二进制data[5:0]
最高位不变:其他位为格雷码对应位以及高位的异或值。
二进制 | 表达式 | 说明 |
data[5] | gray[5] | 最高位不变 |
data[4] | gray[5]^gray[4] | 从最高位开始异或 |
data[3] | gray[5]^gray[4]^gray[3] | 从最高位开始异或 |
data[2] | gray[5]^gray[4]^gray[3]^gray[2] | 从最高位开始异或 |
data[1] | gray[5]^gray[4]^gray[3]^gray[2]^gray[1] | 从最高位开始异或 |
data[0] | gray[5]^gray[4]^gray[3]^gray[2]^gray[1]^gray[0] | 从最高位开始异或 |
Verilog实现代码如下:
function [5:0] gray2bin;
input [5:0]gray_in;
reg [5:0]gray_code;
reg [5:0]bin_code;
integer i,j;
reg tmp;
begin
gray_code=gray_in;
for(i=0;i<=5;i=i+1)
begin
tmp=1’b0;
for(j=i;j<=5;j=j+1)
tmp=gray_code^tmp;
bin_code[i]=tmp;
end
gray2bin=bin_code;
end
endfunction
assign data=gray2bin(gray_bin); //调用