文章最后附带源码:
有时间会对部分代码进行解析
四位并行加法器思想
对比四位串行加法器
延迟分析
32位并行加法器
结构:
一、 进位模块
a) 第一重进位
b) 第二重进位
二、结果模块
基于以下原理进行编码实现
每一位的进位:
d = a&b;
t = a^b
改进之后 的总模块(由于并行加法器模块最低位进位不存在进位,所以后面修改代码cin接地了)
总模块(改进之前,后面截图均为改动之前)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210509004145698.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2MTIzODY2,size_16,color_FFFFFF,t_70
各模块展开后
产生D0-D7,T0-T7组合模块
产生每一个D,T的模块
产生C3,C7,C11,C15,C19,C23,C27,C31进位的模块,即第二重进位链模块
产生除第二重进位链的其它进位 ,即第一重进位链模块
结果模块
仿真测试:
1、无溢出情况
2、出现溢出的情况
时延分析
若采用32位串行加法器:3x32=96个门级
32位并行加法器:16个门级
源码:
//封装add_32模块的模块
module add_unit(
input[31:0]a,b,
output [31:0]sum,output OF
);
add_32 adder(a,b,sum,OF);
endmodule
module add_32(
input[31:0] a,b,
output[31:0]sum,output cout
);
wire cin;//最低位进位置零
wire [31:0] d,t;
wire [30:0] cry;
wire [7:0] cry_temp;
wire [7:0] dd,tt;
assign cin=1'b0;
assign d=a&b;
assign t=a^b;
cry_1 m0(d[2:0],t[2:0],cin,cry[2:0]);
//生成D0-D7,T0-T7
dd_tt dt0(d[31:0],t[31:0],dd[7:0],tt[7:0]);
//第一大组
//生成C3,C7,C11,C15
cry_advance c0(dd[3:0],tt[3:0],cin,cry_temp[3:0]);
assign cry[3]=cry_temp[0];
assign cry[7]=cry_temp[1];
assign cry[11]=cry_temp[2];
assign cry[15]=cry_temp[3];
cry_1 m1(d[6:4],t[6:4],cry_temp[0],cry[6:4]);
cry_1 m2(d[10:8],t[10:8],cry_temp[1],cry[10:8]);
cry_1 m3(d[14:12],t[14:12],cry_temp[2],cry[14:12]);
//第二大组
//生成C19,C23,C27,C3
cry_advance c1(dd[7:4],tt[7:4],cry_temp[3],cry_temp[7:4]);
assign cry[19]=cry_temp[4];
assign cry[23]=cry_temp[5];
assign cry[27]=cry_temp[6];
assign cout=cry_temp[7];//cry[31]
cry_1 m4(d[18:16],t[18:16],cry_temp[3],cry[18:16]);
cry_1 m5(d[22:20],t[22:20],cry_temp[4],cry[22:20]);
cry_1 m6(d[26:24],t[26:24],cry_temp[5],cry[26:24]);
cry_1 m7(d[30:28],t[30:28],cry_temp[6],cry[30:28]);
//调用结果计算模块
result rst(t,cin,cry,sum);
endmodule
//-----------------------------------------------------------------------
//生成产生D0_D7,T0_T7
module dd_tt(input [31:0]d,t,output[7:0]dd,tt);
dt dt0(d[3:0],t[3:0],dd[0],tt[0]);
dt dt1(d[7:4],t[7:4],dd[1],tt[1]);
dt dt2(d[11:8],t[11:8],dd[2],tt[2]);
dt dt3(d[15:12],t[15:12],dd[3],tt[3]);
dt dt4(d[19:16],t[19:16],dd[4],tt[4]);
dt dt5(d[23:20],t[23:20],dd[5],tt[5]);
dt dt6(d[27:24],t[27:24],dd[6],tt[6]);
dt dt7(d[31:28],t[31:28],dd[7],tt[7]);
endmodule
//生成D,T
module dt(input [3:0]d,t,output dd,tt);
assign dd=d[3]|d[2]&t[3]|d[1]&t[2]&t[3]|d[0]&t[1]&t[2]&t[3];
assign tt=t[0]&t[1]&t[2]&t[3];
endmodule
//-------------------------------------------------------------------------
//第二重进位
//生成C_3,7,11,15,19,23,27,31进位模块
module cry_advance(input [3:0]dd,tt,input cin,output [3:0]cry);
assign cry[0]=dd[0]|tt[0]&cin;
assign cry[1]=dd[1]|dd[0]&tt[1]|tt[0]&tt[1]&cin;
assign cry[2]=dd[2]|dd[1]&tt[2]|dd[0]&tt[1]&tt[2]|tt[0]&tt[1]&tt[2]&cin;
assign cry[3]=dd[3]|dd[2]|dd[1]&tt[2]&tt[3]|dd[0]&tt[1]&tt[2]&tt[3]|tt[0]&tt[1]&tt[2]&tt[3]&cin;
endmodule
//第一重进位生成模块
module cry_1(
input [2:0]d,t,input cin,
output [2:0]c
);
assign c[0]=d[0]|t[0]&cin;
assign c[1]=d[1]|d[0]&t[1]|t[0]&t[1]&cin;
assign c[2]=d[2]|d[1]&t[2]|d[0]&t[1]&t[2]|t[0]&t[1]&t[2]&cin;
endmodule
//计算结果模块
module result(
input [31:0] t,input cin,input [30:0]cry,
output [31:0] sum
);
assign sum[0]=t[0]^cin;
assign sum[1]=t[1]^cry[0];
assign sum[2]=t[2]^cry[1];
assign sum[3]=t[3]^cry[2];
assign sum[4]=t[4]^cry[3];
assign sum[5]=t[5]^cry[4];
assign sum[6]=t[6]^cry[5];
assign sum[7]=t[7]^cry[6];
assign sum[8]=t[8]^cry[7];
assign sum[9]=t[9]^cry[8];
assign sum[10]=t[10]^cry[9];
assign sum[11]=t[11]^cry[10];
assign sum[12]=t[12]^cry[11];
assign sum[13]=t[13]^cry[12];
assign sum[14]=t[14]^cry[13];
assign sum[15]=t[15]^cry[14];
assign sum[16]=t[16]^cry[15];
assign sum[17]=t[17]^cry[16];
assign sum[18]=t[18]^cry[17];
assign sum[19]=t[19]^cry[18];
assign sum[20]=t[20]^cry[19];
assign sum[21]=t[21]^cry[20];
assign sum[22]=t[22]^cry[21];
assign sum[23]=t[23]^cry[22];
assign sum[24]=t[24]^cry[23];
assign sum[25]=t[25]^cry[24];
assign sum[26]=t[26]^cry[25];
assign sum[27]=t[27]^cry[26];
assign sum[28]=t[28]^cry[27];
assign sum[29]=t[29]^cry[28];
assign sum[30]=t[30]^cry[29];
assign sum[31]=t[31]^cry[30];
endmodule
仿真激励文件
module add_test(
output [31:0]sum,output OF
);
reg [31:0]a,b;
initial begin
//0-1000范围内的数据
a=32'd256;
b=32'd256;
#5 a=32'd571;
b=32'd424;
#5 a=32'd677;
b=32'd993;
#5 a=32'd914;
b=32'd905;
#5 a=32'd521;
b=32'd10;
#5 a=32'd339;
b=32'd312;
#5 a=32'd812;
b=32'd16;
#5 a=32'd625;
b=32'd113;
#5 a=32'd972;
b=32'd563;
#5 a=32'd276;
b=32'd951;
#5 a=32'd575;
b=32'd410;
//0-100000内的数据
#5 a=32'd68268;
b=32'd32640;
#5 a=32'd4612;
b=32'd71316;
#5 a=32'd99268;
b=32'd80974;
#5 a=32'd75245;
b=32'd96809;
#5 a=32'd14093;
b=32'd52513;
#5 a=32'd77219;
b=32'd72287;
#5 a=32'd84919;
b=32'd76230;
#5 a=32'd44887;
b=32'd6214;
#5 a=32'd74295;
b=32'd42942;
#5 a=32'd32479;
b=32'd57308;
//0-2147483648内的数据
#5 a=32'd409549355;
b=32'd488087536;
#5 a=32'd1423021903;
b=32'd1369264341;
#5 a=32'd1531482796;
b=32'd930145615;
#5 a=32'd53548407;
b=32'd1078897689;
#5 a=32'd732909408;
b=32'd2089361111;
#5 a=32'd911327023;
b=32'd1450555475;
#5 a=32'd1642104613;
b=32'd1011402235;
#5 a=32'd1248319996;
b=32'd381548182;
#5 a=32'd1466022704;
b=32'd117381754;
#5 a=32'd1301108757;
b=32'd1836440709;
#5 a=32'd622962793;
b=32'd926590276;
#5 a=32'd1473822608;
b=32'd1243198992;
#5 a=32'd538967954;
b=32'd1706297504;
#5 a=32'd721152411;
b=32'd1160341088;
#5 a=32'd2010200916;
b=32'd1630621188;
#5 a=32'd1486057183;
b=32'd1420968823;
#5 a=32'd862694140;
b=32'd1104825233;
#5 a=32'd1704283292;
b=32'd396429851;
#5 a=32'd388507523;
b=32'd893857814;
#5 a=32'd1412022256;
b=32'd114458402;
end
add_unit all(a,b,sum,OF);
endmodule