在文章逻辑运算加法器中,介绍了两种加法运算方式,串行进位加法器
和进位选择加法器
,我们给出了逻辑门的实现并给出了C语言描述,本篇文章介绍另外一种加法计算方法:并行进位加法器
首先介绍一个概念,门延迟
。
我们知道,集成电路的主要工作单位是晶体管,晶体管虽然状态的改变非常迅速,但是毕竟有延迟,尤其随着晶体管串行数量的增大,延迟不可小觑。我们把一组电路中最大串行逻辑门的延迟门数量之和称为该电路的延迟门。延迟门是衡量电路性能的标志,下面是基本逻辑门的延迟门数量:
使用一个或门,一个与非门进行与门操作
实现的。我们从前面的文章能知道,串行进位加法器的主要性能瓶颈在于每一项的进位值需要前面的计算结果
。对于n位的两个相加的值 X X X和 Y Y Y,我们再次给出进位值和计算值的公式:
{ F i = ( X i ⨁ Y i ) ⨁ C i − 1 , 计算值 C i = ( X i C i − 1 ) + ( Y i C i − 1 ) + ( X i Y i ) , 进位值 \begin{cases} F_i = (X_i \bigoplus Y_i) \bigoplus C_{i-1},计算值\\ C_i = (X_i C_{i-1}) + (Y_i C_{i-1}) + (X_i Y_i ),进位值 \end{cases} {Fi=(Xi⨁Yi)⨁Ci−1,计算值Ci=(XiCi−1)+(YiCi−1)+(XiYi),进位值
用电路表示 C i C_i Ci的值为,可以看到进位的计算的门延迟是2:
根据布尔运算
C i = ( X i C i − 1 ) + ( Y i C i − 1 ) + ( X i Y i ) = X i Y i + ( X i + Y i ) C i − 1 C_i =(X_i C_{i-1}) + (Y_i C_{i-1}) + (X_i Y_i ) = X_i Y_i + (X_i+Y_i)C_{i-1} Ci=(XiCi−1)+(YiCi−1)+(XiYi)=XiYi+(Xi+Yi)Ci−1
也就是说:
C 1 = X 1 Y 1 + ( X 1 + Y 1 ) C 0 C_1 = X_1 Y_1 + (X_1+Y_1)C_{0} C1=X1Y1+(X1+Y1)C0
C 2 = X 2 Y 2 + ( X 2 + Y 2 ) C 1 = X 2 Y 2 + ( X 2 + Y 2 ) ( X 1 Y 1 + ( X 1 + Y 1 ) C 0 ) = X 2 Y 2 + ( X 2 + Y 2 ) ( X 1 Y 1 ) + ( X 2 + Y 2 ) ( X 1 + Y 1 ) C 0 \begin{aligned} C_2 &= X_2 Y_2 + (X_2+Y_2)C_{1}\\ &=X_2 Y_2 + (X_2+Y_2)(X_1 Y_1 + (X_1+Y_1)C_{0})\\ &=X_2 Y_2 + (X_2+Y_2)(X_1 Y_1) + (X_2+Y_2)(X_1+Y_1)C_{0} \end{aligned} C2=X2Y2+(X2+Y2)C1=X2Y2+(X2+Y2)(X1Y1+(X1+Y1)C0)=X2Y2+(X2+Y2)(X1Y1)+(X2+Y2)(X1+Y1)C0
C 3 = X 3 Y 3 + ( X 3 + Y 3 ) C 2 = X 3 Y 3 + ( X 3 + Y 3 ) ( X 2 Y 2 + ( X 2 + Y 2 ) ( X 1 Y 1 ) + ( X 2 + Y 2 ) ( X 1 + Y 1 ) C 0 ) = X 3 Y 3 + ( X 3 + Y 3 ) ( X 2 Y 2 ) + ( X 3 + Y 3 ) ( X 2 + Y 2 ) ( X 1 Y 1 ) + ( X 3 + Y 3 ) ( X 2 + Y 2 ) ( X 1 + Y 1 ) C 0 \begin{aligned} C_3 &= X_3 Y_3 + (X_3+Y_3)C_{2}\\ &=X_3 Y_3 + (X_3+Y_3)(X_2 Y_2 + (X_2+Y_2)(X_1 Y_1) + (X_2+Y_2)(X_1+Y_1)C_{0})\\ &=X_3 Y_3 + (X_3+Y_3)(X_2 Y_2) + (X_3+Y_3)(X_2+Y_2)(X_1 Y_1)+(X_3+Y_3)(X_2+Y_2)(X_1+Y_1)C_{0} \end{aligned} C3=X3Y3+(X3+Y3)C2=X3Y3+(X3+Y3)(X2Y2+(X2+Y2)(X1Y1)+(X2+Y2)(X1+Y1)C0)=X3Y3+(X3+Y3)(X2Y2)+(X3+Y3)(X2+Y2)(X1Y1)+(X3+Y3)(X2+Y2)(X1+Y1)C0
我们假设 P i = X i + Y i P_i = X_i+Y_i Pi=Xi+Yi, G i = X i Y i G_i = X_iY_i Gi=XiYi,也就是 P i P_i Pi是一个逻辑或门, G i G_i Gi是一个逻辑与门,上面的公式可以写成如下形式:
C 1 = G 1 + P 1 C 0 C_1 = G_1 + P_1C_{0} C1=G1+P1C0
C 2 = G 2 + P 2 G 1 + P 2 P 1 C 0 C_2= G_2 + P_2G_1+ P_2P_1C_{0} C2=G2+P2G1+P2P1C0
C 3 = G 3 + P 3 G 2 + P 3 P 2 G 1 + P 3 P 2 P 1 C 0 C_3= G_3 + P_3G_2+P_3P_2G_1+P_3P_2P_1C_{0} C3=G3+P3G2+P3P2G1+P3P2P1C0
同理:
C 4 = G 4 + P 4 G 3 + P 4 P 3 G 2 + P 4 P 3 P 2 G 1 + P 4 P 3 P 2 P 1 C 0 C_4= G_4 + P_4G_3+P_4P_3G_2+P_4P_3P_2G_1+P_4P_3P_2P_1C_{0} C4=G4+P4G3+P4P3G2+P4P3P2G1+P4P3P2P1C0
即然 C 4 、 C 3 、 C 2 、 C 1 C_4、C_3、C_2、C_1 C4、C3、C2、C1都能使用 C 0 C_0 C0来表示,那么我们就可以通过设计电路来同时计算
C 4 、 C 3 、 C 2 、 C 1 C_4、C_3、C_2、C_1 C4、C3、C2、C1的值,然后根据计算后的值进行每一位的加法运算。设计后电路图如下:
上面的电路称为先行进位部件
,简称CLA(Carry Lookahead Unit)
我们把输入的 X 、 Y X、Y X、Y和数值位的计算添加进来,然后把 C i C_i Ci的值也添加到加法器,这样便组成了一个全先行进位加法
,电路图如下:
我们看一下上面电路的门延迟:
并行
着,并且 M i = X i ⨁ Y i M_i = X_i \bigoplus Y_i Mi=Xi⨁Yi异或操作门延迟正好也是3,也就是到现在为止,一共的门延迟为3所有的门延迟一共为6
下面,给出CLA电路的C语言描述:
/**
* CLA电路的C语言描述,计算4位的加法值
* in_1:输入X
* in_2:输入Y
* c0:默认的进位项
*/
extern long alu_add_cla(long in_1, long in_2, long* c0);
long alu_add_cla(long in_1, long in_2, long* c0)
{
// 初始结果为0
long result = 0;
// 下面这四组并行,每一组在电路中需要1级门延迟
long x1 = alu_bit(in_1, 0); // 获取输入1的第0位
long y1 = alu_bit(in_2, 0); // 获取输入2的第0位
long p1 = or_gate(x1, y1);
long g1 = and_gate(x1, y1);
long x2 = alu_bit(in_1, 1); // 获取输入1的第1位
long y2 = alu_bit(in_2, 1); // 获取输入2的第1位
long p2 = or_gate(x2, y2);
long g2 = and_gate(x2, y2);
long x3 = alu_bit(in_1, 2); // 获取输入1的第2位
long y3 = alu_bit(in_2, 2); // 获取输入2的第2位
long p3 = or_gate(x3, y3);
long g3 = and_gate(x3, y3);
long x4 = alu_bit(in_1, 3); // 获取输入1的第3位
long y4 = alu_bit(in_2, 3); // 获取输入2的第3位
long p4 = or_gate(x4, y4);
long g4 = and_gate(x4, y4);
// CLA电路实现,需要门延迟2
long c1 = or_gate(g1, and_gate(p1, *c0));
long c2 = or_gate(or_gate(g2, and_gate(p2, g1)),and_gate(and_gate(p2, p1), *c0));
long c3 = or_gate(or_gate(or_gate(g3, and_gate(p3, g2)), and_gate(and_gate(p3, p2), g1)), and_gate(and_gate(and_gate(p3, p2), p1), *c0));
long c4 = or_gate(or_gate(or_gate(or_gate(g4, and_gate(p4, g3)), and_gate(and_gate(p4, p3), g2)), and_gate(and_gate(and_gate(p4, p3), p2), g1)), and_gate(and_gate(and_gate(and_gate(p4, p3), p2), p1), *c0));
// 异或操作,门延迟3,与上面的并行
long m1 = xor_gate(x1, y1);
long m2 = xor_gate(x2, y2);
long m3 = xor_gate(x3, y3);
long m4 = xor_gate(x4, y4);
// 最后的异或计算,门延迟3
long r1 = xor_gate(m1, *c0);
long r2 = xor_gate(m2, c1);
long r3 = xor_gate(m3, c2);
long r4 = xor_gate(m4, c3);
result |= r4<<3;
result |= r3<<2;
result |= r2<<1;
result |= r1;
// 将进位值返回给c0
*c0 = c4;
return result;
}
有了四位的全先行进位加法器我们可以实现多位的加法器了,这里还可以分为两种:
首先看第一种:
单级先行进位加法器是将 n n n个全先行进位加法器串起来,可以实现 4 n 4n 4n位的加法运算,我们计算一下对于 4 n 4n 4n位的单级先行进位加法器,门延迟是多少?
一共消耗2n+2个门延迟
现在我们可以给出64位加法器的C语言描述了,因为有了之前CLA的定义,非常简单:
/**
* CLA电路的串行加法器
* in_1:输入X
* in_2:输入Y
* bits:计算的位数
* c0:默认的进位项
*/
extern long alu_add_cla_64(long in_1, long in_2,long bits, long* c0);
long alu_add_cla_64(long in_1, long in_2,long bits, long* c0)
{
long result = 0;
for(int i = 0;i>i,in_2>>i,c0)<
输出结果为:
r0 = -115
r1 = 681
最后,我们在研究一下多级先行进位加法器,所谓多级先行进位加法器就是将多个全先行进位加法器并起来,而不是串起来
,先看一下16位的两级先行进位加法器,整个逻辑是下面这个样子:
好了,了解了两级先行进位加法器以后,就可以构建三级的先行进位加法器。三级能够进行64位的加减操作,对于我们目前来说足够了,并且三级的并行操作能使性能达到最优。
三级的先行进位加法器构建如下:
最后,给出三级先行进位加法器的C语言描述,代码比较多,为了展示电路级别的操作,逻辑写的比较复杂,其实实际上很多操作都是并行触发的
/**
* 三级先行进位加法器
* in_1:输入X
* in_2:输入Y
* bits:计算的位数
* c0:默认的进位项
* return:返回计算结果
*/
extern long alu_add_bcla_64(long in_1, long in_2,long bits, long* c0);
long alu_add_bcla_64(long in_1, long in_2,long bits, long* c0)
{
// 计算p、g,一共64位
long out_p = alu_or(in_1, in_2,sizeof(long)*8);
long out_g = alu_and(in_1, in_2,sizeof(long)*8);
// 第二级p、g,一共16位
long out_pm=0;
long out_gm=0;
// 第三极p、g,一共4位
long out_pm2=0;
long out_gm2=0;
// 计算第二级p、g,应该是并行的
for(int i=0;i<16;i++)
{
long p4 =alu_bit(out_p,i*4+3);
long p3 =alu_bit(out_p,i*4+2);
long p2 =alu_bit(out_p,i*4+1);
long p1 =alu_bit(out_p,i*4+0);
long g4 =alu_bit(out_g,i*4+3);
long g3 =alu_bit(out_g,i*4+2);
long g2 =alu_bit(out_g,i*4+1);
long g1 =alu_bit(out_g,i*4+0);
out_pm|=((and_gate(and_gate(and_gate(p4, p3), p2), p1))<
结果为:
r0 = -115
r1 = 681
我们从不断优化的方案可以看出时间和空间的权衡方案,性能和速度的提升几乎必然伴随着电路的复杂度提高,需要更多的空间来安排电路的排线,需要更多的空间来放置更多的逻辑门。本篇文章完成时,荷兰的2纳米光刻机已经开始交付给intel。可预见的是,集成电路还会有大幅提升的空间。