格雷碼原理
格雷碼是一個叫弗蘭克*格雷的人在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所有,切勿用於商業! 若引用資料、代碼、圖片、文字等等請注明出處,謝謝!
每日推送不同科技解讀,原創深耕解讀當下科技,敬請關注微信公眾號“科乎”。

