數字設計---格雷碼與二進制碼


格雷碼與二進制碼

格雷碼

格雷碼是一種循環二進制碼或者叫作反射二進制碼。

格雷碼的特點是從一個數變為相鄰的一個數時,只有一個數據位發生跳變(或者說相鄰的兩個格雷碼之間只有一位不同)

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博客_二進制轉格雷碼
《硬件架構的藝術》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM