超前进位加法器的流水线化

建议先看我的这篇文章超前进位加法器

思想:

超前进位的思想:通过计算G和P信号,来解决后面三个16bit模块的进位信号,因此可以把高位的三个16bit模块并行起来。
流水线的做法: 在关键路径上插触发器,尽量均衡各部分的延时。

具体设计:g和p信号的计算以及G(GX)和P(PX)信号的计算,与C_in无关,因此可以单独先算出来。 通过这些进位产生/传播信号计算各模块的C_in。然后就是把关键路径尽量均分,这里插入三级触发器。

架构图如下:

自己画的架构图,按照这个架构用verilog实现并仿真验证

verilog代码实现

module adder_nocarry( 
    input A,B,C_in,
    output S
    );
    assign S = A ^ B ^ C_in;
endmodule

module adder_16bit( //超前三位计算进位信号
    input [15:0]A,B,
    input [15:0]C,
    output [15:0]Y
);
    generate 
        genvar i;
        for(i=0;i<16;i=i+1)
        begin
            adder_nocarry a (A[i],B[i],C[i],Y[i]); 
        end
    endgenerate
endmodule

module Carry_signal_cal_mode(
    input [3:0]g,p,
    input C_in,
    output [3:0]C
);
    assign C[0] = g[0] | (p[0]&C_in);
    assign C[1] = g[1] | (p[1]&g[0]) | (p[0]&p[1]&C_in) ;
    assign C[2] = g[2] | (p[2]&g[1]) | (p[2]&p[1]&g[0]) | (p[2]&p[1]&p[0]&C_in);
    assign C[3] = g[3] | (p[3]&g[2]) | (p[3]&p[2]&g[1]) | (p[3]&p[2]&p[1]&g[0]) | (p[3]&p[2]&p[1]&p[0]&C_in) ;
endmodule

module Carry_signal_cal_mode_16bit(
    input [15:0]g,p,
    input [3:0]C_in,
    output [15:0]C
);
    generate 
        genvar i;
        for(i=0;i<4;i=i+1)
        begin: carry_signal_layer2
           Carry_signal_cal_mode q (g[4*i+3:4*i],p[4*i+3:4*i],C_in[i],C[4*i+3:4*i]);
        end
    endgenerate
endmodule

module g_p_mode(
    input [63:0]A,B,
    output [63:0]g,p     
);
    generate 
        genvar i;
        for(i=0;i<64;i=i+1)
        begin: g_p
            assign g[i] = A[i] & B[i];
            assign p[i] = A[i] ^ B[i];
        end
    endgenerate
endmodule

module G_P_generator(
    input [63:0]g,p,
    output [15:0]G,P
);
    generate
        genvar i;
        for(i=0;i<16;i=1+i)
        begin: G_P_loop
            assign G[i] = g[4*i+3] | (p[4*i+3]&g[4*i+2]) | (p[4*i+3]&p[4*i+2]&g[4*i+1]) | (p[4*i+3]&p[4*i+2]&p[4*i+1]&g[4*i]) ;
            assign P[i] = p[4*i]&p[4*i+1]&p[4*i+2]&p[4*i+3];
        end
    endgenerate
endmodule

module GX_PX_generator(
    input [15:0]G,P,
    output [3:0]GX,PX
);
    generate
        genvar i;
        for(i=0;i<4;i=1+i)
        begin: G_P_loop
            assign GX[i] = G[4*i+3] | (P[4*i+3]&G[4*i+2]) | (G[4*i+3]&P[4*i+2]&G[4*i+1]) | (P[4*i+3]&P[4*i+2]&P[4*i+1]&G[4*i]) ;
            assign PX[i] = P[4*i]&P[4*i+1]&P[4*i+2]&P[4*i+3];
        end
    endgenerate
endmodule



