学习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-1xor 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 //
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=G0xor B1 ,i=1,2,...,n-1。此时G0是确定的值,但是B1还未计算出来,是不定值x,因此二者异或结果为不定值x,其他bit以此类推。从modelsim生成的原理图也能看出来,二进制码的次态输出除了取决于格雷码的现态值,还依赖于二进制码的现态值。
将上述算法进行修改,for循环从高bit为开始,结果如下。
表述一修改后的仿真实例:
源代码:
1 //
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 //
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选项)

















