传统乘法器设计在求出中间结果时,使用全加器对各级中间结果相加求出最终乘法器结果。由于全加器进位链的限制,特别是随着乘法器位宽的增加,乘法器的速度受到限制,而华莱士树加法器采用进位保存加法器而非全加器对中间结果进行计算,它能同时执行三数相加而非两数相加,虽然消耗元器件个数增多但其速度提高很多。
进位保存加法器输入由X,Y和进位Z组成,其输出由改位和S和进位C组成,一次计算将产生两个结果,相比传统的全加器区别在于进位保存加法器的进位输出并不参与上一位的求和,而是单独输出,最后再用一个全加器进行进位加入。下面就4位加法器的计算原理进行解释说明:
考虑乘法1011*1110,首先计算各个乘积项的中间结果:
1 0 1 1
x 1 1 1 0
------------------------------
0 0 0 0 PP1
1 0 1 1 PP2
1 0 1 1 PP3
1 0 1 1 PP4
------------------------------
乘积项中间结果有4个:PP1、PP2、PP3、PP4。由于进位保存加法器只能进行三个数的相加,因而可采用两个进位保存加法器实现。第一个进位保存加法器实现PP1、PP2、PP3的加法,第二个进位保存加法器将PP4和上一级的S和C相加。最终通过一个并行加法器输出积。计算过程如下:
第一个进位保存加法器
PP1: 0 0 0 0
PP2: 1 0 1 1 0
PP3: 1 0 1 1 0 0
---------------------------------------
sum1 1 1 1 0 1 0
c1 0 0 0 1 0 0
第二个进位保存加法器
pp4 1 0 1 1 0 0 0
sum1 0 1 1 1 0 1 0
c1 0 0 0 1 0 0 0
---------------------------------------
sum2: 1 1 0 1 0 1 0
c2: 0 0 1 1 0 0 0
并行加法器(全加器):
sum2: 1 1 0 1 0 1 0
c2: 0 1 1 0 0 0 0
---------------------------------------
product 1 0 0 1 1 0 1 0
在参与下一级运算的过程中,由于进位要用于高位的求和,故c1,c2均应左移一位求值。计算结果为:10011010(154)。
module Wallace_multipler(
input [3:0] a,
input [3:0] b,
output [7:0] product
);
wire [3:0] c[3:0];
wire [5:0] sum1,carry1;
wire [6:0] sum2,carry2;
assign c[0]=b[0]?a:'d0;
assign c[1]=b[1]?a:'d0;
assign c[2]=b[2]?a:'d0;
assign c[3]=b[3]?a:'d0;
wire [6-1:0] csa1_a = {2'd0,c[0]};
wire [6-1:0] csa1_b = {1'd0,(c[1]<<1)};
wire [6-1:0] csa1_c = c[2]<<2;
wire [7-1:0] csa2_a = {1'd0,sum1};
wire [7-1:0] csa2_b = carry1<<1;
wire [7-1:0] csa2_c = c[3]<<3;
carry_save_adder #(.DATA_WIDTH(6)) csa1(csa1_a,csa1_b,csa1_c,sum1,carry1);
carry_save_adder #(.DATA_WIDTH(7)) csa2(csa2_a,csa2_b,csa2_c,sum2,carry2);
assign product = sum2 + (carry2<<1);
endmodule
module carry_save_adder#(parameter DATA_WIDTH=4)(
input [DATA_WIDTH-1:0]a,
input [DATA_WIDTH-1:0]b,
input [DATA_WIDTH-1:0]cin,
output [DATA_WIDTH-1:0] sum,
output [DATA_WIDTH-1:0]carry_out
);
generate
genvar index;
for(index=0;index<DATA_WIDTH;index=index+1'b1) //assign each bit of carry_out and sum
begin
assign {carry_out[index], sum[index]} = a[index]+b[index]+cin[index];
end
endgenerate
endmodule