格雷码(Gray Code)转二进制码(Binary Code)
学习verilog generate语句时,偶然看到用generate语句来进行格雷码到二进制码转换的代码,就从网上找了一些案例来学习。
下表为几种自然二进制码与格雷码的对照表:
十进制数 | 自然二进制数 | 格雷码 | 十进制数 | 自然二进制数 | 格雷码 |
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 |
格雷码转换为二进制码算法有以下几种表述形式:
表述一:
二进制格雷码为Gn-1Gn-2...G2G1G0
对应的自然二进制码为Bn-1Bn-2...B2B1B0
其中:最高位保留—Bn-1=Gn-1
其他各位—Bi-1=Gi-1 xor Bi ,i=1,2,...,n-1
表述二:
Bi = ˆG[n-1:i]=G[n-1]ˆG[n-2]ˆ..ˆG[i],i=0,1,...,n-1
表述三:
Bi = ˆ(G>>i),i=0,1,...,n-1
表述一的仿真实例:
源代码:
1 //http://www.cnblogs.com/adamite/archive/2008/10/20/1314949.html 2 //example2 3 module GrayToBinary2 (binarycode, graycode); 4 parameter n = 4; // this module is parameterizable 5 output reg [n-1:0] binarycode; 6 input [n-1:0] graycode; 7 integer i; 8 always @ (graycode) 9 begin 10 binarycode[n-1]=graycode[n-1]; 11 for(i=1;i<=n-1;i=i+1) 12 binarycode[i-1]=graycode[i-1] ^ binarycode[i];//比较节省空间 13 end 14 endmodule
测试代码:
1 `timescale 1ns/1ns 2 module tb_GrayToBinary2; 3 4 reg [3:0] gray; 5 wire [3:0] bin; 6 7 GrayToBinary2 dut (bin,gray); 8 9 initial begin 10 gray = 4'h0; 11 #10; 12 gray = 4'h1; 13 #10; 14 gray = 4'h2; 15 #10; 16 gray = 4'h3; 17 #10; 18 gray = 4'he; 19 #10; 20 gray = 4'h7; 21 #10; 22 gray = 4'hf; 23 end 24 endmodule
仿真结果:
modelsim生成的原理图(注意要在vsim后面加上-debugDB选项)
从仿真结果来看,格雷码转二进制码过程中出现错误。开始两次转换出现不定态,而且后面的转换结果也是错误的。是什么原因呢?从算法上看,格雷码的最高位给了二进制码的最高位,这没问题。但是接下来的for循环,从二进制的最低bit位开始,即B0=G0 xor B1 ,i=1,2,...,n-1。此时G0是确定的值,但是B1还未计算出来,是不定值x,因此二者异或结果为不定值x,其他bit以此类推。从modelsim生成的原理图也能看出来,二进制码的次态输出除了取决于格雷码的现态值,还依赖于二进制码的现态值。
将上述算法进行修改,for循环从高bit为开始,结果如下。
表述一修改后的仿真实例:
源代码:
1 //http://www.cnblogs.com/adamite/archive/2008/10/20/1314949.html 2 //example2 3 module GrayToBinary2ex (binarycode, graycode); 4 parameter n = 4; // this module is parameterizable 5 output reg [n-1:0] binarycode; 6 input [n-1:0] graycode; 7 integer i; 8 always @ (graycode) 9 begin 10 binarycode[n-1]=graycode[n-1]; 11 // for(i=1;i<=n-1;i=i+1) 12 // binarycode[i-1]=graycode[i-1] ^ binarycode[i];//比较节省空间 13 for(i=n-1;i>0;i=i-1) 14 binarycode[i-1]=graycode[i-1] ^ binarycode[i];//比较节省空间 15 end 16 endmodule
测试代码:
1 `timescale 1ns/1ns 2 module tb_GrayToBinary2ex; 3 4 reg [3:0] gray; 5 wire [3:0] bin; 6 7 GrayToBinary2ex dut (bin,gray); 8 9 initial begin 10 gray = 4'h0; 11 #10; 12 gray = 4'h1; 13 #10; 14 gray = 4'h2; 15 #10; 16 gray = 4'h3; 17 #10; 18 gray = 4'he; 19 #10; 20 gray = 4'h7; 21 #10; 22 gray = 4'hf; 23 end 24 endmodule
仿真结果:
modelsim生成的原理图(注意要在vsim后面加上-debugDB选项)
表述二的仿真实例:
源代码:
1 // Verilog LRM 1364-2005.pdf P184 2 module gray2bin (bin, gray); 3 parameter SIZE = 4; // this module is parameterizable 4 output [SIZE-1:0] bin; 5 input [SIZE-1:0] gray; 6 7 genvar i; 8 generate 9 for (i=0; i<SIZE; i=i+1) begin:bit 10 assign bin[i] = ^gray[SIZE-1:i]; 11 // i refers to the implicitly defined localparam whose 12 // value in each instance of the generate block is 13 // the value of the genvar when it was elaborated. 14 end 15 endgenerate 16 endmodule
测试代码:
1 `timescale 1ns/1ns 2 module tb_gray2bin; 3 4 reg [3:0] gray; 5 wire [3:0] bin; 6 7 gray2bin dut (bin,gray); 8 9 initial begin 10 gray = 4'h0; 11 #10; 12 gray = 4'h1; 13 #10; 14 gray = 4'h2; 15 #10; 16 gray = 4'h3; 17 #10; 18 gray = 4'he; 19 #10; 20 gray = 4'h7; 21 #10; 22 gray = 4'hf; 23 end 24 endmodule
仿真结果:
modelsim生成的原理图(注意要在vsim后面加上-debugDB选项)
表述三的仿真实例:
源代码:
1 //http://www.cnblogs.com/adamite/archive/2008/10/20/1314949.html 2 //example1 3 module GrayToBinary1 (binarycode, graycode); 4 parameter n = 4; // this module is parameterizable 5 output reg [n-1:0] binarycode; 6 input [n-1:0] graycode; 7 integer i; 8 always @ (graycode) 9 begin 10 for(i=0;i<=n-1;i=i+1) 11 binarycode[i]=^(graycode>>i);//比较浪费空间 12 end 13 endmodule
测试代码:
1 `timescale 1ns/1ns 2 module tb_GrayToBinary1; 3 4 reg [3:0] gray; 5 wire [3:0] bin; 6 7 GrayToBinary1 dut (bin,gray); 8 9 initial begin 10 gray = 4'h0; 11 #10; 12 gray = 4'h1; 13 #10; 14 gray = 4'h2; 15 #10; 16 gray = 4'h3; 17 #10; 18 gray = 4'he; 19 #10; 20 gray = 4'h7; 21 #10; 22 gray = 4'hf; 23 end 24 endmodule
仿真结果:
modelsim生成的原理图(注意要在vsim后面加上-debugDB选项)