简析

使用自然二进制码计数时,相邻数据之间可能会产生多bit的变化。比如,从011111110111\rightarrow1111,四个bit全部发生了变化。这会产生较大的尖峰电流以及其他问题。格雷码是一种相邻数据只有1bit变化的码制

十进制 自然二进制 格雷码
0 000 000
1 001 001
2 010 011
3 011 010
4 100 110
5 101 111
6 110 101
7 111 100

自然二进制码binary_codebinary\_code转换为格雷码gray_codegray\_code如下:

gray_code=binary_code(binary_code>>1)gray\_code = binary\_code \oplus (binary\_code>>1)

格雷码gray_codegray\_code转换为自然二进制码binary_codebinary\_code要复杂一些,以4bit码为例:

{binary_code3=gray_code3,binary_code2=gray_code2binary_code3=gray_code2gray_code3,binary_code1=gray_code1binary_code1=gray_code1gray_code2gray_code3,binary_code0=gray_code0binary_code0=gray_code0gray_code1gray_code2gray_code3\left\{ \begin{array}{lr} binary\_code_3=gray\_code_3, \\ binary\_code_2=gray\_code_2 \oplus binary\_code_3=gray\_code_2 \oplus gray\_code_3, \\ binary\_code_1=gray\_code_1 \oplus binary\_code_1=gray\_code_1 \oplus gray\_code_2 \oplus gray\_code_3, \\ binary\_code_0=gray\_code_0 \oplus binary\_code_0=gray\_code_0 \oplus gray\_code_1 \oplus gray\_code_2 \oplus gray\_code_3 \\ \end{array} \right.

最后一点,根据波形图,计数器两个周期变化一次。(2022.06.03更:题目已经修改,这个条件已经删除)

代码

`timescale 1ns/1ns

module gray_counter(
   input   clk,
   input   rst_n,

   output  reg [3:0] gray_out
);
    reg [3:0] binary_cnt;
    reg flag;
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            flag <= 0;
        else
            flag <= ~flag;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            binary_cnt <= 0;
        else
            binary_cnt <= flag? binary_cnt + 1: binary_cnt;
    end
    
    always@(*) begin
        gray_out = binary_cnt^(binary_cnt>>1);
    end
endmodule