trustintruth · 2020年06月10日

格雷码与格雷码计数器Verilog

最近在做项目中遇到了一个问题,首先我们知道信号的边缘不会像我们想要的那么陡峭,而且不会像我们想的一样准时到达。
作者:Trustintruth
来源:   https://zhuanlan.zhihu.com/p/130732799

那如果是在多位翻转时,各个信号到来时间也可能不同,所以我们的多位变化时会发生误码的概率大大增加,例如位宽为5的信号由11111到00000变化时有可能会是是这样

11111——11011——11010——10010——00010——00000

出于对稳定性的考虑,我们采用格雷码,尤其是在FSM的状态我们经常使用格雷码表示。

格雷码在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码反射码。

相对于二进制,格雷码转二进制可以使用公式来变换

根据公式设计出格雷码转二进制的译码器

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

同样二进制转格雷码也可以使用公式
610.jpg
二进制转化为格雷码的编码器设计

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

右上边的可以得到最终的设计——格雷码计数器

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

获取更多代码与资料,欢迎关注我啊!

推荐阅读

关注此系列,请关注专栏FPGA的逻辑
推荐阅读
关注数
10614
内容数
577
FPGA Logic 二三事
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息