格雷碼原理與Verilog實現


格雷碼原理    

    格雷碼是一個叫弗蘭克*格雷的人在1953年發明的,最初用於通信。格雷碼是一種循環二進制碼或者叫作反射二進制碼。格雷碼的特點是從一個數變為相鄰的一個數時,只有一個數據位發生跳變,由於這種特點,就可以避免二進制編碼計數組合電路中出現的亞穩態。格雷碼常用於通信,FIFO或者RAM地址尋址計數器中。

    如二進制計數編碼從0到F的計數過程如下:

    

十進制

二進制

格雷碼

十進制

二進制

格雷碼

0

0000

0000

8

1000

1100

1

0001

0001

9

1001

1101

2

0010

0011

10

1010

1111

3

0011

0010

11

1011

1110

4

0100

0110

12

1100

1010

5

0101

0111

13

1101

1011

6

0110

0101

14

1110

1001

7

0111

0100

15

1111

1000

    當從7變為8時,4位二進制數都發生跳變,這就很可能會發生亞穩態。而采用格雷碼,就可以編碼4位二進制數都同時發生跳變,導致出現的亞穩態,就算出現亞穩態,最多也就一位出現錯誤。

格雷碼轉二進制

    觀察上表可知,格雷碼轉二進制是從左邊第二位起,將每位與左邊一位二進制碼的值異或,作為該位二進制碼后的值(最左邊一位依然不變)。

 

module gray_to_bin(

gray_in,

bin_out

);

parameter data_width = 4;

 

input [data_width-1:0] gray_in;

output [data_width-1:0] bin_out;

reg [data_width-1:0] bin_out;

always @(gray_in)

begin

bin_out[3] = gray_in[3];

bin_out[2] = gray_in[2]^bin_out[3];

bin_out[1] = gray_in[1]^bin_out[2];

bin_out[0] = gray_in[0]^bin_out[1];

end

endmodule

 

二進制轉格雷碼

    從最右邊一位起,依次將每一位與左邊一位異或(XOR),作為對應格雷碼該位的值,最左邊一位不變。

 

 

module bin_to_gray(

bin_in,

gray_out

);

parameter data_width = 4;

 

input [data_width-1:0] bin_in;

output [data_width-1:0] gray_out;

 

assign gray_out = (bin_in >> 1) ^ bin_in;

 

endmodule

 

格雷碼計數器原理

    格雷碼計數器,采用三個模塊進行設計,格雷碼轉二進制、加法器、二進制轉格雷碼。

格雷碼轉二進制將格雷碼轉換為二進制,並將值輸出用於加法器進行加法運算,然后將加法運算結果通過二進制轉格雷碼轉換為格雷碼,最后將格雷碼進行輸出,同時將結果輸出到格雷碼轉二進制作為輸入,形成一個計數功能。

 

頂層設計

module gray_counter(

clk,

reset_n,

// gray_in,

gray_out

);

parameter data_width = 4;

 

input clk;

input reset_n;

// input [data_width-1:0] gray_in;

output [data_width-1:0] gray_out;

 

//格雷碼轉二進制

wire [data_width-1:0] bin_out;

gray_to_bin gray_to_bin_1(

.gray_in (gray_wire),

.bin_out (bin_out)

);

//二進制加一

wire [data_width-1:0] bin_add_wire;

assign bin_add_wire = bin_out + 1'b1;

//二進制轉格雷碼

wire [data_width-1:0] gray_wire;

reg [data_width-1:0] gray_out;

bin_to_gray bin_to_gray_1(

.bin_in (bin_add_wire),

.gray_out (gray_wire)

);

 

always @(posedge clk or negedge reset_n)

begin

if(reset_n == 1'b0)

begin

gray_out <= {data_width{1'b0}};

end

else

begin

gray_out <= gray_wire;

end

end

endmodule

RTL視圖,與設計框圖一致

 

實驗結果

 

    經過與上表對比,驗證了功能的正確性。

 

大西瓜FPGA-->https://daxiguafpga.taobao.com

 

博客資料、代碼、圖片、文字等屬大西瓜FPGA所有,切勿用於商業! 若引用資料、代碼、圖片、文字等等請注明出處,謝謝!

 

每日推送不同科技解讀,原創深耕解讀當下科技,敬請關注微信公眾號“科乎”。


免責聲明!

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



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