精华内容
下载资源
问答
  • 格雷码,又叫循环二进制码或反射二进制码,格雷码是我们在工程中常会遇到的一种编码方式,它的基本的特点就是任意两个相邻的代码只有一位二进制数不同,这点在下面会详细讲解到。格雷码的基本特点就是任意两个相邻的...

    一、什么是格雷码

    格雷码,又叫循环二进制码或反射二进制码,格雷码是我们在工程中常会遇到的一种编码方式,它的基本的特点就是任意两个相邻的代码只有一位二进制数不同,这点在下面会详细讲解到。格雷码的基本特点就是任意两个相邻的代码只有一位二进制数不同,这点很重要。常用的二进制数与格雷码间的转换关系如下表:
    在这里插入图片描述

    二、二进制格雷码与自然二进制码的互换

    1、二进制码转换成二进制格雷码

    二进制码转换成二进制格雷码,其法则是保留二进制码的最高位作为格雷码的最高位,而次高位格雷码为二进制码的高位与次高位相异或,而格雷码其余各位与次高位的求法相类似。
    在这里插入图片描述
    verilog代码

    `timescale 1ns / 1ns
    module DecimaltoGray
    #(parameter width=5
    )
    (
    input wire clk,
    input wire rst_n,
    input wire decimal_load,
    input wire [width-1:0] decimal,
    output reg gray_finsh,
    output reg [width-1:0] gray
        );
    parameter [2:0]idle=3'd0;
    parameter [2:0]load_decimal=3'd1;
    parameter [2:0]finsh_gray=3'd2;
    
    reg [2:0] state;
        
    reg [width-1:0]decimal_reg1;
    
    always@(posedge clk or negedge rst_n) begin
      if(!rst_n)begin
        decimal_reg1<='d0;
        gray_finsh<=1'b0;
      end
      else if(decimal_load) begin
        decimal_reg1<=decimal;
        gray<={decimal[width-1],decimal[width-1:1]^decimal[width-2:0]};
        gray_finsh<=1'b1;
      end
      else begin
        gray_finsh<=1'b0;
        decimal_reg1<=decimal_reg1;
      end
    end
    
    endmodule
    

    仿真代码

    module graycode(
    
        );
    parameter width=5;
    reg clk;
    reg rst_n;
    reg [width-1:0] decimal;
    reg decimal_load;
    wire gray_finsh;
    wire [width-1:0] gray;
    initial begin
    clk<=1'b1;
    rst_n<=1'b1;
    #100
    rst_n<=1'b0;
    #100
    rst_n<=1'b1;
    #20
    decimal_load<=1'b0;
    decimal<=5'd1;
    #20
    decimal_load<=1'b0;
    decimal<=5'd0;
    #20
    decimal_load<=1'b1;
    decimal<=5'd1;
    #20
    decimal_load<=1'b0;
    decimal<=5'd0;
    #20
    decimal_load<=1'b1;
    decimal<=5'd2;
    #20
    decimal_load<=1'b0;
    decimal<=5'd0;
    #20
    decimal_load<=1'b1;
    decimal<=5'd3;
    #20
    decimal_load<=1'b0;
    decimal<=5'd0;
    #20
    decimal_load<=1'b1;
    decimal<=5'd4;
    #20
    decimal_load<=1'b0;
    decimal<=5'd0;
    #20
    decimal_load<=1'b1;
    decimal<=5'd5;
    #20
    decimal_load<=1'b0;
    decimal<=5'd0;
    #100
    $finish;
    
    end
    
    always #10 clk=~clk;
    
    DecimaltoGray 
    #(.width(width)
    )
    DecimaltoGray_inst(
    .clk(clk),
    .rst_n(rst_n),
    .decimal_load(decimal_load),
    .decimal(decimal),
    .gray_finsh(gray_finsh),
    .gray(gray)
    );
    
    endmodule
    

    仿真波形,使用vivado
    在这里插入图片描述

    2、二进制格雷码转换成二进制码

    二进制格雷码转换成二进制码,其法则是保留格雷码的最高位作为自然二进制码的最高位,而次高位自然二进制码为高位自然二进制码与次高位格雷码相异或,而自然二进制码的其余各位与次高位自然二进制码的求法相类似
    在这里插入图片描述

    verilog代码

    `timescale 1ns / 1ps
    module GraytoDecimal#(parameter width=5
    )
    (
    input wire clk,
    input wire rst_n,
    input wire gray_load,
    input wire [width-1:0] gray,
    output reg decimal_finsh,
    output reg [width-1:0] decimal
        );
        
    reg [7:0]cnt;
    parameter [2:0]idle=3'd0;
    parameter [2:0]load_decimal=3'd1;
    parameter [2:0]ing_gray=3'd2;
    parameter [2:0]finsh_gray=3'd3;
    reg [2:0] state;
    reg [width-1:0] gray_reg;
    reg [width-1:0] decimal_reg;
    
    
    always@(posedge clk or negedge rst_n) begin
      if(!rst_n)begin
      gray_reg<='d0;
      decimal_reg<='d0;
      cnt<=8'd0;
      state<=idle;
      decimal_finsh<=1'b0;
    end
    else begin
      case(state)
      idle: begin
        decimal_finsh<=1'b0;
        if(gray_load)begin
          gray_reg<=gray;
          state<=load_decimal;
        end
      end
      load_decimal:begin
      cnt<=width-2;
      state<=ing_gray;
      decimal_reg[width-1]<=gray_reg[width-1];
      end
      
      ing_gray:begin
      cnt<=cnt-1;
      decimal_reg[cnt]<=decimal_reg[cnt+1]^gray_reg[cnt];
      if(cnt==8'd0) begin
        state<=finsh_gray;
      end
      
      end
      finsh_gray:begin
        decimal<=decimal_reg;
        decimal_finsh<=1'b1;
        state<=idle;
      end
      
      default:begin
      state<=idle;
      
      end
      endcase
    end
    
    end
    
    endmodule
    

    仿真代码

    `timescale 1ns / 1ns
    module graycode(
    
        );
     parameter width=5;
    reg clk;
    reg rst_n;
    reg [width-1:0] gray;
    reg gray_load;
    wire decimal_finsh;
    wire [width-1:0] decimal;
    initial begin
    clk<=1'b1;
    rst_n<=1'b1;
    #100
    rst_n<=1'b0;
    #100
    rst_n<=1'b1;
    #20
    gray_load<=1'b1;
    gray<=5'd0;
    #20
    gray_load<=1'b0;
    gray<=5'd0;
    #200
    gray_load<=1'b1;
    gray<=5'd1;
    #20
    gray_load<=1'b0;
    gray<=5'd1;
    #200
    gray_load<=1'b1;
    gray<=5'd2;
    #20
    gray_load<=1'b0;
    gray<=5'd2;
    #200
    gray_load<=1'b1;
    gray<=5'd3;
    #20
    gray_load<=1'b0;
    gray<=5'd3;
    #200
    gray_load<=1'b1;
    gray<=5'd4;
    #20
    gray_load<=1'b0;
    gray<=5'd4;
    #200
    gray_load<=1'b1;
    gray<=5'd5;
    #20
    gray_load<=1'b0;
    gray<=5'd5;
    #500
    $finish;
    
    end
    
    always #10 clk=~clk;
    
    GraytoDecimal 
    #(.width(width)
    )
    GraytoDecimal_inst(
    .clk(clk),
    .rst_n(rst_n),
    .gray_load(gray_load),
    .gray(gray),
    .decimal_finsh(decimal_finsh),
    .decimal(decimal)
    );
    endmodule  
    

    vivado仿真波形
    在这里插入图片描述
    由于格雷码求二进制需要逐位计算,因此需要周期比较长,本代码使用了一个状态机进行改过程计算。

    展开全文
  • 四、 将格雷码转换为二进制 1. 将格雷码转换为二进制 2. 根据条件递增二进制值 3. 将二进制转换为格雷码 4. 将计数器的最终格雷码保存至寄存器中 四、由格雷码转换为二进制 公式 例:将格雷码转换为相等的二进制数 ...

    数字电路基础知识——格雷码和二进制码的转换的算法和Verilog实现

    关于数字电路中的码制问题在这篇博客中已经做了详细分析,
    数字电路基础知识——数字IC中的进制问题(原码,反码,补码以及各进制的转换)
    这篇博客会再次详细分析一下数字IC设计中关于 格雷码(Gray Code) 的问题,在数字IC设计中格雷码的使用范围很广,格雷码由于其误码率底的有点基本上每个模块都会使用到格雷码。
    近期在学习FIFO的时候碰到格雷码转换二进制码的问题。特此写这篇博客总结一下。

    一、什么是格雷码

    格雷码的每一位按照一定的顺序循环。如最右边的一位按照0110的顺序循环,右边第二位按照00111100的顺序循环。即自右向左0、1的循环数目翻倍。
    格雷码的最主要特点:各个相邻码之间仅有一位状态不同,首尾也是仅有一位状态不同。
    在这里插入图片描述

    二、为什么要用格雷码

    首先说下二进制码,在FIFO的设计中,在写请求中,写指针在写时钟作用下递增,在产生FIFO满信号时,需要将写指针和读指针进行比较,由于两个指针分别与其各自的时钟同步,但是彼此之间又是异步的关系,所以在使用二进制计数器实现指针的时候,就会出现比较的指针出现取样值错误的问题。
    如从FFF到000可能会进行如下的转换
    在这里插入图片描述
    如果此时同步时钟边沿在FFF向000转换的时候,就可能会把上面的的三位二进制数的任何取样值同步到新的时钟域,导致数据错误。
    所以采取的办法通常是使用格雷码计数
    在这里插入图片描述
    格雷码的优势在于一个数变为另一个数时,只有一位发生变化。

    三、用格雷码实现FIFO指针

    在这里插入图片描述
    如果要产生完美的FIFO空或满条件,首先需要正确的读写指针,在时钟域传递指针的最好的办法就是使用格雷码来实现指针,这种编码能够消除绝大数错误。上面是格雷码的设计流程。

    1. 将格雷码转换为二进制
    2. 根据条件递增二进制值
    3. 将二进制转换为格雷码
    4. 将计数器的最终格雷码保存至寄存器中
    四、由格雷码转换为二进制
    1. 公式
      格雷码的转换公式:(i < n-1)
      在这里插入图片描述
      计数器的位编号如下:
      MSB: Most Significant Bit的缩写,指最高有效位
      LSB: Least Significant Bit,指最低有效位
      在这里插入图片描述
    2. 例:将格雷码转换为相等的二进制数(@表示异或xor)
      i = 3,
      bin3=gray3 = gray[3] = 1
      i = 2,
      bin2 = gray2 @ bin3 = gray2 @ gray3 = gray[2] @ gray[3] = 1
      i = 1,
      bin1 = gray1 @ bin2 = gray1 @ gray2 @ gray3 = gray[1] @gray[2] @gray[3] = 0
      i = 0,
      bin0 = gray0 @ bin1 = gray0 @ gray1 @ gray2 @ gray3 = gray[0] @ gray[1] @ gray[2] @ gray[3] =0
      于是可以得到如下四个等式:
      在这里插入图片描述
    3. Verilog 语言描述格雷码转换为二进制码
    module gray_to_bin (bin, gray);
    parameter SIZE = 4;
    input [SIZE – 1:0] bin;
    output [SIZE – 1:0] gray;
    reg [SIZE – 1:10] bin;
    integer i;
    always @ (gray)
    for ( i = 0; i <= SIZE; i = i + 1)
    bin[i] = ^(gray >> i);  		//右移一位并按位异或
    endmodule
    
    五、由二进制码转换为格雷码
    1. 公式
      二进制向格雷码的转换公式:(i < n-1)
      在这里插入图片描述
    2. 例:将二进制转换为相等的格雷码(@表示异或xor)
      i = 3,
      gray3 = bin3 = bin[3] = 1
      i = 2,
      gray2 = bin2 @ bin3 = bin[2] @ bin[3] = 0
      i = 1,
      gray1 = bin1 @ bin2 = bin[1] @ bin[2] = 1
      i = 0,
      gray0 = bin0 @ bin1 = bin[0] @ bin[1] = 0
      于是可以得到如下四个等式:
      在这里插入图片描述
      由上式可以看出,通过逐位异或,或者将二进制码右移后与自己异或的操作方式,计算相应的格雷码,如下
      在这里插入图片描述
    3. Verilog 语言描述二进制码转换为格雷码
    module bin_to_gray (bin, gray);
    parameter SIZE = 4;
    input [SIZE-1:0] bin;
    output [SIZE-1:0] gray;
    assign gray = (bin >> 1) ^ bin;			//右移与自己异或
    endmodule
    
    六、格雷码计数逻辑的实现

    由格雷码实现FIFO指针的流程图发现

    module gray_ counter (clk, gray, inr, reset_n)
    	parameter SIZE = 4;
    	input clk, inr, reset_n;t
    	output [SIZE -1 ] gray;
    	reg [SIZE]1 ] gray_temp, gray, bin_temp, bin;
    	integer i;
    	
    	always @ (gray or inr)
    	begin:gray_bin_gray
    		for (i = 0; i<SIZE ; 1 = i +1)
    		bin[i] = ^(gray >> i); // gray to binary conversion
    		bin_temp = bin + inr; // addition in binary
    		gray_temp = bin_temp >> 1) ^ bin_temp; // binary to gray conversion
    	end
    endmodule
    

    下面的逻辑快将转换后的格雷码值寄存起来

    always @ (posedge clk or negedge reset_n)
    begin:gray_registered
    if (~reset_n)
    	gray <= {SIZE {1’b0}};
    else
    	gray <= gray_temp;
    end
    

    下图显示格雷码计数器的逻辑原理图:

    展开全文
  • verilog实现格雷码二进制的转化

    千次阅读 2018-09-27 18:59:52
    verilog实现格雷码二进制的转化:  1)自然二进制码转换为格雷码的方法  自然二进制码转换成二进制格雷码,其法则是保留自然二进制码的最高位作为格雷码的最高位,而次高位格雷码二进制码的高位与次高 位相...

    verilog实现格雷码与二进制的转化:

        1)自然二进制码转换为格雷码的方法

            自然二进制码转换成二进制格雷码,其法则是保留自然二进制码的最高位作为格雷码的最高位,而次高位格雷码为二进制码的高位与次高    位相异或,而格雷码其余各位与次高位的求法相类似。     

        原理: 若二进制码表示为: B[N-1]B[N-2]...B[2]B[1]B[0];

             相应地, 则二进制格雷码表示为: G[N-1]G[N-2]...G[2]G[1]G[0].

             其中最高位保留: G[N-1] = B[N-1];

             其他各位: G[i] = B[i+1] xor B[i]. (i = 0, 1, 2, ..., n-2)

        图示如下:

           

     

                bin[3]    bin[2]     bin[1]      bin[0]          ---二进制值 : 二进制

             +     0     bin[3]     bin[2]      bin[1]          ---右移值(二进制)


              gray[3]  gray[2]    gray[1]    gray[0]      ---对应的格雷码值

    总结:格雷码的值只需要在原来的二进制的基础上右移一位再异或原来的二进制值即可得到。

    module  binary2grey #(
            parameter   N       =       4
    )(
            input         [N-1: 0]   binary                 ,
            output  wire  [N-1: 0]   grey
    );
    //=====================================================================\
    // ********** Define Parameter and Internal Signals *************
    //=====================================================================/
    
    
    //======================================================================
    // ***************      Main    Code    ****************
    //======================================================================
    assign  grey    =       {1'b0,binary[N-1:1]}^binary;
    
    
    endmodule
    

     2)格雷码转换为二进制码的实现方法

             二进制格雷码转换成自然二进制码,其法则是保留格雷码的最高位作为自然二进制码的最高位,而次高位自然二进制码为高位自然二进制       码与次高位格雷码相异或,而自然二进制码的其余各位与次高位自然二进制码的求法相类似。      

        原理: 若二进制格雷码表示为: G[N-1]G[N-2]...G[2]G[1]G[0];

             相应地, 则二进制码表示为: B[N-1]B[N-2]...B[2]B[1]B[0].

             其中最高位保留: B[N-1] = G[N-1];

             其他各位: B[i-1] = G[i-1] xor B[i]. (i = 1, 2, ..., n-1)

        图示如下:

      

    module  grey2binary #(
            parameter   N       =       4
    )(
            input         [N-1: 0]   grey                   ,
            output  wire  [N-1: 0]   binary
    );
    //=====================================================================\
    // ********** Define Parameter and Internal Signals *************
    //=====================================================================/
    
    
    
    //======================================================================
    // ***************      Main    Code    ****************
    //======================================================================
    assign  binary[N-1]     =       grey[N-1];
    
    generate
    genvar  i;
        for(i=0;i<N-1;i=i+1) begin:b2g
            assign  binary[i]     =       grey[i]^binary[i+1];
        end
    endgenerate
    
    
    endmodule
    

     

    展开全文
  • 格雷码转二进制二进制转格雷码 代码如下 //gray to bin module gray2bin #(parameter ADDR_WIDTH=8)( input [ADDR_WIDTH-1:0] grayin, output [ADDR_WIDTH-1:0] binout, output reg [ADDR_WIDTH-1:0] ...

    格雷码转二进制码
    二进制码转格雷码
    代码如下

    
    //gray to bin 
    
    module gray2bin #(parameter ADDR_WIDTH=8)(
    	input [ADDR_WIDTH-1:0] grayin,
    	output [ADDR_WIDTH-1:0] binout,
    	output reg [ADDR_WIDTH-1:0] binout1,
    	output [ADDR_WIDTH-1:0] grayout
    	);
    	
    //调用gray2bin实现方式2的函数
    assign binout=gray2bin(grayin);
    
    gray2bin 实现方式1:always组合逻辑块
    integer j;
    always@(*)
    	for(j=0;j<ADDR_WIDTH;j=j+1)
    		binout1[j]= ^(grayin>>j);
    
    //gray2bin  实现方式2:function组合逻辑块
    function  [ADDR_WIDTH-1:0] gray2bin ( input [ADDR_WIDTH-1:0] gray);
    reg [31:0] i;
    for(i=0; i<ADDR_WIDTH;i=i+1)
    	gray2bin[i]=^(gray>> i);
    endfunction
    	
    //二进制转格雷码
    assign grayout=binout1^(binout1>>1);
    
    endmodule
    

    tb(sv)如下

    parameter ADDR_WIDTH=4;
    class datarand;
        rand bit [ADDR_WIDTH-1:0] data;
    endclass
    
    module tb_gray2bin(  );
    logic [ADDR_WIDTH-1:0] grayin,grayout, binout, binout1;
    
    gray2bin #(.ADDR_WIDTH(ADDR_WIDTH)) gray2bin(
        .grayin(grayin),
        .binout(binout),
        .binout1(binout1),
        .grayout(grayout)
        );
    datarand dr;
    integer k;
    initial
        begin
        dr=new();
        for(k=0;k<30;k=k+1)
        begin
        #10
        assert(dr.randomize());
        grayin=dr.data;
        end
        end
    
    endmodule
    
    展开全文
  • verilog实现格雷码二进制的转化:

    千次阅读 2019-04-08 20:46:31
    verilog实现格雷码二进制的转化: 1)自然二进制码转换为格雷码的方法 自然二进制码转换成二进制格雷码,其法则是保留自然二进制码的最高位作为格雷码的最高位,而次高位格雷码二进制码的高位与次高 位相异或...
  • 2 实现格雷码二进制码的相互转换 Verilog代码(用一个函数实现): // 定义函数 完成 二进制格雷码的相互转换 function [WIDTH:0] data_out(input op, input [WIDTH:0] data_in); integer i; begin if(op ...
  • 下图是格雷码转二进制 下面是二进制转格雷码
  • 文章目录边沿检测思路代码总结格雷码二进制码的转换思路代码总结 边沿检测 实现信号边沿检测功能,输出一个周期宽度的脉冲信号 思路 边沿的两侧信号是相反的。 上升沿 = ~res[0] && res[1] 下降沿 = res[0...
  • 格雷码二进制码的互换—算法与硬件实现 采用软件及硬件Verilog的两种方法转换,有兴趣可以了解一下
  • 二进制码和格雷码之间的转换 一、二进制码与格雷码转换原理 (1)二进制码转换格雷码 二进制码 Bi Bi-1 Bi-2 ... B1 B0 ^ ^ ^ ^ ^ 0 Bi Bi-1 ... B2 B1 格雷码 Gi Gi-1 Gi-2 ... G
  • 对于格雷码,相邻的两个数间只有一个bit是不一样的(格雷码,在本文中不作详细介绍),如果先将RAM的写地址转为格雷码,然后再将写地址的格雷码进行打两拍,之后再在RAM的读时钟域将格雷码恢复成10进制。这种处理就...
  • 二进制格雷码转换verilog实现

    千次阅读 2018-05-13 09:57:19
    依次递增的连续格雷码只有一个比特位不一样,常用于异步FIFO的读写地址跨时钟,进行二进制格雷码间的相互转换以降低亚稳态发生概率,确保异步FIFO的功能正常。十进制 二进制 格雷码 备注 0 000 000 只有1比特变化 1 ...
  • 格雷码是一种循环二进制码或者叫作反射二进制码。格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变,由于这种特点,就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码常用于通信,FIFO ...
  • 格雷码是一种循环二进制码或者叫作反射二进制码。格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变,由于这种特点,就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码常用于通信,FIFO或者...
  • (1)二进制转格雷码: 原数右移一位再与原数异或 (2)格雷码转二进制二进制最高位取格雷码最高位,然后循环做二进制高位与低一位的格雷码异或 verilog代码 module GRAY_tb(); // 定义函数 完成 二进制格雷码...
  • 3)二进制转格雷码原理 4)FPGA简介 5)二进制转格雷码代码 6)结束语 1 格雷码简介 格雷码是一个叫弗兰克*格雷的人在1953年发明的,最初用于通信。格雷码是一种循环二进制码或者叫作反射二进制码。格雷码的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 679
精华内容 271
关键字:

格雷码转二进制verilog