Wallace树乘法器专题研究
绪论:在乘法器的设计中采用树形乘法器,可以减少关键路径和所需的加法器单元数目,Wallace树乘法器就是其中的一种。下面以一个4*4位乘法器为例介绍Wallace树乘法器及其Verilog HDL实现。
原理:Wallace树乘法器的运算原理如下:
从数据最密集的地方开始,不断的反复使用全加器、半加器来覆盖“树”。全加器是一个3输入2输出的器件,因此全加器又称作3—2压缩器。通过全加器将树的深度不断缩减,最终缩减为一个深度为2的树。最后一级则采用简单的2输入加法器组成。
部分积 |
|||||||
被乘数 |
|
|
|
X3 |
X2 |
X1 |
X0 |
乘数 |
|
|
|
Y3 |
Y2 |
Y1 |
Y0 |
|
|
|
|
X3y0 (a[6]) |
X2y0 (a[3]) |
X1y0 (a[1]) |
X0y0 (a[0]) |
|
|
|
X3y1 (a[10]) |
X2y1 (a[7]) |
X1y1 (a[4]) |
X0y1 (a[2]) |
|
|
|
X3y2 (a[13]) |
X2y2 (a[11]) |
X1y2 (a[8]) |
X0y2 (a[5]) |
|
|
|
X3y3 (a[15]) |
X2y3 (a[14]) |
X1y3 (a[12]) |
X0y3 (a[9]) |
|
|
|
第一级 |
|||||||
|
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
X3y3 (a[15]) |
X3y2 (a[13]) |
X3y1 (a[10]) |
X3y0 (a[6]) |
X2y0 (a[3]) |
X1y0 (a[1]) |
X0y0 (a[0]) |
|
|
X2y3 (a[14]) |
X2y2 (a[11]) |
X2y1 (a[7]) |
X1y1 (a[4]) |
X0y1 (a[2]) |
|
|
|
|
X1y3 (a[12]) |
X1y2 (a[8]) |
X0y2 (a[5]) |
|
|
|
|
|
|
X0y3 (a[9]) |
|
|
|
加法器结果 |
|
|
[1 : 0] b1 |
[1 : 0] b0 |
|
|
|
注:对第一级的绿色部分,即a[8]和a[9],以及a[11]和a[12],使用半加器进行处理,
其verilog HDL代码体现如下:
1. hadd U1(.x(a[8]), .y(a[9]), .out(b0)); //2输入半加器(第一级)
2. hadd U2(.x(a[11]), .y(a[12]), .out(b1));//第一级
输出分别为b0和 b1 。
第二级 |
|||||||
|
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
X3y3 (a[15]) |
X3y2 (a[13]) |
X3y1 (a[10]) |
X3y0 (a[6]) |
X2y0 (a[3]) |
X1y0 (a[1]) |
X0y0 (a[0]) |
|
|
X2y3 (a[14]) |
b1[0] |
X2y1 (a[7]) |
X1y1 (a[4]) |
X0y1 (a[2]) |
|
|
|
b1[1] |
b0[1] |
b0[0] |
X0y2 (a[5]) |
|
|
加法器结果 |
|
[1 : 0] C3 |
[1 : 0] C2 |
[1 : 0] C1 |
[1 : 0] C0 |
|
|
注:半加器仍然用绿色部分表示,全加器用橙色部分表示,第二级经过半加器以及全加器的处理后,到达第三级。
其verilog HDL代码体现如下:
1. hadd U3(.x(a[4]), .y(a[5]), .out(c0)); //第二级
2. fadd U4(.x(a[6]), .y(a[7]), .z(b0[0]), .out(c1)); //3输入全加器(第二级)
3. fadd U5(.x(b1[0]), .y(a[10]), .z(b0[1]), .out(c2));
4. fadd U6(.x(a[13]), .y(a[14]), .z(b1[1]), .out(c3));
第三级 |
||||||
6 |
5 |
4 |
3 |
2 |
1 |
0 |
X3y3 (a[15]) |
C3[0] |
C2[0] |
C1[0] |
X2y0 (a[3]) |
X1y0 (a[1]) |
X0y0 (a[0]) |
C3[1] |
C2[1] |
C1[1] |
C0[1] |
C0[0] |
X0y1 (a[2]) |
|
注:第三级树的深度减少到2,采用简单的2输入加法器即可得到最后的结果。
其在verilog HDL代码中的体现如下:
1. assign add_a = {c3[1],c2[1],c1[1],c0[1],c0[0],a[2]}; //加法器(第三极)
2. assign add_b = {a[15],c3[0],c2[0],c1[0],a[3],a[1]};
3. assign add_out = add_a + add_b;
4. assign out = {add_out,a[0]};
Verilog HDL 描述:
整个电路的verilog HDL 设计代码如下:
1. module wallace(x,y,out);
2. parameter size = 4; //定义参数,乘法器的位数
3. input [size - 1 : 0] x,y; //输入y是乘数,x是被乘数
4. output [2*size - 1 : 0] out;
5. wire [size*size - 1 : 0] a; //a为部分积
6. wire [1 : 0] b0, b1; //第一级的输出,包含进位
7. wire [1 : 0] c0, c1, c2, c3; //第二级的输出,包含进位
8. wire [5 : 0] add_a, add_b; //第三极的输入
9. wire [6 : 0] add_out; //第三极的输出
10. wire [2*size - 1 : 0] out; //乘法器的输出(组合逻辑)
11.
12. assign a = {x[3],x[2],x[3],x[1],x[2],x[3],x[0],x[1],
13. x[2],x[3],x[0],x[1],x[2],x[0],x[1],x[0]}
14. &{y[3],y[3],y[2],y[3],y[2],y[1],y[3],y[2]
15. ,y[1],y[0],y[2],y[1],y[0],y[1],y[0],y[0]}; //部分积
16.
17. hadd U1(.x(a[8]), .y(a[9]), .out(b0)); //2输入半加器(第一级)
18. hadd U2(.x(a[11]), .y(a[12]), .out(b1));//第一级
19. hadd U3(.x(a[4]), .y(a[5]), .out(c0)); //第二级
20.
21. fadd U4(.x(a[6]), .y(a[7]), .z(b0[0]), .out(c1)); //3输入全加器(第二级)
22. fadd U5(.x(b1[0]), .y(a[10]), .z(b0[1]), .out(c2));
23. fadd U6(.x(a[13]), .y(a[14]), .z(b1[1]), .out(c3));
24.
25.
26. assign add_a = {c3[1],c2[1],c1[1],c0[1],c0[0],a[2]}; //加法器(第三极)
27. assign add_b = {a[15],c3[0],c2[0],c1[0],a[3],a[1]};
28. assign add_out = add_a + add_b;
29. assign out = {add_out,a[0]};
30.
31. endmodule
32.
33. //全加器模块
34. module fadd(x, y, z, out);
35. input x, y, z;
36. output [1 : 0] out;
37. assign out = x + y + z;
38. endmodule
39.
40. //半加器模块
41. module hadd(x, y, out);
42. input x, y;
43. output [1 : 0] out;
44. assign out = x + y;
45. endmodule
Testbench(测试) 文件代码如下:
1. //测试文件
2.
3. `timescale 1ns/1ps
4. module wallace_tb;
5. reg [3 : 0] x, y;
6. wire [7 : 0] out;
7. wallace U1(.x(x), .y(y), .out(out)); //模块实例
8.
9. initial
10. begin
11. x = 3;
12. y = 4;
13. # 20
14. x = 2;
15. y = 3;
16. # 20
17. x = 6;
18. y = 8;
19. end
20.
21. endmodule
用Modelsim仿真软件仿真图波形图如下:
测试发现,结果符合预期结果。
在ISE软件中仿真,其 RTL Schematic 如下: