格雷码计数器

简介

实现FIFO存储器读写指针比较好的方法就是使用格雷码计数器。格雷码计数器的优势在于其相邻两个数值之间只有一位发生变化,提高了系统的抗干扰能力,而且在计数时,各个输出的门电路翻转次数要远远小于二进制计数器,从而可以大幅度降低系统的功耗。

实现格雷码计数器的步骤如下:

  1. 将格雷值转换为二进制值。
  2. 根据条件递增二进制值。
  3. 将二进制值转换为格雷码
  4. 将计数器的最终格雷值保存到寄存器中。

gray

格雷码转二进制

格雷码转二进制的公式如下:

binngrayn1
bingrayibini+1

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

module gray_to_bin (gray,bin);

    parameter WIDTH = 8;

    input [WIDTH-1:0] gray;
    output [WIDTH-1:0] bin;
    wire [WIDTH-1:0] bin;

    assign bin[WIDTH-1] = gray[WIDTH-1];
    genvar i;
    generate
        for (i=WIDTH-2; i>=0; i=i-1)
            begin: gry_to_bin
                assign bin[i] = bin[i+1] ^ gray[i];
            end
    endgenerate

endmodule
二进制转格雷码

二进制转格雷码公式如下:

graynbinn1
graybinibini+1

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

module bin_to_gray (bin,gray);

    parameter WIDTH = 8;

    input [WIDTH-1:0] bin;
    output [WIDTH-1:0] gray;
    wire [WIDTH-1:0] gray;

    assign gray = bin ^ (bin >> 1);

endmodule
格雷码计数器

将四个步骤组合在一起(格雷码转二进制、加法器、二进制转格雷码、保存格雷码的寄存器)即可实现格雷码计数器,其Verlog代码如下:

module gray_counter(clk, rst_n, gray_dout);
    parameter WIDTH = 8;
    input clk;
    input rst_n;
    output [WIDTH-1:0] gray_dout;

    reg  [WIDTH-1:0] gray_dout;
    wire [WIDTH-1:0] gray_temp;
    wire [WIDTH-1:0] bin_dout;
    wire [WIDTH-1:0] bin_add;

    assign bin_add = bin_out + 1'b1;
    assign gray_temp = bin_add ^ (bin_add >> 1);

    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            gray_dout <= {WIDTH{1'b0}};
        else
            gray_dout <= gray_temp;
    end

    gray_to_bin gtb(.gray(gray_dout), .bin(bin_dout));
    defparam gtb .WIDTH = WIDTH;

endmodule

功能仿真结果如下:
rt

如果需要设计更加可靠快速的格雷码计数器,请参考Advanced Synthesis Cookbook





posted @ 2015-09-09 22:54  yfwblog  阅读(2602)  评论(0编辑  收藏  举报