1. 超前进位加法器

与1bit全加器方法类似,生成信号为两数单bit与,传播信号为两数单bit或,进位则可以用如下表示。超前进位加法器相当于在算法上进行优化。

各bit进位表示如下,对于一个4bit加法器来说,最终需要得到的是C4,而C1,C2,C3,C4都可以用G、P、C0这些已知参数计算。并不需要等待低bit运算完的进位,这样就能增加并行性,从而减小加法运算延时,但是也使得电路面积增大。这种方法叫做超前进位加法器(Carry-Look ahead Adder,CLA)。

4bit超前进位加法器器综合出来的电路如下如所示,可以看到相比于行波进位加法器,其关键路径减少,布线延时和逻辑延时都会降低。

4bit超前进位加法器代码如下:

module CLA_Adder(
    input   [3:0]   a   ,
    input   [3:0]   b   ,
    input           cin ,
    output  [3:0]   sum ,
    output          cout    
    );

    wire    [3:0]   g , p , c ;

    assign g = a & b ;
    assign p = a | b ;

    assign c[0] = cin ;
    assign c[1] = g[0] | (p[0] & c[0]) ;
    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 cout = g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))));

    assign sum = a ^ b ^ c ;

endmodule

2. 进位保留加法器

进位保留加法器(Carry Save Adder,CSA)在执行多个数加法时具有极小的进位传播延迟,假设三个数相加,一般方法是先将前两个数相加,结果再与第三个数相加,而进位保留加法器的基本思想是将进位c和本位计算结果s分别保存,并且在计算时每个bit同时进行计算c和s。

假设4bit三个数如下图所示,进位保留加法器计算时,第一,先进行本位sum计算,即三个数对应bit位相加,如果有奇数个1,则sum为1,偶数个1,sum为0。第二,计算进位Carry,低位向高位进位,三个数对应bit中只要出现2个以上的1,就会产生进位,并且进位要比原来bit高1位。第三,将Carry低位补个0,sum高位补个0,使得二者位数相等,进行加法运算。

上述计算方法在电路中结构如下图所示,3个数,每个对应bit都同时并行进行加法运算,然后将c和s的结果拼接、位数补齐(c低位补0,s高位补0),再将c和s进行一次加法运算。

Vivado综合结果如下,电路delay为1个1bit加法器的delay(4个并行)+最后1个5bit加法器delay,远小于串行方式delay。CSA简化操作可以看成是在真正进行两个数加法之前的预处理操作。

进位保留加法器RTL代码如下:

module CSA_4bit(
        input       [3:0]       num1   ,
        input       [3:0]       num2   ,
        input       [3:0]       num3   ,
        output                  cout,
        output      [4:0]       sum 
    );

    wire    [4:0]   c ;
    wire    [4:0]   s ;

    assign  c[0] = 1'b0 ;
    assign  s[4] = 1'b0 ;

    assign {cout,sum} = s + c ;

    adder_1bit u0_adder_1bit (
        .a      (num1[0]   )   ,
        .b      (num2[0]   )   ,
        .cin    (num3[0]   )   ,
        .s      (s[0]      )   ,
        .cout   (c[1]      )   
    );
    adder_1bit u1_adder_1bit (
        .a      (num1[1]   )   ,
        .b      (num2[1]   )   ,
        .cin    (num3[1]   )   ,
        .s      (s[1]      )   ,
        .cout   (c[2]      )   
    );
    adder_1bit u2_adder_1bit (
        .a      (num1[2]   )   ,
        .b      (num2[2]   )   ,
        .cin    (num3[2]   )   ,
        .s      (s[2]      )   ,
        .cout   (c[3]      )   
    );
    adder_1bit u3_adder_1bit (
        .a      (num1[3]   )   ,
        .b      (num2[3]   )   ,
        .cin    (num3[3]   )   ,
        .s      (s[3]      )   ,
        .cout   (c[4]      )   
    );

endmodule

其中adder_1bit为1bit的全加器,RTL代码如下:

module adder_1bit(
    input   a   ,
    input   b   ,
    input   cin ,

    output  s   ,
    output  cout
);

wire    p ;     
wire    g ;     

assign  p = a | b ;
assign  g = a & b ;

assign  s = a ^ b ^ cin ;
assign  cout = (p & cin) | g ; 

endmodule

3. Wallace Tree

Wallace Tree可以看作是CSA的扩展,当有多个数相加时,可不断将三个数进行CSA操作,CSA进3个数,出carry和sum(2个数),和另一个CSA的结果组成三个数,再CSA操作,直到最终通过CSA简化成两个数,将这两个数通过加法器相加即可。

对于Wallace Tree结构,在进行多个数加法时,还可以使用流水线结构,可以在某个CSA之间插入寄存器,形成流水处理,这样对提升主频将会有更大的帮助。

参考资料

[1].https://www.jianshu.com/p/6ce9cad8b467
[2].https://blog.csdn.net/zhouxuanyuye/article/details/103947258
[3].https://blog.csdn.net/qq_40677883/article/details/128961549