华莱士树乘法器这个结构是我用在FFT处理器项目中的一种乘法器,原本最优化的乘法器是华莱士树乘法器和布斯编码结合一起用,一个是时间一个是其实布斯编码器在乘数里0比较多的情况下才比较优,所以当时就选择只用了华莱士树乘法器。
最常见的,也是数电书里将的最基本的乘法器的结构如下图所示:
这个很好理解吧,就是一级一级加上去。但是呢作为组合逻辑,延时太长了,会导致后端频率上不去。
如上图所示,原本如果按照正常的进位加法器结构,那么可以看到4个数加起来需要3级加法器的延时,而使用华莱士树则减少为3级。
其中下图这个加法器就是最基础的运算单元:
这个也叫3:2压缩器,顾名思义就是2输入结果压缩成2输出。
//32压缩器/全加器
module FA(
P1,
P2,
P3,
C,
S);
input P1,P2,P3;
output wire C,S;
wire [1:0]sum1;
wire [1:0]sum2;
assign sum1=P1+P2;
assign sum2=sum1+{1'b0,P3};
assign S=sum2[0];
assign C=sum2[1];
endmodule
其实C就是进位,S是计算出的值。
上面的图就是用3:2压缩器搭出来的8*8的乘法器结构。上面的图我们可以看出当计算第07位的值时候,通过华莱士树我们将延时级数压缩到了:
07位总延时=4级全加器+1级进位传播延时
这样比最原始结构7级延时加法器延时要低。但是实际我们可以想到,这个其实有可以优化的地步,可以想办法将延时进一步压缩。既然有3:2压缩,那么有没有4:2压缩呢?
这样我们就可以实现像这样的压缩结构:
这样一看实际上总延时变成2级4:2压缩+1级超前进位。
4:2 压缩器,其实存在 5 个输入信号和 3 个输出信号。5 个输入信号中,4 个部分积信号和 1 个上一级对本级的进位信号。3 个输出信号中,2 个为本级的输出信号和 1 个进位输出信号,输出到下一级压缩器结构中。所以,有时也将 4:2 压缩器称为 5:3 压缩器。
由于 4:2 压缩器具有良好的压缩率及规整的电路结构,比较常见的结构有加法器结构 4:2 压缩器、选择器结构 4:2 压缩器、混合结构 4:2 压缩器和输入延迟相等的 4:2 压缩器[28].虽然 4:2压缩器电路结构不同,但是它们均遵循将 5 个输入压缩至 3 个输出的原则。
//42压缩器
module compress42
(
P0,
P1,
P2,
P3,
OUT_I,
OUT_O,
C,
S
);
input P0,P1,P2,P3,OUT_I;
output wire OUT_O,C,S;
wire C1;
FA FA1(
.P1(P0),
.P2(P1),
.P3(P2),
.C(OUT_O),
.S(C1)
);
FA FA2(
.P1(C1),
.P2(P3),
.P3(OUT_I),
.C(C),
.S(S)
);
endmodule
处理中间的级数优化,其实最后的进位传播加法器也可以进行优化,可以使用超前进位加法器。这个可以在新的文章中具体讲解。
完整的代码如下,其中Add32_head 模块是写的超前进位加法器,减少最后一级加法的延时,仿真时,只需要改成加法就可以了。
//定点有符号数乘法器(输入原码,输出原码)
//输入24位数,16位整数,8位小数,最高位第16位为整数符号位
//输入9位数,1位符号位,8位小数
//输出16位整数,8位小数,最高位整数符号位
//由于蝶形运算乘法均和三角函数相乘所以不会产生增加的位数
//该乘法器只能用于计算32位被乘数与小于1的小数乘数的乘法运算
module fix_multi(
mult1,
mult2,
out);
input [23:0]mult1;
input [8:0]mult2;
output wire[23:0]out;
wire [22:0]PD[7:0];
wire sign;
//--------------------------------
wire [23:0]OUT_O1,OUT_O2;
wire [28:0]OUT_O3;
wire [25:0]C1,C2;
wire [25:0]S1,S2;
wire [30:0]C3,S3;
wire [31:0]prod;
assign sign=mult1[23]^mult2[8];
//--------------------------------
//产生部分积
generate
genvar i,j;
for (i=0;i<8;i=i+1'b1)begin
for (j=0;j<23;j=j+1'b1)begin
assign PD[i][j]=mult1[j]&mult2[i];
end
end
endgenerate
//----------------------------------
//第一组
//----------------------------------
//第1列
assign S1[0]=PD[0][0];
assign C1[0]=1'b0;
//第2列
compress42 cp1_2(.P0(PD[0][1]),
.P1(PD[1][0]),
.P2(1'b0),
.P3(1'b0),
.OUT_I(1'b0),
.OUT_O(OUT_O1[0]),
.C(C1[2]),
.S(S1[1])
);
assign C1[1]=1'b0;
//第3列
compress42 cp1_3(.P0(PD[0][2]),
.P1(PD[1][1]),
.P2(PD[2][0]),
.P3(1'b0),
.OUT_I(OUT_O1[0]),
.OUT_O(OUT_O1[1]),
.C(C1[3]),
.S(S1[2])
);
//第4列
compress42 cp1_4(.P0(PD[0][3]),
.P1(PD[1][2]),
.P2(PD[2][1]),
.P3(PD[3][0]),
.OUT_I(OUT_O1[1]),
.OUT_O(OUT_O1[2]),
.C(C1[4]),
.S(S1[3])
);
//第5列
compress42 cp1_5(.P0(PD[0][4]),
.P1(PD[1][3]),
.P2(PD[2][2]),
.P3(PD[3][1]),
.OUT_I(OUT_O1[2]),
.OUT_O(OUT_O1[3]),
.C(C1[5]),
.S(S1[4])
);
//第6列
compress42 cp1_6(.P0(PD[0][5]),
.P1(PD[1][4]),
.P2(PD[2][3]),
.P3(PD[3][2]),
.OUT_I(OUT_O1[3]),
.OUT_O(OUT_O1[4]),
.C(C1[6]),
.S(S1[5])
);
compress42 cp1_7(.P0(PD[0][6]),
.P1(PD[1][5]),
.P2(PD[2][4]),
.P3(PD[3][3]),
.OUT_I(OUT_O1[4]),
.OUT_O(OUT_O1[5]),
.C(C1[7]),
.S(S1[6])
);
compress42 cp1_8(.P0(PD[0][7]),
.P1(PD[1][6]),
.P2(PD[2][5]),
.P3(PD[3][4]),
.OUT_I(OUT_O1[5]),
.OUT_O(OUT_O1[6]),
.C(C1[8]),
.S(S1[7])
);
compress42 cp1_9(.P0(PD[0][8]),
.P1(PD[1][7]),
.P2(PD[2][6]),
.P3(PD[3][5]),
.OUT_I(OUT_O1[6]),
.OUT_O(OUT_O1[7]),
.C(C1[9]),
.S(S1[8])
);
compress42 cp1_10(.P0(PD[0][9]),
.P1(PD[1][8]),
.P2(PD[2][7]),
.P3(PD[3][6]),
.OUT_I(OUT_O1[7]),
.OUT_O(OUT_O1[8]),
.C(C1[10]),
.S(S1[9])
);
compress42 cp1_11(.P0(PD[0][10]),
.P1(PD[1][9]),
.P2(PD[2][8]),
.P3(PD[3][7]),
.OUT_I(OUT_O1[8]),
.OUT_O(OUT_O1[9]),
.C(C1[11]),
.S(S1[10])
);
compress42 cp1_12(.P0(PD[0][11]),
.P1(PD[1][10]),
.P2(PD[2][9]),
.P3(PD[3][8]),
.OUT_I(OUT_O1[9]),
.OUT_O(OUT_O1[10]),
.C(C1[12]),
.S(S1[11])
);
compress42 cp1_13(.P0(PD[0][12]),
.P1(PD[1][11]),
.P2(PD[2][10]),
.P3(PD[3][9]),
.OUT_I(OUT_O1[10]),
.OUT_O(OUT_O1[11]),
.C(C1[13]),
.S(S1[12])
);
compress42 cp1_14(.P0(PD[0][13]),
.P1(PD[1][12]),
.P2(PD[2][11]),
.P3(PD[3][10]),
.OUT_I(OUT_O1[11]),
.OUT_O(OUT_O1[12]),
.C(C1[14]),
.S(S1[13])
);
compress42 cp1_15(.P0(PD[0][14]),
.P1(PD[1][13]),
.P2(PD[2][12]),
.P3(PD[3][11]),
.OUT_I(OUT_O1[12]),
.OUT_O(OUT_O1[13]),
.C(C1[15]),
.S(S1[14])
);
compress42 cp1_16(.P0(PD[0][15]),
.P1(PD[1][14]),
.P2(PD[2][13]),
.P3(PD[3][12]),
.OUT_I(OUT_O1[13]),
.OUT_O(OUT_O1[14]),
.C(C1[16]),
.S(S1[15])
);
compress42 cp1_17(.P0(PD[0][16]),
.P1(PD[1][15]),
.P2(PD[2][14]),
.P3(PD[3][13]),
.OUT_I(OUT_O1[14]),
.OUT_O(OUT_O1[15]),
.C(C1[17]),
.S(S1[16])
);
compress42 cp1_18(.P0(PD[0][17]),
.P1(PD[1][16]),
.P2(PD[2][15]),
.P3(PD[3][14]),
.OUT_I(OUT_O1[15]),
.OUT_O(OUT_O1[16]),
.C(C1[18]),
.S(S1[17])
);
compress42 cp1_19(.P0(PD[0][18]),
.P1(PD[1][17]),
.P2(PD[2][16]),
.P3(PD[3][15]),
.OUT_I(OUT_O1[16]),
.OUT_O(OUT_O1[17]),
.C(C1[19]),
.S(S1[18])
);
compress42 cp1_20(.P0(PD[0][19]),
.P1(PD[1][18]),
.P2(PD[2][17]),
.P3(PD[3][16]),
.OUT_I(OUT_O1[17]),
.OUT_O(OUT_O1[18]),
.C(C1[20]),
.S(S1[19])
);
compress42 cp1_21(.P0(PD[0][20]),
.P1(PD[1][19]),
.P2(PD[2][18]),
.P3(PD[3][17]),
.OUT_I(OUT_O1[18]),
.OUT_O(OUT_O1[19]),
.C(C1[21]),
.S(S1[20])
);
compress42 cp1_22(.P0(PD[0][21]),
.P1(PD[1][20]),
.P2(PD[2][19]),
.P3(PD[3][18]),
.OUT_I(OUT_O1[19]),
.OUT_O(OUT_O1[20]),
.C(C1[22]),
.S(S1[21])
);
compress42 cp1_23(.P0(PD[0][22]),
.P1(PD[1][21]),
.P2(PD[2][20]),
.P3(PD[3][19]),
.OUT_I(OUT_O1[20]),
.OUT_O(OUT_O1[21]),
.C(C1[23]),
.S(S1[22])
);
//24列
compress42 cp1_24(.P0(1'b0),
.P1(PD[1][22]),
.P2(PD[2][21]),
.P3(PD[3][20]),
.OUT_I(OUT_O1[21]),
.OUT_O(OUT_O1[22]),
.C(C1[24]),
.S(S1[23])
);
//25列
compress42 cp1_25(.P0(1'b0),
.P1(1'b0),
.P2(PD[2][22]),
.P3(PD[3][21]),
.OUT_I(OUT_O1[22]),
.OUT_O(OUT_O1[23]),
.C(C1[25]),
.S(S1[24])
);
compress42 cp1_26(.P0(1'b0),
.P1(1'b0),
.P2(1'b0),
.P3(PD[3][22]),
.OUT_I(OUT_O1[23]),
.OUT_O(),
.C(),
.S(S1[25])
);
//--------------------------
//第二组
//--------------------------
//第1列
assign S2[0]=PD[4][0];
assign C2[0]=1'b0;
//第2列
compress42 cp2_2(.P0(PD[4][1]),
.P1(PD[5][0]),
.P2(1'b0),
.P3(1'b0),
.OUT_I(1'b0),
.OUT_O(OUT_O2[0]),
.C(C2[2]),
.S(S2[1])
);
assign C2[1]=1'b0;
//第3列
compress42 cp2_3(.P0(PD[4][2]),
.P1(PD[5][1]),
.P2(PD[6][0]),
.P3(1'b0),
.OUT_I(OUT_O2[0]),
.OUT_O(OUT_O2[1]),
.C(C2[3]),
.S(S2[2])
);
//第4列
compress42 cp2_4(.P0(PD[4][3]),
.P1(PD[5][2]),
.P2(PD[6][1]),
.P3(PD[7][0]),
.OUT_I(OUT_O2[1]),
.OUT_O(OUT_O2[2]),
.C(C2[4]),
.S(S2[3])
);
//第5列
compress42 cp2_5(.P0(PD[4][4]),
.P1(PD[5][3]),
.P2(PD[6][2]),
.P3(PD[7][1]),
.OUT_I(OUT_O2[2]),
.OUT_O(OUT_O2[3]),
.C(C2[5]),
.S(S2[4])
);
compress42 cp2_6(.P0(PD[4][5]),
.P1(PD[5][4]),
.P2(PD[6][3]),
.P3(PD[7][2]),
.OUT_I(OUT_O2[3]),
.OUT_O(OUT_O2[4]),
.C(C2[6]),
.S(S2[5])
);
compress42 cp2_7(.P0(PD[4][6]),
.P1(PD[5][5]),
.P2(PD[6][4]),
.P3(PD[7][3]),
.OUT_I(OUT_O2[4]),
.OUT_O(OUT_O2[5]),
.C(C2[7]),
.S(S2[6])
);
compress42 cp2_8(.P0(PD[4][7]),
.P1(PD[5][6]),
.P2(PD[6][5]),
.P3(PD[7][4]),
.OUT_I(OUT_O2[5]),
.OUT_O(OUT_O2[6]),
.C(C2[8]),
.S(S2[7])
);
compress42 cp2_9(.P0(PD[4][8]),
.P1(PD[5][7]),
.P2(PD[6][6]),
.P3(PD[7][5]),
.OUT_I(OUT_O2[6]),
.OUT_O(OUT_O2[7]),
.C(C2[9]),
.S(S2[8])
);
compress42 cp2_10(.P0(PD[4][9]),
.P1(PD[5][8]),
.P2(PD[6][7]),
.P3(PD[7][6]),
.OUT_I(OUT_O2[7]),
.OUT_O(OUT_O2[8]),
.C(C2[10]),
.S(S2[9])
);
compress42 cp2_11(.P0(PD[4][10]),
.P1(PD[5][9]),
.P2(PD[6][8]),
.P3(PD[7][7]),
.OUT_I(OUT_O2[8]),
.OUT_O(OUT_O2[9]),
.C(C2[11]),
.S(S2[10])
);
compress42 cp2_12(.P0(PD[4][11]),
.P1(PD[5][10]),
.P2(PD[6][9]),
.P3(PD[7][8]),
.OUT_I(OUT_O2[9]),
.OUT_O(OUT_O2[10]),
.C(C2[12]),
.S(S2[11])
);
compress42 cp2_13(.P0(PD[4][12]),
.P1(PD[5][11]),
.P2(PD[6][10]),
.P3(PD[7][9]),
.OUT_I(OUT_O2[10]),
.OUT_O(OUT_O2[11]),
.C(C2[13]),
.S(S2[12])
);
compress42 cp2_14(.P0(PD[4][13]),
.P1(PD[5][12]),
.P2(PD[6][11]),
.P3(PD[7][10]),
.OUT_I(OUT_O2[11]),
.OUT_O(OUT_O2[12]),
.C(C2[14]),
.S(S2[13])
);
compress42 cp2_15(.P0(PD[4][14]),
.P1(PD[5][13]),
.P2(PD[6][12]),
.P3(PD[7][11]),
.OUT_I(OUT_O2[12]),
.OUT_O(OUT_O2[13]),
.C(C2[15]),
.S(S2[14])
);
compress42 cp2_16(.P0(PD[4][15]),
.P1(PD[5][14]),
.P2(PD[6][13]),
.P3(PD[7][12]),
.OUT_I(OUT_O2[13]),
.OUT_O(OUT_O2[14]),
.C(C2[16]),
.S(S2[15])
);
compress42 cp2_17(.P0(PD[4][16]),
.P1(PD[5][15]),
.P2(PD[6][14]),
.P3(PD[7][13]),
.OUT_I(OUT_O2[14]),
.OUT_O(OUT_O2[15]),
.C(C2[17]),
.S(S2[16])
);
compress42 cp2_18(.P0(PD[4][17]),
.P1(PD[5][16]),
.P2(PD[6][15]),
.P3(PD[7][14]),
.OUT_I(OUT_O2[15]),
.OUT_O(OUT_O2[16]),
.C(C2[18]),
.S(S2[17])
);
compress42 cp2_19(.P0(PD[4][18]),
.P1(PD[5][17]),
.P2(PD[6][16]),
.P3(PD[7][15]),
.OUT_I(OUT_O2[16]),
.OUT_O(OUT_O2[17]),
.C(C2[19]),
.S(S2[18])
);
compress42 cp2_20(.P0(PD[4][19]),
.P1(PD[5][18]),
.P2(PD[6][17]),
.P3(PD[7][16]),
.OUT_I(OUT_O2[17]),
.OUT_O(OUT_O2[18]),
.C(C2[20]),
.S(S2[19])
);
compress42 cp2_21(.P0(PD[4][20]),
.P1(PD[5][19]),
.P2(PD[6][18]),
.P3(PD[7][17]),
.OUT_I(OUT_O2[18]),
.OUT_O(OUT_O2[19]),
.C(C2[21]),
.S(S2[20])
);
compress42 cp2_22(.P0(PD[4][21]),
.P1(PD[5][20]),
.P2(PD[6][19]),
.P3(PD[7][18]),
.OUT_I(OUT_O2[19]),
.OUT_O(OUT_O2[20]),
.C(C2[22]),
.S(S2[21])
);
compress42 cp2_23(.P0(PD[4][22]),
.P1(PD[5][21]),
.P2(PD[6][20]),
.P3(PD[7][19]),
.OUT_I(OUT_O2[20]),
.OUT_O(OUT_O2[21]),
.C(C2[23]),
.S(S2[22])
);
//24列
compress42 cp2_24(.P0(1'b0),
.P1(PD[5][22]),
.P2(PD[6][21]),
.P3(PD[7][20]),
.OUT_I(OUT_O2[21]),
.OUT_O(OUT_O2[22]),
.C(C2[24]),
.S(S2[23])
);
//25列
compress42 cp2_25(.P0(1'b0),
.P1(1'b0),
.P2(PD[6][22]),
.P3(PD[7][21]),
.OUT_I(OUT_O2[22]),
.OUT_O(OUT_O2[23]),
.C(C2[25]),
.S(S2[24])
);
//26列
compress42 cp2_26(.P0(1'b0),
.P1(1'b0),
.P2(1'b0),
.P3(PD[7][22]),
.OUT_I(OUT_O2[23]),
.OUT_O(),
.C(),
.S(S2[25])
);
//-------------------------------
//第三组
compress42 cp3_1(.P0(S1[0]),
.P1(C1[0]),
.P2(1'b0),
.P3(1'b0),
.OUT_I(1'b0),
.OUT_O(OUT_O3[0]),
.C(C3[1]),
.S(S3[0])
);
assign C3[0]=1'b0;
compress42 cp3_2(.P0(S1[1]),
.P1(C1[1]),
.P2(1'b0),
.P3(1'b0),
.OUT_I(OUT_O3[0]),
.OUT_O(OUT_O3[1]),
.C(C3[2]),
.S(S3[1])
);
compress42 cp3_3(.P0(S1[2]),
.P1(C1[2]),
.P2(1'b0),
.P3(1'b0),
.OUT_I(OUT_O3[1]),
.OUT_O(OUT_O3[2]),
.C(C3[3]),
.S(S3[2])
);
compress42 cp3_4(.P0(S1[3]),
.P1(C1[3]),
.P2(1'b0),
.P3(1'b0),
.OUT_I(OUT_O3[2]),
.OUT_O(OUT_O3[3]),
.C(C3[4]),
.S(S3[3])
);
//第5列
compress42 cp3_5(.P0(S1[4]),
.P1(C1[4]),
.P2(S2[0]),
.P3(C2[0]),
.OUT_I(OUT_O3[3]),
.OUT_O(OUT_O3[4]),
.C(C3[5]),
.S(S3[4])
);
compress42 cp3_6(.P0(S1[5]),
.P1(C1[5]),
.P2(S2[1]),
.P3(C2[1]),
.OUT_I(OUT_O3[4]),
.OUT_O(OUT_O3[5]),
.C(C3[6]),
.S(S3[5])
);
compress42 cp3_7(.P0(S1[6]),
.P1(C1[6]),
.P2(S2[2]),
.P3(C2[2]),
.OUT_I(OUT_O3[5]),
.OUT_O(OUT_O3[6]),
.C(C3[7]),
.S(S3[6])
);
compress42 cp3_8(.P0(S1[7]),
.P1(C1[7]),
.P2(S2[3]),
.P3(C2[3]),
.OUT_I(OUT_O3[6]),
.OUT_O(OUT_O3[7]),
.C(C3[8]),
.S(S3[7])
);
compress42 cp3_9(.P0(S1[8]),
.P1(C1[8]),
.P2(S2[4]),
.P3(C2[4]),
.OUT_I(OUT_O3[7]),
.OUT_O(OUT_O3[8]),
.C(C3[9]),
.S(S3[8])
);
compress42 cp3_10(.P0(S1[9]),
.P1(C1[9]),
.P2(S2[5]),
.P3(C2[5]),
.OUT_I(OUT_O3[8]),
.OUT_O(OUT_O3[9]),
.C(C3[10]),
.S(S3[9])
);
compress42 cp3_11(.P0(S1[10]),
.P1(C1[10]),
.P2(S2[6]),
.P3(C2[6]),
.OUT_I(OUT_O3[9]),
.OUT_O(OUT_O3[10]),
.C(C3[11]),
.S(S3[10])
);
compress42 cp3_12(.P0(S1[11]),
.P1(C1[11]),
.P2(S2[7]),
.P3(C2[7]),
.OUT_I(OUT_O3[10]),
.OUT_O(OUT_O3[11]),
.C(C3[12]),
.S(S3[11])
);
compress42 cp3_13(.P0(S1[12]),
.P1(C1[12]),
.P2(S2[8]),
.P3(C2[8]),
.OUT_I(OUT_O3[11]),
.OUT_O(OUT_O3[12]),
.C(C3[13]),
.S(S3[12])
);
compress42 cp3_14(.P0(S1[13]),
.P1(C1[13]),
.P2(S2[9]),
.P3(C2[9]),
.OUT_I(OUT_O3[12]),
.OUT_O(OUT_O3[13]),
.C(C3[14]),
.S(S3[13])
);
compress42 cp3_15(.P0(S1[14]),
.P1(C1[14]),
.P2(S2[10]),
.P3(C2[10]),
.OUT_I(OUT_O3[13]),
.OUT_O(OUT_O3[14]),
.C(C3[15]),
.S(S3[14])
);
compress42 cp3_16(.P0(S1[15]),
.P1(C1[15]),
.P2(S2[11]),
.P3(C2[11]),
.OUT_I(OUT_O3[14]),
.OUT_O(OUT_O3[15]),
.C(C3[16]),
.S(S3[15])
);
compress42 cp3_17(.P0(S1[16]),
.P1(C1[16]),
.P2(S2[12]),
.P3(C2[12]),
.OUT_I(OUT_O3[15]),
.OUT_O(OUT_O3[16]),
.C(C3[17]),
.S(S3[16])
);
compress42 cp3_18(.P0(S1[17]),
.P1(C1[17]),
.P2(S2[13]),
.P3(C2[13]),
.OUT_I(OUT_O3[16]),
.OUT_O(OUT_O3[17]),
.C(C3[18]),
.S(S3[17])
);
compress42 cp3_19(.P0(S1[18]),
.P1(C1[18]),
.P2(S2[14]),
.P3(C2[14]),
.OUT_I(OUT_O3[17]),
.OUT_O(OUT_O3[18]),
.C(C3[19]),
.S(S3[18])
);
compress42 cp3_20(.P0(S1[19]),
.P1(C1[19]),
.P2(S2[15]),
.P3(C2[15]),
.OUT_I(OUT_O3[18]),
.OUT_O(OUT_O3[19]),
.C(C3[20]),
.S(S3[19])
);
compress42 cp3_21(.P0(S1[20]),
.P1(C1[20]),
.P2(S2[16]),
.P3(C2[16]),
.OUT_I(OUT_O3[19]),
.OUT_O(OUT_O3[20]),
.C(C3[21]),
.S(S3[20])
);
compress42 cp3_22(.P0(S1[21]),
.P1(C1[21]),
.P2(S2[17]),
.P3(C2[17]),
.OUT_I(OUT_O3[20]),
.OUT_O(OUT_O3[21]),
.C(C3[22]),
.S(S3[21])
);
compress42 cp3_23(.P0(S1[22]),
.P1(C1[22]),
.P2(S2[18]),
.P3(C2[18]),
.OUT_I(OUT_O3[21]),
.OUT_O(OUT_O3[22]),
.C(C3[23]),
.S(S3[22])
);
compress42 cp3_24(.P0(S1[23]),
.P1(C1[23]),
.P2(S2[19]),
.P3(C2[19]),
.OUT_I(OUT_O3[22]),
.OUT_O(OUT_O3[23]),
.C(C3[24]),
.S(S3[23])
);
compress42 cp3_25(.P0(S1[24]),
.P1(C1[24]),
.P2(S2[20]),
.P3(C2[20]),
.OUT_I(OUT_O3[23]),
.OUT_O(OUT_O3[24]),
.C(C3[25]),
.S(S3[24])
);
compress42 cp3_26(.P0(S1[25]),
.P1(C1[25]),
.P2(S2[21]),
.P3(C2[21]),
.OUT_I(OUT_O3[24]),
.OUT_O(OUT_O3[25]),
.C(C3[26]),
.S(S3[25])
);
compress42 cp3_27(.P0(1'b0),
.P1(1'b0),
.P2(S2[22]),
.P3(C2[22]),
.OUT_I(OUT_O3[25]),
.OUT_O(OUT_O3[26]),
.C(C3[27]),
.S(S3[26])
);
compress42 cp3_28(.P0(1'b0),
.P1(1'b0),
.P2(S2[23]),
.P3(C2[23]),
.OUT_I(OUT_O3[26]),
.OUT_O(OUT_O3[27]),
.C(C3[28]),
.S(S3[27])
);
compress42 cp3_29(.P0(1'b0),
.P1(1'b0),
.P2(S2[24]),
.P3(C2[24]),
.OUT_I(OUT_O3[27]),
.OUT_O(OUT_O3[28]),
.C(C3[29]),
.S(S3[28])
);
compress42 cp3_30(.P0(1'b0),
.P1(1'b0),
.P2(S2[25]),
.P3(C2[25]),
.OUT_I(OUT_O3[28]),
.OUT_O(),
.C(C3[30]),
.S(S3[29])
);
assign S3[30]=1'b0;
//assign prod[30:0]=S3+C3;
wire [31:0]sum;
assign prod[30:0]=sum[30:0];
Add32_head Add32
(
.A({1'b0,S3}),
.B({1'b0,C3}),
.C_in(0),
.Result(sum),
.C_out()
);
assign prod[31]=sign;
assign out=prod[31:8];
endmodule
对照上图,看代码主要分成三级,4个部分积过4:2压缩后会生成2个新的部分积,这样第一级计算1-4行,第二级计算5-8行,计算结果会生成4行新的部分积,再用一级4:2压缩,则最后只剩2行新的部分积,这样只需要普通加法器即可计算出结果了。
最后附上仿真对比计算结果和中间过程调试的matlab程序:
clear all;
p='11111111111111111111111';
part=[''];
for i=1:8
part=[part;fill_zero(8-i),p,fill_zero(i)];
end
%第一组
OUT_IN1=fill_zero(31);C1=fill_zero(31);S1=fill_zero(31);OUT_O1=fill_zero(31);
for i=31:-1:2
[OUT_O1(i),C1(i-1),S1(i)]=compress42(part(1,i-1),part(2,i-1),part(3,i-1),part(4,i-1),OUT_IN1(i));
OUT_IN1(i-1)=OUT_O1(i);
end
%第二组
OUT_IN2=fill_zero(31);C2=fill_zero(31);S2=fill_zero(31);OUT_O2=fill_zero(31);
for i=31:-1:2
[OUT_O2(i),C2(i-1),S2(i)]=compress42(part(5,i-1),part(6,i-1),part(7,i-1),part(8,i-1),OUT_IN2(i));
OUT_IN2(i-1)=OUT_O2(i);
end
%第三组
OUT_IN3=fill_zero(31);C3=fill_zero(31);S3=fill_zero(31);OUT_O3=fill_zero(31);
for i=31:-1:2
[OUT_O3(i),C3(i-1),S3(i)]=compress42(S1(1,i),C1(1,i),S2(1,i),C2(1,i),OUT_IN3(i));
OUT_IN3(i-1)=OUT_O3(i);
end
product=dec2bin(bin2dec(S3)+bin2dec(C3),31);
correct_prod=dec2bin(bin2dec(p)*bin2dec('11111111'),31);
function r=fill_zero(n)
r=[''];
for i=1:n
r=[r,'0'];
end
end
function [OUT_O,C0,S0]=compress42(P0,P1,P2,P3,OUT_IN)
[S,OUT_O]=FA(P0,P1,P2);
[S0,C0]=FA(S,P3,OUT_IN);
end
function [S,C]=FA(P1,P2,P3)
sum=str2num(P1)+str2num(P2)+str2num(P3);
bin=dec2bin(sum,2);
S=bin(2);
C=bin(1);
end