1.什么是格雷码?
格雷码是由弗兰克·格雷于1953年发明的,最初是以发明专利的形式出现。格雷码的主要特点是相邻编码值中只有一个比特发生变化(任意两个相邻的代码只有一位二进制数不同),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。
在数字系统中,常要求代码按一定顺序变化。例如,按自然数递增计数,若采用8421码,则数0111变到1000时四位均要变化,而在实际电路中,4位的变化不可能绝对同时发生,则计数中可能出现短暂的其它代码(1100、1111等)。在特定情况下可能导致电路状态错误或输入错误。使用格雷码可以避免这种错误。(来源百度百科)
这些特点使得格雷码有着非常广泛的应用,比如在数字电路设计中被应用于两个不同时钟域的异步fifo中,此时单比特翻转的特性就变得极为重要,如下图所示(图片来源于verilog高级数字系统设计技术与实例分析)。
2.二进制转换为格雷码
2.1转换方法
保留二进制码的最高位作为格雷码的最高位,而次高位格雷码的值为二进制的高位与次高位想异或的结果。如下链接里面有更为直观的图片,便于理解:格雷码与二进制的转换_格雷码与二进制码的互转_探花郎K的博客-CSDN博客
2.2 二进制转格雷码代码和仿真设计
设计源码
module btgray#(parameter PTR = 8)(
input [PTR-1:0] binary_value,
output [PTR-1:0] gray_value
);
genvar i;
generate
for(i=0;i<(PTR-1);i=i+1) begin
assign gray_value[i] = binary_value[i]^binary_value[i+1];
end
endgenerate
assign gray_value[PTR-1] = binary_value[PTR-1];
endmodule
testbench编写
`timescale 1ns / 1ps
module tb_btgray( );
reg [7:0] binary_value;
wire [7:0] gray_value ;
initial begin
binary_value = 'b0;
#100;
binary_value = 8'b11001010;
end
btgray u_tbgray(
.binary_value(binary_value),
.gray_value(gray_value)
);
endmodule
仿真波形
3.格雷码转换为二进制
3.1转换方法
同样是保留格雷码的最高位作为二进制码的最高位,而次高位二进制码的值为高位二进制码与次高位格雷码异或的值。
3.2格雷码转二进制代码和仿真设计
设计源码
module graytb#(parameter PTR = 8)(
input [PTR-1:0] gray_value,
output [PTR-1:0] binary_value
);
genvar i;
generate
for(i=0;i<(PTR-1);i=i+1)
begin
assign binary_value[i] = binary_value[i+1]^gray_value[i];
end
endgenerate
assign binary_value[PTR-1] = gray_value[PTR-1];
endmodule
testbench编写
module tb_grayt();
reg [7:0] gray_value;
wire [7:0] binary_value;
initial begin
gray_value ='b0;
#100;
gray_value = 8'b10011100;
end
graytb u_graytb(
.gray_value(gray_value),
.binary_value(binary_value)
);
endmodule
仿真波形
参考文献:
verilog高级数字系统设计技术与实例分析