分类: 数字电路

  • 超前进位加法器

    超前进位加法器

    • 超前进位加法器(carry lookahead adder, CLA),该加法器改进了行波进位加法器的关键路径,通过并行计算进位的方式解决了行波进位加法器的进位依赖问题,其进位输入是通过前面全加器的输入经逻辑运算而得。
    • CLA位数大于4时,超前进位逻辑会变得异常复杂、单元面积耗费大。于是对于大于4位的CLA使用,常将4位CLA进行级联实现,或者组间超前进位的方式实现,即进行多级超前进位。
    //4位CLA实现
    module  operator_A(
    input   A,
    input   B,
    output  P,
    output  G
    );
    
    assign  P=A^B;
    assign  G=A&B;
    
    endmodule
    
    module  operator_B(
    input   P,G,P1,G1,
    output  Po,Go
    );
    
    assign  Po=P&P1;
    assign  Go=G|(P&G1);
    
    endmodule
    
    module  operator_C(
    input   P,G,G1,
    output  Go
    );
    
    assign  Go=G|(P&G1);
    
    endmodule
    
    module CLA_4bit(
        input [3:0] i_a,
        input [3:0] i_b,
        input i_c,
        output [3:0] o_s,
        output o_c,
        output o_p, 
        output o_g
        );
    
        wire [3:0] P0, G0;
        operator_A operator_A_0(i_a[0], i_b[0], P0[0], G0[0]);
        operator_A operator_A_1(i_a[1], i_b[1], P0[1], G0[1]);
        operator_A operator_A_2(i_a[2], i_b[2], P0[2], G0[2]);
        operator_A operator_A_3(i_a[3], i_b[3], P0[3], G0[3]);
    
        wire [3:0] C;
        wire P1, G1;
        wire P2, G2;
        wire P3, G3;
    
        operator_C operator_C_0(P0[0], G0[0], i_c, C[0]);
    
        operator_B operator_B_0(P0[1], G0[1], P0[0], G0[0], P1, G1);
        operator_C operator_C_1(P1, G1, i_c, C[1]);
    
        operator_B operator_B_1(P0[2], G0[2], P1, G1, P2, G2);
        operator_C operator_C_2(P2, G2, i_c, C[2]);
    
        operator_B operator_B_2(P0[3], G0[3], P2, G2, P3, G3);
        operator_C operator_C_3(P3, G3, i_c, C[3]);
    
        assign o_s[0] = P0[0] ^ i_c;
        assign o_s[1] = P0[1] ^ C[0];
        assign o_s[2] = P0[2] ^ C[1];
        assign o_s[3] = P0[3] ^ C[2];
        assign o_c = C[3];
        assign o_p = P3;
        assign o_g = G3;
    
    endmodule
    
    //16位CLA实现
    module  operator_A(
    input   A,
    input   B,
    output  P,
    output  G
    );
    
    assign  P=A^B;
    assign  G=A&B;
    
    endmodule
    
    module  operator_B(
    input   P,G,P1,G1,
    output  Po,Go
    );
    
    assign  Po=P&P1;
    assign  Go=G|(P&G1);
    
    endmodule
    
    module  operator_C(
    input   P,G,G1,
    output  Go
    );
    
    assign  Go=G|(P&G1);
    
    endmodule
    
    module CLA_4bit(
        input [3:0] i_a,
        input [3:0] i_b,
        input i_c,
        output [3:0] o_s,
        output o_c,
        output o_p, 
        output o_g
        );
    
        wire [3:0] P0, G0;
        operator_A operator_A_0(i_a[0], i_b[0], P0[0], G0[0]);
        operator_A operator_A_1(i_a[1], i_b[1], P0[1], G0[1]);
        operator_A operator_A_2(i_a[2], i_b[2], P0[2], G0[2]);
        operator_A operator_A_3(i_a[3], i_b[3], P0[3], G0[3]);
    
        wire [3:0] C;
        wire [3:1] P1, G1;
    
        operator_C operator_C_0(P0[0], G0[0], i_c, C[0]);
    
        operator_B operator_B_0(P0[1], G0[1], P0[0], G0[0], P1[1], G1[1]);
        operator_C operator_C_1(P1[1], G1[1], i_c, C[1]);
    
        operator_B operator_B_1(P0[2], G0[2], P1[1], G1[1], P1[2], G1[2]);
        operator_C operator_C_2(P1[2], G1[2], i_c, C[2]);
    
        operator_B operator_B_2(P0[3], G0[3], P1[2], G1[2], P1[3], G1[3]);
        operator_C operator_C_3(P1[3], G1[3], i_c, C[3]);
    
        assign o_s[0] = P0[0] ^ i_c;
        assign o_s[1] = P0[1] ^ C[0];
        assign o_s[2] = P0[2] ^ C[1];
        assign o_s[3] = P0[3] ^ C[2];
        assign o_c = C[3];
        assign o_p = P1[3];
        assign o_g = G1[3];
    
    endmodule
    
    module LAC(
        input [3:0] P1,
        input [3:0] G1,
        input i_c,
        output [3:0] C,
        output o_p,
        output o_g
    );
    
        wire [3:1] P2, G2;
        operator_C operator_C_0(P1[0], G1[0], i_c, C[0]);
    
        operator_B operator_B_0(P1[1], G1[1], P1[0], G1[0], P2[1], G2[1]); 
        operator_C operator_C_1(P2[1], G2[1], i_c, C[1]);
    
        operator_B operator_B_1(P1[2], G1[2], P2[1], G2[1], P2[2], G2[2]);
        operator_C operator_C_2(P2[2], G2[2], i_c, C[2]);
    
        operator_B operator_B_2(P1[3], G1[3], P2[2], G2[2], P2[3], G2[3]);
        operator_C operator_C_3(P2[3], G2[3], i_c, C[3]);
    
        assign o_p = P2[3];
        assign o_g = G2[3];
    
    endmodule
    
    module CLA_16bit(
        input [15:0] i_a,
        input [15:0] i_b,
        input i_c,
        output [15:0] o_s,
        output o_c,
        output o_p,
        output o_g
    );
    
        wire [3:0] P, G;
        wire [3:0] C;
    
        CLA_4bit CLA_4bit_0(
            .i_a    (i_a[3:0]),
            .i_b    (i_b[3:0]),
            .i_c    (i_c),
            .o_s    (o_s[3:0]),
            .o_c    (),
            .o_p    (P[0]),
            .o_g    (G[0])
        );
    
        CLA_4bit CLA_4bit_1(
            .i_a    (i_a[7:4]),
            .i_b    (i_b[7:4]),
            .i_c    (C[0]),
            .o_s    (o_s[7:4]),
            .o_c    (),
            .o_p    (P[1]),
            .o_g    (G[1])
        );
    
        CLA_4bit CLA_4bit_2(
            .i_a    (i_a[11:8]),
            .i_b    (i_b[11:8]),
            .i_c    (C[1]),
            .o_s    (o_s[11:8]),
            .o_c    (),
            .o_p    (P[2]),
            .o_g    (G[2])
        );
    
        CLA_4bit CLA_4bit_3(
            .i_a    (i_a[15:12]),
            .i_b    (i_b[15:12]),
            .i_c    (C[2]),
            .o_s    (o_s[15:12]),
            .o_c    (),
            .o_p    (P[3]),
            .o_g    (G[3])
        );
    
        assign o_c = C[3];
    
        LAC LAC_4x4(
            .P1     (P),
            .G1     (G),
            .i_c    (i_c),
            .C      (C),
            .o_p    (o_p),
            .o_g    (o_g)
        );
    
    endmodule

    CLA相应逻辑推导如下:

  • 行波进位加法器

    行波进位加法器

    • 行波进位加法器(ripple carry adder, RCA),该加法器简单由N位1bit全加器串联而成。每个全加器的cout为下一个的cin,故称ripple carry adder。
    • 缺点在于超长的串行进位链严重限制加法器的运算速度

    接口定义如下:

    ripple_carry_addr RCA(
        input   [width-1 : 0] i_a,
        input   [width-1 : 0] i_b,
        input   i_c,
        output  [width-1 : 0] o_s,
        output  o_c
    );
    //4位RCA实现
    module  operator_A(
        input   i_a,
        input   i_b,
        input   i_c,
        output  o_s,
        output  o_c
    );
    
    assign o_s = i_a ^ i_b ^ i_c;
    //assign o_c = (i_a & i_b) | (i_c & (i_a | i_b));
    assign o_c = (i_a & i_b) | (i_c & (i_a ^ i_b));
    
    endmodule
    
    module RCA_4bit(
        input [3:0] i_a,
        input [3:0] i_b,
        input i_c,
        output [3:0] o_s,
        output o_c
        );
    
        wire [3:0] P0, G0;
        operator_A operator_A_0(i_a[0], i_b[0], i_c, P0[0], G0[0]);
        operator_A operator_A_1(i_a[1], i_b[1], G0[0], P0[1], G0[1]);
        operator_A operator_A_2(i_a[2], i_b[2], G0[1], P0[2], G0[2]);
        operator_A operator_A_3(i_a[3], i_b[3], G0[2], P0[3], G0[3]);
    
        assign o_s[0] = P0[0];
        assign o_s[1] = P0[1];    
        assign o_s[2] = P0[2];
        assign o_s[3] = P0[3];
        assign o_c = G0[3];
    
    endmodule
    //16位RCA实现
    module  operator_A(
        input   i_a,
        input   i_b,
        input   i_c,
        output  o_s,
        output  o_c
    );
    
    assign o_s = i_a ^ i_b ^ i_c;
    //assign o_c = (i_a & i_b) | (i_c & (i_a | i_b));
    assign o_c = (i_a & i_b) | (i_c & (i_a ^ i_b));
    
    endmodule
    
    module RCA_16bit(
        input [15:0] i_a,
        input [15:0] i_b,
        input i_c,
        output [15:0] o_s,
        output o_c
        );
    
        wire [15:0] P0, G0;
        operator_A operator_A_0(i_a[0], i_b[0], i_c, P0[0], G0[0]);
        operator_A operator_A_1(i_a[1], i_b[1], G0[0], P0[1], G0[1]);
        operator_A operator_A_2(i_a[2], i_b[2], G0[1], P0[2], G0[2]);
        operator_A operator_A_3(i_a[3], i_b[3], G0[2], P0[3], G0[3]);
        operator_A operator_A_4(i_a[4], i_b[4], G0[3], P0[4], G0[4]);
        operator_A operator_A_5(i_a[5], i_b[5], G0[4], P0[5], G0[5]);
        operator_A operator_A_6(i_a[6], i_b[6], G0[5], P0[6], G0[6]);
        operator_A operator_A_7(i_a[7], i_b[7], G0[6], P0[7], G0[7]);
        operator_A operator_A_8(i_a[8], i_b[8], G0[7], P0[8], G0[8]);
        operator_A operator_A_9(i_a[9], i_b[9], G0[8], P0[9], G0[9]);
        operator_A operator_A_10(i_a[10], i_b[10], G0[9], P0[10], G0[10]);
        operator_A operator_A_11(i_a[11], i_b[11], G0[10], P0[11], G0[11]);
        operator_A operator_A_12(i_a[12], i_b[12], G0[11], P0[12], G0[12]);
        operator_A operator_A_13(i_a[13], i_b[13], G0[12], P0[13], G0[13]);
        operator_A operator_A_14(i_a[14], i_b[14], G0[13], P0[14], G0[14]);
        operator_A operator_A_15(i_a[15], i_b[15], G0[14], P0[15], G0[15]);
    
        assign o_s[0] = P0[0];
        assign o_s[1] = P0[1];    
        assign o_s[2] = P0[2];
        assign o_s[3] = P0[3];
        assign o_s[4] = P0[4];
        assign o_s[5] = P0[5];
        assign o_s[6] = P0[6];
        assign o_s[7] = P0[7];
        assign o_s[8] = P0[8];
        assign o_s[9] = P0[9];
        assign o_s[10] = P0[10];
        assign o_s[11] = P0[11];
        assign o_s[12] = P0[12];
        assign o_s[13] = P0[13];
        assign o_s[14] = P0[14];
        assign o_s[15] = P0[15];
        assign o_c = G0[15]; 
    
    endmodule

    4位RCA的逻辑图如下

  • 半加器和全加器

    半加器和全加器

    半加器(half adder, HA)

    不考虑低位进位输入,接口定义为

       half_adder HA(
        input   i_a,
           input   i_b,
        output  o_s,
        output  o_c
       );

    于是一位半加器实现如下:

       assign o_s = i_a ^ i_b;
       assign o_c = i_a & i_b;
       //assign {o_c, o_s} = i_a + i_b;
    全加器(full adder, FA)

    若考虑低位进位输入,接口定义为

       full_adder FA(
        input   i_a,
        input   i_b,
        input   i_c,
        output  o_s,
        output  o_c
       );

    于是一位全加器实现如下:

       assign o_s = i_a ^ i_b ^ i_c;
       //assign o_c = (i_a & i_b) | (i_c & (i_a | i_b));
       assign o_c = (i_a & i_b) | (i_c & (i_a ^ i_b)); 
       //assign {o_c, o_s} = i_a + i_b + i_c;

    如下为FA和HA2FA的逻辑图