专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

verilog实现二进制和格雷码互转

作者:kb129   来源:kb129   点击数:  更新时间:2014年06月08日   【字体:

最近在看数电,看到了格雷码,阎石那本书介绍转换方法为:每一位的状态变化都按一定的顺序循环。不理解,然后在网上搜了下,蛮多人写怎么转换的。然后发现John的《数字设计原理与实践》(原书第四版)中讲了两个方法特别实用。

 

 

1.什么是格雷码?

      对于做FPGA的来说,格雷码一般是用来定义状态机,有什么优势,我前面写的FSM中需注意事项一文中有提到。格雷码的特点:相邻的两个数之间只有一位不同。这就是格雷码存在的意义。

2.转换方法

      二进制转为格雷码方法有两个:方法1比较适用于笔试,考试等;方法二适用于代码编程,主要是为了做课程设计这类的。

  方法一:递归法,我喊作:顺序逆序递归法

         1.  1位格雷码有2个码字:0和1

         2.  (n+1)位格雷码中的前2^n(2的N次方)个字码等于n位格雷码的码字,按顺序书写,加前缀0.

         3. (n+1)位格雷码中的后2^n(2的N次方)个字码等于n位格雷码的码字,但按逆序书写,加前缀1.

释说明:

之所以称此方法为递归,是因为对于任意位的二进制的格雷码最终都将归结于1位二进制的格雷码的求解。上图就是根据已知的3bit二进制的格雷码,求4bit二进制的格雷码,此时的n为3,所以2^3=8,所以0-7 的格雷码为0+3bit格雷,8-15的格雷码为1+逆序3bit格雷码。

   方法二:向左异或法

               1. 对n位二进制或格雷码的码字,将数位从右到左,从0到n-1编码。

               2. 如果二进制码字的第i位和第i+1位相同,则对应的格雷码码字的第i位为0,否则为1.

(当i+1=n,二进制码字的第n位被认为是0)

释说明:

     就那四位二进制数4'b0010举例,二进制第0位为0,第1位为1,异或结果为1,所以格雷码的第0位为1;二进制第1位为1,第2位为0,异或为1,所以格雷码的第1位为1;二进制第2位为0,第3位为0,异或为0,所以格雷码的第2位为0;二进制的第3位为0,二进制没有第4位,所以第4位默认为0,异或为0,所以格雷码第3位为0。。。结果4'b0010的格雷码为0011。

verilog代码实现:

//pro : binary to gray

//data: 2014-04-23 kb129
//info: this is a pro exe that change the binary data to gray
module
binary_gray(
    binary,

    gray

);


parameter n = 4;

inpu     [n-1:0]    binary;

output  [n-1:0  gray;

reg         [n-1:0]    data_reg;

always@(binary)
begin

        data_reg[0] = binary[0]^binary[1];

        data_reg[1] = binary[1]^binary[2];
        data_reg[2] = binary[2]^binary[3];
        data_reg[3] = binary[3];
end
assign gray = data_reg;

endmodule

测试代码(testbench):

`timescale 1ns / 1ps

//Module Name: gray_tb.v

module gray_tb;

reg [3:0] binary;

wire [3:0] gray;
initial

begin

             binary = 0;

    #5     binary =4'b0001;

   #10    binary =4'b0010;

   #15    binary =4'b0011;

   #20    binary =4'b0100;

   #25    binary =4'b0101;

   #30    binary =4'b0110;

   #35    binary =4'b0111;

   #40    binary =4'b1000;

   #45    binary =4'b1001;

   #50    binary =4'b1010;

   #55    binary =4'b1011;

   #60    binary =4'b1100;

   #65    binary =4'b1101;

   #70    binary =4'b1110;

   #75    binary =4'b1111;

   #80    binary =4'b1111;

end

binary_gray u_binary_gray(

   .binary(binary),

   .gray(gray)

);

endmodule

仿真结果


3.解码实

    码的方法为编码中法二的逆过程,我称之为:向右异或法。

     360百科:最左边一位不变,从左边第二位起,将每一位与左边一位解码后的值进行异或。

值得注意的是:这里是同解码后的值异或。

码代码:

//pro : gray to binary

//data: 2014-04-23 kb129

//info: this is a pro exe that change the gray data to binary

module binary_gray(
  
 binary,

    gray

);
 parameter n = 4;

 input     [n-1:0]   gray;

 output   [n-1:0]   binary;

 reg        [n-1:0]    data_reg;

always@(gray )

begin

        data_reg[3] = gray[3]; 

        data_reg[2] = gray[2]^data_reg[3];

        data_reg[1] = gray[1]^data_reg[2];

        data_reg[0] = gray[0]^data_reg[1]; 

end

assign binary = data_reg;

endmodule

测试代码(testbench):

`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
//Engineer:   LYC

//Create Date:   2014.4.23

//Module Name:  gray_tb.v

////////////////////////////////////////////////////////////////////////////////
module  gray_tb;

reg     [3:0]   gray;

wire    [3:0]   binary;

initial

       begin

                      gray = 0; 

           #5       gray =4'b0001;

           #10     gray =4'b0011;    

           #15     gray =4'b0010;     

           #20     gray =4'b0110;

           #25     gray =4'b0111;

           #30     gray =4'b0101;

           #35     gray =4'b0100;

           #40     gray =4'b1100;

           #45     gray =4'b1101;

           #50     gray =4'b1111;

           #55     gray =4'b1110;

           #60     gray =4'b1010;

           #65     gray =4'b1011;

           #70     gray =4'b1001;

           #75     gray =4'b1000;

           #80   gray =4'b0000;

end

binary_gray  u_binary_gray(

      .binary(binary),

      .gray(gray)

  ); 
endmodule

仿真结果





关闭窗口

相关文章