module pipelined_adder_LKAHD(
    input clk,rst,
    input [63:0]A,B,
    input C_in,
    output [63:0]S,
    output C_out
);
    reg [127:0]L1_AB,L2_AB,L3_AB;
    reg [63:0]L1_S,L2_S,L3_S;
    reg [127:0]L1_gp,L2_gp,L3_gp;
    reg [31:0]L1_GP,L2_GP,L3_GP;
    reg [7:0]L1_GXPX,L2_GXPX,L3_GXPX;
    reg L1_Cin,L3_Cin;
    reg [3:0]L2_Cin;
   
    wire [63:0]g,p;
    wire [15:0]G,P;
    wire [3:0]GX,PX;
    
    wire [3:0]C2;
    wire [15:0]C1;
    wire [3:0]C3;
    wire [15:0]S1;
    
    wire [3:0]C2_2_1,C2_2_2,C2_2_3;
    wire [15:0]C1_2_1,C1_2_2,C1_2_3;
    wire [15:0]S2,S3,S4;
    always@(posedge clk,posedge rst)
    begin 
        if(rst)
        begin
            L1_AB<=0;
            L1_S<=0;
            L1_gp<=0;
            L1_GP<=0;
            L1_GXPX<=0;
            L1_Cin <= 0;
            L2_AB<=0;
            L2_S<=0;
            L2_gp<=0;
            L2_GP<=0;
            L2_GXPX<=0;
            L2_Cin <= 0;
            L3_AB<=0;
            L3_S<=0;
            L3_gp<=0;
            L3_GP<=0;
            L3_GXPX<=0;
            L2_Cin <= 0;
        end
        else
        begin
         // first level sequential logic 
            L1_AB <= {A,B};
            L1_S <= 64'b0;
            L1_gp <= {p,g};
            L1_GP <= {P,G};
            L1_GXPX <= {PX,GX};
            L1_Cin <= C_in;
          //second leverl sequential logic
            L2_AB <= L1_AB;
            L2_S <= {48'b0,S1};
            L2_gp <= L1_gp;
            L2_GP <= L1_GP;
            L2_GXPX <= L1_GXPX;
            L2_Cin <= C3;
          //third level sequential logic
            L3_AB <= L2_AB;
            L3_S <= {S4,S3,S2,L2_S[15:0]};
            L3_gp <= L2_gp;
            L3_GP <= L2_GP;
            L3_GXPX <= L2_GXPX;
            L3_Cin <= L2_Cin[3];
        end
    end
    // first level combined logic
    g_p_mode g_p (A,B,g,p);
    G_P_generator G_P (g,p,G,P);
    GX_PX_generator GX_PX(G,P,GX,PX);
    //secvond level combined logic
    Carry_signal_cal_mode level1_layer2 (L1_GP[3:0],L1_GP[19:16],L1_Cin, C2);
    Carry_signal_cal_mode_16bit level1_layer1(L1_gp[15:0],L1_gp[79:64],{C2[2:0],L1_Cin},C1);
    adder_16bit add1_1 (L1_AB[15:0],L1_AB[79:64],{C1[14:0],L1_Cin},S1);
    Carry_signal_cal_mode layer3 (L1_GXPX[3:0],L1_GXPX[7:4],L1_Cin,C3);
    //third level combined logic
    Carry_signal_cal_mode level2_layer2_1 (L2_GP[7:4],L2_GP[23:20],L2_Cin[0],C2_2_1);
    Carry_signal_cal_mode_16bit level2_layer1_1(L2_gp[31:16],L2_gp[95:80],{C2_2_1[2:0],L2_Cin[0]},C1_2_1);
    adder_16bit add2_1 (L2_AB[31:16],L2_AB[95:80],{C1_2_1[14:0],L2_Cin[0]},S2);
    
    Carry_signal_cal_mode level2_layer2_2 (L2_GP[11:8],L2_GP[27:24],L2_Cin[1],C2_2_2);
    Carry_signal_cal_mode_16bit level2_layer1_2(L2_gp[47:32],L2_gp[111:96],{C2_2_2[2:0],L2_Cin[1]},C1_2_2);
    adder_16bit add2_2 (L2_AB[47:32],L2_AB[111:96],{C1_2_2[14:0],L2_Cin[1]},S3);
    
    Carry_signal_cal_mode level2_layer2_3 (L2_GP[15:12],L2_GP[31:28],L2_Cin[2],C2_2_3);
    Carry_signal_cal_mode_16bit level2_layer1_3(L2_gp[63:48],L2_gp[127:112],{C2_2_3[2:0],L2_Cin[2]},C1_2_3);
    adder_16bit add2_3 (L2_AB[63:48],L2_AB[127:112],{C1_2_3[14:0],L2_Cin[2]},S4);
    
    assign S = L3_S;
    assign C_out = L3_Cin;
endmodule

TB如下


module pipelined_adder_LKAHD_tb();
    reg clk,rst;
    reg [63:0]a,b;
    reg cin;
    wire cout;
    wire [63:0]y;
    pipelined_adder_LKAHD  T4 (.clk(clk),.rst(rst),.A(a),.B(b),.C_in(cin),.S(y),.C_out(cout));
    
    always #5 clk = ~clk;
    integer i = 0;
    initial 
    begin
        rst = 1;
        clk = 0 ;
        cin = 1;
        #10
        rst = 0;
        for(i=0;i<16;i=i+1)
        begin
            a = $random;
            b = $random;
            #10;
        end
        cin = 0;
        for(i=0;i<16;i=i+1)
        begin
            a = $random;
            b = $random;
            #10;
        end
    end    
endmodule

仿真结果:仿真结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值