加法器单元可以分为全加器和半加器,半加器没有输入进位端,所以半加器时两个比特相加,而全加器时3个比特相加。如下为一个1位半加器,
而一个1位全加器单元的逻辑门数量要比半加器多,:
1.串行进位加法器
多位数相加时,直接描述产生串行进位加法器。代码如下:
//3位半加器
module(cout,sum,a,b);
output cout;
output [2:0]sum;
input [2:0]a,b;
assign {cout,sum} = a + b;
endmodule
//3位全加器,有低位向本位的进位
module(cout,sum,a,b,cin);
output cout;
output [2:0]sum;
input [2:0]a,b;
input cin;
assign {cout,sum} = a + b + cin;
endmodule
2.超前进位加法器
两个多bit位的数相加时,每一位都是带进位相加的,因为必须要使用全加器。如果采用串行进位加法器(如上代码所示)的话,只要依次将低位全加器的进位输出端(CO)接到高位全加器的进位输入端(CI)。这就每一位相加的结果都必须要等到低一位的计算结束,产生进位交给高一位的进位输入端,才可以计算高一位。由此类推,如果数值的位数多的话,那么这个串行进位加法器的输出延迟会非常的大。
为了提高运行速度,提前计算好进位信号,这样高位的全加器就不需要等待来自低位的进位信号了。怎么实现呢?因为第i位的信号都可以由两个数的第 (i-1) 位、第 (i-2) 位、…、第0位唯一地确定。第 i 进位可以用 :
以四阶超前进位加法器为例,进位的产生如下图:
代码如下:
module four_bits_fast_adder(cout,sum,a,b,cin);
output [3:0]sum;//数据累加和本位
output cout;//输出进位
input [3:0]a,b;//需要相加的数
input cin;//输入进位
wire [4:0]g,p,c;//分别对应Gi、Pi和Ci
assign c[0] = din;//最低进位为输入进位
assign P = a | b;// Pi = Ai·Bi
assign g = a & b;// Gi = Ai+Bi
assign c[1] = g[0] | (p[0]&c[0]);//对应图中 C1
assign c[2] = g[1] | ( p[1]&(g[0] | (p[0]&c[0]) );
assign c[3] = g[2] | (p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))));
assign c[4] = g[3] | (p[3]&(g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))))));
assign sum = p ^ c[3:0];
assign cout = c[4];
endmodule