二进制码与格雷码的相互转换原理与Verilog实现

一、写在前面

  二进制码是一种基于二进制数系统的编码方式,使用 0 和 1 两个数字来表示数字信号。例如,数字 7 在二进制码中表示为0111。
  而格雷码是一种二进制反射码,也称为格雷反码。格雷码中的相邻两个码位只有一个位的变化,可以减少数字信号传输过程中的传输错误率。例如,数字 7 在格雷码中表示为 0100。
  在数字电路中,格雷码的编码方式可以大大简化电路的设计。由于相邻两个码位只有一个位的变化,因此在使用格雷码编码时,只需要使用异或门就可以实现数字信号的编码和解码。而使用二进制码进行编码时,需要使用更多的逻辑门才能实现编码和解码。

二、二进制码与格雷码的相互转换

2.1 二进制码转格雷码原理

  假设n比特的二进制码为 B n − 1 B n − 2 . . . B 1 B 0 B_{n-1}B_{n-2}...B_1B_0 Bn1Bn2...B1B0,而转换后的n比特格雷码为 G n − 1 G n − 2 . . . G 1 G 0 G_{n-1}G_{n-2}...G_1G_0 Gn1Gn2...G1G0,二进制码转格雷码的法则如下:格雷码的最高位等于二进制码的最高位,而格雷码得次高位等于二进制码的最高位与二进制码次高位的异或结果,格雷码的其他位与次高位的求法相类似。
G n − 1 = B n − 1 G i = B i + 1 ⊕ B i \begin{matrix} G_{n-1}=B_{n-1} \\ \\G_{i}=B_{i+1}\oplus B_{i} \end{matrix} Gn1=Bn1Gi=Bi+1Bi
  以4比特的二进制码转格雷码为例,如下图所示。

在这里插入图片描述

2.2 异或运算的特性

  在《数字电子技术基础》中,我们学过异或运算,异或运算有一点特性很重要。如果 A ⊕ B = C A \oplus B=C AB=C,则 A ⊕ C = B A \oplus C=B AC=B B ⊕ C = A B \oplus C=A BC=A,如下图所示。

在这里插入图片描述

2.3 格雷码转二进制码原理

  那么,根据异或运算的特性,我们可以对二进制转格雷码的法则进行变化,得到格雷码转二进制的公式,如下:
B n − 1 = G n − 1 B i = B i + 1 ⊕ G i \begin{matrix} B_{n-1}=G_{n-1} \\ \\B_{i}=B_{i+1}\oplus G_{i} \end{matrix} Bn1=Gn1Bi=Bi+1Gi
  即二进制码的最高位等于格雷码的最高位,而二进制码的次高位等于二进制码的最高位与格雷码的次高位异或结果。而二进制码的其他位与二进制码的次高位求法相似。
  以4比特的格雷码转二进制码为例,如下图所示。

在这里插入图片描述

三、二进制码与格雷码相互转换的Verilog实现

  根据上述的二进制码转格雷码与格雷码转二进制码的原理,可以编写Verilog代码,如下。

module BinaryGrayConvert
#(
  parameter DATA_WIDTH  = 8 //二进制码/格雷码位宽
)
(
  input		[DATA_WIDTH-1:0]		binary_in , //二进制码输入
  input		[DATA_WIDTH-1:0]		gray_in   , //格雷码输入
  output	[DATA_WIDTH-1:0]		binary_out, //二进制码输出
  output	[DATA_WIDTH-1:0]		gray_out    //格雷码输出
);

//二进制码转格雷码
assign gray_out = binary_in ^ (binary_in>>1);

//格雷码转二进制码
genvar i;
generate
  for(i=0;i<DATA_WIDTH;i=i+1) begin:gray2binary
    if(i==DATA_WIDTH-1)
	  assign binary_out[i] = gray_in[i];
	else
	  assign binary_out[i] = binary_out[i+1] ^ gray_in[i];
  end
endgenerate

endmodule

四、仿真验证

  对该二进制码与格雷码的相互转换模块编写TestBench进行仿真。

`timescale 1ns/1ns	//时间单位/精度

module tb_BinaryGrayConvert();

parameter DATA_WIDTH  = 8;

reg     clk,rst_n;
reg 	[DATA_WIDTH-1:0]		binary_in ; //二进制码输入
reg 	[DATA_WIDTH-1:0]		gray_in   ; //格雷码输入
wire	[DATA_WIDTH-1:0]		binary_out; //二进制码输出
wire	[DATA_WIDTH-1:0]		gray_out  ; //格雷码输出

initial begin
  clk = 1'b0;
  rst_n <= 1'b0;
  #20 
  rst_n <= 1'b1;
end

always #10 clk = ~clk;

always @(posedge clk or negedge rst_n)
  if(!rst_n) begin
    binary_in <= 8'b0000_0000;
    gray_in <= 8'b0000_0000;	
  end
  else begin
    binary_in <= binary_in + 1'b1;
    gray_in <= gray_in + 1'b1;	
  end
    
BinaryGrayConvert
#(
  .DATA_WIDTH(DATA_WIDTH) //二进制码/格雷码位宽
)
BinaryGrayConvert_inst
(
  .binary_in (binary_in ), //二进制码输入
  .gray_in   (gray_in   ), //格雷码输入
  .binary_out(binary_out), //二进制码输出
  .gray_out  (gray_out  )  //格雷码输出
);

endmodule

  仿真结果如下图所示,观察波形,以 ( 00000101 ) B i n a r y − > ( 00000111 ) G r a y (00000101)_{Binary} -> (00000111)_{Gray} (00000101)Binary>(00000111)Gray ( 00000101 ) G r a y − > ( 00000110 ) B i n a r y (00000101)_{Gray} -> (00000110)_{Binary} (00000101)Gray>(00000110)Binary为例,可见转换正确,符合我们预期实现的二进制码与格雷码的相互转换。

在这里插入图片描述

五、写在后面

  在本文中,我们学习了二进制码与格雷码相互转换的原理,并使用Verilog实现,同时编写TestBench文件对其进行仿真,验证模块的正确性。如果有疑义的地方欢迎评论区友好探讨学习!!!!!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值