数字设计---格雷码与二进制码

格雷码与二进制码

格雷码

格雷码是一种循环二进制码或者叫作反射二进制码。

格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变(或者说相邻的两个格雷码之间只有一位不同)

img

从图上可以看出,相邻的二进制数会出现多位的变化(比如从15变到0就会有4位的变化),但对于格雷码来说,相邻的格雷码只有一位存在不同。

对于二进制数计数器来说,如果在跨时钟域的时候将计数器传到不同的时钟域,如果仅采用“打两拍的方法”,因为有多位数的变化,就可能会导致电路出现亚稳态或者出现毛刺。

由于格雷码的这种特点,采用格雷码就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码常用于通信,FIFO 或者 RAM 地址寻址计数器中。

格雷码与BCD码的转换

BCD码转格雷码

对于\(n\)位的二进制数,可以通过下面的式子转换为格雷码

\[gray_{n-1} = bin_{n-1} \]

\[gray_i = bin_i \oplus bin_{i+1} \qquad i<n-1 \]

即格雷码的最高位与二进制数的最高位相同,后面格雷码的各位等于相应的二进制码的对应位与上一位的异或。

img

从上图可以看出二进制码转换为格雷码的具体流程

拿5位二进制数10110举例

\(gray[4] = bin[4] = 1\)

\(gray[3] = bin[3] \oplus bin[4] = 1\)

\(gray[2] = bin[2] \oplus bin[3] = 1\)

\(gray[1] = bin[1] \oplus bin[2] =0\)

\(gray[0] = bin[0] \oplus bin[1] =1\)

对于verilog来说,我们可以将二进制数与他右移一位的数按位相异或来求得gray码。

module bin_to_gray
#(parameter WIDTH = 4)
( 
      input [WIDTH-1:0] bin_in, 
      output [WIDTH-1:0] gray_out
);
 //================================================================
 // ------------------------- MAIN CODE --------------------------
 //================================================================
 
    assign gray_out = (bin_in >> 1) ^ bin_in;        //右移一位再按位相异或
    // gray_out[0] = (bin_in[1]) ^ bin_in[0];        //当然可以分着来,就是没上面那么简洁
    // gray_out[1] = (bin_in[2]) ^ bin_in[1];
    // gray_out[2] = (bin_in[3]) ^ bin_in[2];
    // gray_out[3] = (bin_in[3]) ^ 0 ;
 
 endmodule

格雷码转BCD码

对于\(n\)位的格雷码,可以采用下面的式子转换为二进制码

\(bin_{n-1} = gray_{n-1}\)

\(bin_{i}=gray_{i}\oplus bin_{i+1}\)

即二进制码的最高位与格雷码的最高位相同,剩余位可以通过将对应位的格雷码与上一位的二进制码相异或求得

img

还是拿上图的5位格雷码10110举例

\(bin[4] = gray[4]=1\)

\(bin[3]=gray[3] \oplus bin[4] = gray[3] \oplus gray[4] =1\)

\(bin[2] = gray[2] \oplus bin[3] = gray[2] \oplus gray[3] \oplus gray[4] = 0\)

\(bin[1] = gray[1] \oplus bin[2] = gray[1] \oplus gray[2] \oplus gray[3] \oplus gray[4] = 1\)

\(bin[0] = gray[0] \oplus bin[1] = gray[0] \oplus gray[1] \oplus gray[2] \oplus gray[3] \oplus gray[4] = 1\)

从上面的分析可以看出格雷码转换为二进制,对应位的二进制可以通过求对应位格雷码及以上所有位的异或求得。

对于verilog实现来说,可以通过将格雷码右移相应位数,再求所有位的异或来实现上面的效果(求对应位格雷码及以上所有位的异或)。

module gray_to_bin
#(parameter WIDTH = 4)
( 
    input [WIDTH-1:0] gray_in, 
    output reg [WIDTH-1:0] bin_out
);
 
 //===================================================
 // ------------------- MAIN CODE -------------------
 //===================================================
integer i; 
 always @(*) begin
    for(i=0;i<WIDTH;i=i+1)
        bin_out[i] = ^(gray_in >> i);
 end
 
 endmodule

参考
(9条消息) 二进制与格雷码互相转换_耐心的小黑的博客-CSDN博客_二进制转格雷码
《硬件架构的艺术》

posted @ 2022-03-27 11:55  孤独野猪骑士  阅读(2089)  评论(0编辑  收藏  举报