在一組數的編碼中,若任意兩個相鄰的代碼只有一位二進制數不同,則稱這種編碼為格雷碼(Gray Code),另外由於最大數與最小數之間也僅一位數不同,即“首尾相連”,因此又稱循環碼或反射碼。
二進制碼→格雷碼(編碼):
此方法從對應的n位二進制碼字中直接得到n位格雷碼碼字,步驟如下:
-
對n位二進制的碼字,從右到左,以0到n-1編號
例如:二進制碼0101,為4位數,所以其所轉為之格雷碼也必為4位數,因此可取轉成之二進位碼第五位為0,即0 b3 b2 b1 b0。
0 xor 0=0,所以g3=0
0 xor 1=1,所以g2=1
1 xor 0=1,所以g1=1
0 xor 1=1,所以g0=1
因此所轉換為之格雷碼為0111
|
格雷碼
→
二進制碼(解碼):
從左邊第二位起,將每位與左邊一位解碼后的值異或,作為該位解碼后的值(最左邊一位依然不變)。依次異或,直到最低位。依次異或轉換后的值(二進制數)就是格雷碼轉換后二進制碼的值。
公式表示:
(G:格雷碼,B:二進制碼)

原碼:p[n:0];
格雷碼:c[n:0](n∈N);編碼:c=G(p);解碼:p=F(c);
書寫時按從左向右標號依次減小,即MSB->LSB,編解碼也按此順序進行
舉例:
如果采集器器采到了
格雷碼:1010
就要將它變為自然二進制:
0 與第四位 1 進行異或結果為 1
上面結果1與第三位0異或結果為 1
上面結果1與第二位1異或結果為 0
上面結果0與第一位0異或結果為 0
因此最終結果為:1100 這就是二進制碼即十進制 12
|
轉換不是太難:
一、二進制碼轉換成格雷碼:
程序:

/********************************Copyright************************************** **----------------------------File information-------------------------- ** File name :bintogry.v ** CreateDate :2015.04 ** Funtions :二進制轉格雷碼 ** Operate on :M5C06N3L114C7 ** Copyright :All rights reserved. ** Version :V1.0 **---------------------------Modify the file information---------------- ** Modified by : ** Modified data : ** Modify Content: *******************************************************************************/ module bintogry ( clk, rst_n, databin, datagry ); localparam width = 4; input clk; input rst_n; input [width-1:0] databin; output [width-1:0] datagry; reg [width-1:0] datagry; //---------------------- reg [width:0] databin_1; /* 輸入數據寄存器,擴展多一位 */ always @(posedge clk or negedge rst_n) begin if(!rst_n) begin databin_1 <= 0; end else begin databin_1[width-1:0] <= databin; /* 寄存下 */ end end //--------------------------- reg [2:0] state; reg [width-1:0] n; reg switchover; reg [width-1:0] datagry_1; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin state <= 0; n <= 0; switchover <= 0; datagry_1 <= 'd0; end else begin case(state) 'd0: begin n <= 0; datagry_1 <= 'd0; if(databin_1[width-1:0]!= databin) state <= 'd1; else state <= 'd0; end 'd1: begin datagry_1[width-1-n] <= databin_1[width-n]^databin_1[width-1-n]; /* 當前位與左邊一位異或 */ state <= 'd2; end 'd2: begin if(n==(width-1)) begin n <= 0; state <= 'd3; switchover <= 1; end else begin n <= n + 1; state <= 'd1; end end 'd3: begin switchover <= 0; state <= 'd0; end default:state <= 'd0; endcase end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin datagry <= 'd0; end else if(switchover) datagry <= datagry_1; else datagry <= datagry; end endmodule
測試程序;

/********************************Copyright************************************** **----------------------------File information-------------------------- ** File name :bintogry_tb.v ** CreateDate :2015.04 ** Funtions : 測試 ** Operate on :M5C06N3L114C7 ** Copyright :All rights reserved. ** Version :V1.0 **---------------------------Modify the file information---------------- ** Modified by : ** Modified data : ** Modify Content: *******************************************************************************/ module bintogry_tb; parameter width = 4; reg clk; reg rst_n; reg [width-1:0] databin; wire [width-1:0] datagry; bintogry bintogry_1 ( .clk, .rst_n, .databin, .datagry ); parameter tck = 24; parameter t = 1000/tck; always #(t/2) clk = ~clk; initial begin clk = 0; rst_n = 0; databin = 0; #(20*t) rst_n = 1; #(20*t) databin = 1; #(20*t) databin = 2; #(20*t) databin = 3; #(20*t) databin = 4; end endmodule
仿真圖:
格雷碼轉換成二進制碼:
程序:

/********************************Copyright************************************** **----------------------------File information-------------------------- ** File name :grytobin.v ** CreateDate :2015.04 ** Funtions :將格雷碼轉化為二進制碼 ** Operate on :M5C06N3L114C7 ** Copyright :All rights reserved. ** Version :V1.0 **---------------------------Modify the file information---------------- ** Modified by : ** Modified data : ** Modify Content: *******************************************************************************/ module grytobin ( clk, rst_n, gry, bin ); localparam width = 4; input clk; input rst_n; input [width-1:0] gry; output [width-1:0] bin; reg [width-1:0] bin; //--------------------------- reg [width-1:0] gry_1; /* 寄存輸入值 */ always @(posedge clk or negedge rst_n) begin if(!rst_n) begin gry_1 <= 'd0; end else begin gry_1 <= gry; end end //-------------------------- reg [2:0] state; reg [width-1:0] n; reg switchover; reg [width:0] bin_1; /* 擴展一位 */ always @(posedge clk or negedge rst_n) begin if(!rst_n) begin state <= 0; n <= 0; switchover <= 0; bin_1 <= 'd0; end else begin case(state) 'd0: begin n <= 0; bin_1 <= 'd0; if(gry_1[width-1:0]!= gry) state <= 'd1; else state <= 'd0; end 'd1: begin bin_1[width-1-n] <= bin_1[width-n]^gry_1[width-1-n]; /* 當前位與上次運算結果異或 */ state <= 'd2; end 'd2: begin if(n==(width-1)) begin n <= 0; state <= 'd3; switchover <= 1; end else begin n <= n + 1; state <= 'd1; end end 'd3: begin switchover <= 0; state <= 'd0; end default:state <= 'd0; endcase end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin bin <= 'd0; end else if(switchover) bin <= bin_1; else bin <= bin; end endmodule
測試文件:

/********************************Copyright************************************** **----------------------------File information-------------------------- ** File name :grytobin_tb.v ** CreateDate :2015.04 ** Funtions :測試文件 ** Operate on :M5C06N3L114C7 ** Copyright :All rights reserved. ** Version :V1.0 **---------------------------Modify the file information---------------- ** Modified by : ** Modified data : ** Modify Content: *******************************************************************************/ module grytobin_tb; parameter width = 4; reg clk; reg rst_n; reg [width-1:0] gry; wire [width-1:0] bin; grytobin grytobin_1 ( .clk, .rst_n, .gry, .bin ); parameter tck = 24; parameter t = 1000/tck; always #(t/2) clk = ~clk; initial begin clk = 0; rst_n = 0; gry = 0; #(20*t) rst_n = 1; #(20*t) gry = 1; #(20*t) gry = 2; #(20*t) gry = 3; #(20*t) gry = 4; end endmodule
仿真圖: