格雷码与二进制码互相转换
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(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
仿真图: