精华内容
下载资源
问答
  • 行波进位加法器八位超前进位加法器原理设计文件综合电路测试文件仿真波形八位行波进位加法器原理设计文件测试文件仿真波形总结八位超前进位加法器原理有学弟问我,超前进位加法器中的p=add1 ^ add2和g=add1 &...

    超前进位加法器&行波进位加法器

    • 八位超前进位加法器

      • 原理

      • 设计文件

      • 综合电路

      • 测试文件

      • 仿真波形

    • 八位行波进位加法器

      • 原理

      • 设计文件

      • 测试文件

      • 仿真波形

    • 总结

    八位超前进位加法器

    原理

    有学弟问我,超前进位加法器中的p=add1 ^ add2g=add1 & add2是什么意思,所以这篇文章就稍微赘述一点吧~

    所谓超前进位,首先应该明白进位是什么。

    8+4=12,其中的1就是进位,其中的2才是结果。

    那么在二进制中,1+1=10,其中的1就是进位,0就是结果。

    明白了进位和结果,那么多位的数字是怎么计算呢?

    其实上面的计算应该是1+1+上一位的进位=10,所以两个数字的计算应该涉及三个内容——加数,被加数,上一位的进位。

    在一位二进制加法中,ab分别表示两个加数,cin表示上一位的进位,cout表示下一位的进位,sum表示结果,我们列出其真值表:

    add1add2cincoutsum
    00000
    01001
    10001
    11010
    00101
    01110
    10110
    11111

    以数字**1为真**,数字**0为假**,a表示1a'表示0,这样的形式。学过离散数学或者数字电路的同学应该多少会点吧,“·”代表“与”“+”代表“或”,所以上面的真值表,写成表达式,就是:

    经过部分化简:

    同理:

    找到两个等式的相同部分,都有a⊕b其中代表“异或”,在Verilog中用“^”表示,即a^b,所以令p = add1 ^ add2,现在知道干什么用的了嘛?

    没错,就是中间变量而已,同理g = add1 & add2也是中间变量,这样就可以把上面两个等式改写成:cout = g | (cin & p)sum = add1 ^ add2 ^ cin(其实就是变短了一点点而已)

    不过呢,适当的使用中间变量,可能会让你的代码精简许多~

    此外,我发现一个网站可以通过真值表生成表达式:http://www.32x8.com/index.html

    设计文件

    module add_8_1(
        input wire [7:0] add1,
        input wire [7:0] add2,
        input wire cin,
        output wire [7:0] sum,
        output wire cout
        );
        wire[7:0] g,p,c;//g和p的含义已经讲解了,c代表每一位计算的进位,c[0]表示原始的进位cin
        assign c[0]=cin;
        assign p=add1 ^ add2;
        assign g=add1 & add2;
        assign c[0] = g[0] | (p[0] & c[0]);
        assign c[1] = g[1] | (p[1] & (g[0] | (p[0] & c[0])));
        assign c[2] = g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))));
        assign c[3] = g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))));
        assign c[4] = g[4] | (p[4] & (g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))))));
        assign c[5] = g[5] | (p[5] & (g[4] | (p[4] & (g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))))))));
        assign c[6] = g[6] | (p[6] & (g[5] | (p[5] & (g[4] | (p[4] & (g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))))))))));
        assign c[7] = g[7] | (p[7] & (g[6] | (p[6] & (g[5] | (p[5] & (g[4] | (p[4] & (g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))))))))))));
        assign sum=p^c[7:0];
        assign cout=c[7];
    endmodule

    上面的代码应该看起来很长,像老太太的裹脚布,但这也就是所谓的超前进位

    Verilog中“块”和assign语句都是并行执行的,上面有许多assign语句,所以从c[0]c[7],根据第一步的cin,就可以同步计算出每一位的进位(超前进位),以及最后的结果,这些是同时完成的,也就完成了超前进位加法器。

    综合电路

    0016f846c0a4de8d4489431c6411cecf.png

    点击RTL-ANALYSIS——Synthesis,可以查看综合电路图:

    19个元件,26IO口,56根线

    ce43452a8daac69595a15cf188b5af63.png

    测试文件

    `timescale 1ns / 1ps
    module add_tb();
        reg [7:0] add1,add2;
        reg cin;
        reg clk;
        wire [7:0] sum;
        wire cout;
        initial begin
            add1 <= 8'd10;
            add2 <= 8'd3;
            cin <= 1'b0;     
            clk <= 1'b0;   
        end
        
        always # 10 clk = ~clk;
        always @ (negedge clk) begin
            {add1,add2} <= {add1,add2} + 1'b1;
        end

        add_8_1 try(.add1(add1),.add2(add2),.cin(cin),.sum(sum),.cout(cout));
        
    endmodule

    还有些同学,对测试文件的理解也还是不够深刻,这里稍提一嘴,测试文件就是给电路加激励信息,使电路运作。至于加提示信息之类的,各自加油就好啦~

    仿真波形

    fa0d8e2a1a03e811378257c5c4ced05f.png
    0c44a0ee9b56e845b8c3461da4636512.png

    右键某一信号,选择相应的进制数,以10+9为例,最终输出cout=0sum=19

    那么之后的10+11为什么没有进位使cout=1呢?

    把他们转换成二进制观察一下就明白啦~

    八位行波进位加法器

    当时不知道在哪听的这个名字,就一直用下了,其实这个应该叫做行波进位加法器——由N个全加器级联而成,所以被我叫成了级联进位emmm

    原理

    如上所说,行波进位加法器是由N个全加器级联而成,比如8位的加法器可以由8个一位全加器级联而成,也可以由2个四位全加器构成,区别就是所综合出的电路大小。

    设计文件

    方式一

    module add_8_2(
        input wire [7:0] add1,add2,
        input wire cin,
        output reg [7:0] sum,
        output reg cout
    );
        reg[7:0] G,P,C; 
    always @(add1 or add2 or cin)
    begin
        G[0] = add1[0] & add2[0]; 
        P[0] = add1[0] ^ add2[0]; 
        C[0] = cin; //最低位的进位输入,即cin
        sum[0] = G[0]^ P[0] ^ C[0];//第一位的计算结果
        G[1] = add1[1] & add2[1];
        P[1] = add1[1] ^ add2[1];
        C[1] = G[0] |(P[0] & C[0]);//c=add1add2+(add1+add2)cin=G|(P&cin)
        sum[1] = G[1] ^ P[1] ^ C[1];
        G[2] = add1[2] & add2[2];
        P[2] = add1[2] ^ add2[2];
        C[2] = G[1] |(P[1] & C[1]);
        sum[2] = G[2] ^ P[2] ^ C[2];
        G[3] = add1[3]& add2[3];
        P[3] = add1[3] ^ add2[3];
        C[3] = G[2] |(P[2] & C[2]);
        sum[3] = G[3] ^ P[3] ^ C[3];
        G[4] = add1[4] & add2[4];
        P[4] = add1[4] ^ add2[4];
        C[4] = G[3] |(P[3] & C[3]);
        sum[4] = G[4] ^ P[4] ^ C[4];
        G[5] = add1[5] & add2[5];
        P[5] = add1[5] ^ add2[5];
        C[5] = G[4] |(P[4] & C[4]);
        sum[5] = G[5] ^ P[5] ^ C[5];
        G[6] = add1[6] & add2[6];
        P[6] = add1[6] ^ add2[6];
        C[6] = G[5] |(P[5] & C[5]);
        sum[6] = G[6] ^ P[6] ^ C[6];
        G[7] = add1[7] & add2[7];
        P[7] = add1[7] ^ add2[7];
        C[7] = G[6] |(P[6] & C[6]);
        sum[7] = G[7] ^ P[7] ^ C[7];
        cout = G[7] |(P[7] & C[7]);
    end
    endmodule

    这是把上述原理复现了一边,上一步的进位输出,传入到下一位计算的进位输入。

    综合后的电路如下,48个元件,26IO口,65根线

    综合电路

    328754c7bf6e73b155bad623cba97189.png

    方式二

    上面的语句重复性太大,就用模块例化的方式来写

    module add_8_2(
        input wire [7:0] add1,add2,
        input wire cin,
        output wire [7:0] sum,
        output wire cout
    );
        wire [6:0] c;
        add_1_unit a1(add1[0],add2[0],cin,c[0],sum[0]);
        add_1_unit a2(add1[1],add2[1],c[0],c[1],sum[1]);
        add_1_unit a3(add1[2],add2[2],c[1],c[2],sum[2]);
        add_1_unit a4(add1[3],add2[3],c[2],c[3],sum[3]);
        add_1_unit a5(add1[4],add2[4],c[3],c[4],sum[4]);
        add_1_unit a6(add1[5],add2[5],c[4],c[5],sum[5]);
        add_1_unit a7(add1[6],add2[6],c[5],c[6],sum[6]);
        add_1_unit a8(add1[7],add2[7],c[6],cout,sum[7]);
    endmodule

    其中的add_1_unit模块如下:

    module add_1_unit(
        input wire add1,add2,cin,
        output wire cout,sum
        );
        assign cout = (add1 & add2) | (cin & (add1 ^ add2));
        assign sum = add1 ^ add2 ^ cin;    
    endmodule

    综合后的电路如下,全展开后有48个元件,26IO口,97根线

    综合电路

    05b76e424782d2b1b9d3414dc7c57bf2.png

    其中的每一个单元如下:

    28f04910bc045fb83ca440c90b61f215.png全展开后如下:5e09adddc3439d8b8db89e126039f21c.png

    两种写法

    数据总线的数量有区别:一个是65根线,一个是97根线。

    代码量有区别:一个40行左右,一个总共27行左右。

    优缺点不言而喻。

    测试文件

    都是八位加法器,与超前进位加法器也没区别

    还是放一下吧:

    `timescale 1ns / 1ps
    module add_tb();
        reg [7:0] add1,add2;
        reg cin;
        reg clk;
        wire [7:0] sum;
        wire cout;
        initial begin
            add1 <= 8'd10;
            add2 <= 8'd3;
            cin <= 1'b0;     
            clk <= 1'b0;   
        end
        
        always # 10 clk = ~clk;
        always @ (negedge clk) begin
            {add1,add2} <= {add1,add2} + 1'b1;
        end

        add_8_2 try(.add1(add1),.add2(add2),.cin(cin),.sum(sum),.cout(cout));
        
    endmodule

    仿真波形

    与超前进位一致,用二进制查看一下如下图:

    0e8875c496b9ca1dc310c1217990a2e1.png

    总结

    行波进位加法器,由于后一位的进位依赖于前一位的进位,所以关键路径更长,限制速度,性能不高,

    超前进位加法器,由于进位计算是并行的,所以关键路径短,速度快,但是位宽越宽,也就代表会综合出更复杂的、面积更大的电路。

    展开全文
  • 行波进位加法器八位超前进位加法器原理设计文件综合电路测试文件仿真波形八位行波进位加法器原理设计文件测试文件仿真波形总结八位超前进位加法器原理 有学弟问我,超前进位加法器中的p=add1 ^ add2和g=add1 &...

    超前进位加法器&行波进位加法器

    • 八位超前进位加法器
      • 原理
      • 设计文件
      • 综合电路
      • 测试文件
      • 仿真波形
    • 八位行波进位加法器
      • 原理
      • 设计文件
      • 测试文件
      • 仿真波形
    • 总结

    八位超前进位加法器

    原理

    有学弟问我,超前进位加法器中的p=add1 ^ add2g=add1 & add2是什么意思,所以这篇文章就稍微赘述一点吧~

    所谓超前进位,首先应该明白进位是什么。

    8+4=12,其中的1就是进位,其中的2才是结果。

    那么在二进制中,1+1=10,其中的1就是进位,0就是结果。

    明白了进位和结果,那么多位的数字是怎么计算呢?

    其实上面的计算应该是1+1+上一位的进位=10,所以两个数字的计算应该涉及三个内容——加数,被加数,上一位的进位。

    在一位二进制加法中,ab分别表示两个加数,cin表示上一位的进位,cout表示下一位的进位,sum表示结果,我们列出其真值表:

    add1add2cincoutsum

    以数字 1为真 ,数字0为假a表示1a'表示0,这样的形式。学过离散数学或者数字电路的同学应该多少会点吧,“·”代表“与”“+”代表“或”,所以上面的真值表,写成表达式,就是:

    经过部分化简:

    同理:

    找到两个等式的相同部分,都有a⊕b其中代表“异或”,在Verilog中用“^”表示,即a^b,所以令p = add1 ^ add2,现在知道干什么用的了嘛?

    没错,就是中间变量而已,同理g = add1 & add2也是中间变量,这样就可以把上面两个等式改写成:cout = g | (cin & p)sum = add1 ^ add2 ^ cin(其实就是变短了一点点而已)

    不过呢,适当的使用中间变量,可能会让你的代码精简许多~

    此外,我发现一个网站可以通过真值表生成表达式:http://www.32x8.com/index.html

    设计文件

    module add_8_1(
        input wire [7:0] add1,
        input wire [7:0] add2,
        input wire cin,
        output wire [7:0] sum,
        output wire cout
        );
        wire[7:0] g,p,c;//g和p的含义已经讲解了,c代表每一位计算的进位,c[0]表示原始的进位cin
        assign c[0]=cin;
        assign p=add1 ^ add2;
        assign g=add1 & add2;
        assign c[0] = g[0] | (p[0] & c[0]);
        assign c[1] = g[1] | (p[1] & (g[0] | (p[0] & c[0])));
        assign c[2] = g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))));
        assign c[3] = g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))));
        assign c[4] = g[4] | (p[4] & (g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))))));
        assign c[5] = g[5] | (p[5] & (g[4] | (p[4] & (g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))))))));
        assign c[6] = g[6] | (p[6] & (g[5] | (p[5] & (g[4] | (p[4] & (g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))))))))));
        assign c[7] = g[7] | (p[7] & (g[6] | (p[6] & (g[5] | (p[5] & (g[4] | (p[4] & (g[3] | (p[3] & (g[2] | (p[2] & (g[1] | (p[1] & (g[0] | (p[0] & c[0])))))))))))))));
        assign sum=p^c[7:0];
        assign cout=c[7];
    endmodule
    

    上面的代码应该看起来很长,像老太太的裹脚布,但这也就是所谓的超前进位

    Verilog中“块”和assign语句都是并行执行的,上面有许多assign语句,所以从c[0]c[7],根据第一步的cin,就可以同步计算出每一位的进位(超前进位),以及最后的结果,这些是同时完成的,也就完成了超前进位加法器。

    综合电路

    dc17a3b8abdffc1b97b0c24bc03b427f.png

    点击RTL-ANALYSIS——Synthesis,可以查看综合电路图:

    19个元件,26IO口,56根线

    d8a3197c4fde9ebe92b3e7090498c436.png

    测试文件

    `timescale 1ns / 1ps
    module add_tb();
        reg [7:0] add1,add2;
        reg cin;
        reg clk;
        wire [7:0] sum;
        wire cout;
        initial begin
            add1 <= 8'd10;
            add2 <= 8'd3;
            cin <= 1'b0;     
            clk <= 1'b0;   
        end
        
        always # 10 clk = ~clk;
        always @ (negedge clk) begin
            {add1,add2} <= {add1,add2} + 1'b1;
        end
    
        add_8_1 try(.add1(add1),.add2(add2),.cin(cin),.sum(sum),.cout(cout));
        
    endmodule
    

    还有些同学,对测试文件的理解也还是不够深刻,这里稍提一嘴,测试文件就是给电路加激励信息,使电路运作。至于加提示信息之类的,各自加油就好啦~

    仿真波形

    0121ce3beae81c05908bec307a82a041.png

    0fcd854f6a33e0d0b559073c2fc08b8a.png

    右键某一信号,选择相应的进制数,以10+9为例,最终输出cout=0sum=19

    那么之后的10+11为什么没有进位使cout=1呢?

    把他们转换成二进制观察一下就明白啦~

    八位行波进位加法器

    当时不知道在哪听的这个名字,就一直用下了,其实这个应该叫做行波进位加法器——由N个全加器级联而成,所以被我叫成了级联进位emmm

    原理

    如上所说,行波进位加法器是由N个全加器级联而成,比如8位的加法器可以由8个一位全加器级联而成,也可以由2个四位全加器构成,区别就是所综合出的电路大小。

    设计文件

    方式一

    module add_8_2(
        input wire [7:0] add1,add2,
        input wire cin,
        output reg [7:0] sum,
        output reg cout
    );
        reg[7:0] G,P,C; 
    always @(add1 or add2 or cin)
    begin
        G[0] = add1[0] & add2[0]; 
        P[0] = add1[0] ^ add2[0]; 
        C[0] = cin; //最低位的进位输入,即cin
        sum[0] = G[0]^ P[0] ^ C[0];//第一位的计算结果
        G[1] = add1[1] & add2[1];
        P[1] = add1[1] ^ add2[1];
        C[1] = G[0] |(P[0] & C[0]);//c=add1add2+(add1+add2)cin=G|(P&cin)
        sum[1] = G[1] ^ P[1] ^ C[1];
        G[2] = add1[2] & add2[2];
        P[2] = add1[2] ^ add2[2];
        C[2] = G[1] |(P[1] & C[1]);
        sum[2] = G[2] ^ P[2] ^ C[2];
        G[3] = add1[3]& add2[3];
        P[3] = add1[3] ^ add2[3];
        C[3] = G[2] |(P[2] & C[2]);
        sum[3] = G[3] ^ P[3] ^ C[3];
        G[4] = add1[4] & add2[4];
        P[4] = add1[4] ^ add2[4];
        C[4] = G[3] |(P[3] & C[3]);
        sum[4] = G[4] ^ P[4] ^ C[4];
        G[5] = add1[5] & add2[5];
        P[5] = add1[5] ^ add2[5];
        C[5] = G[4] |(P[4] & C[4]);
        sum[5] = G[5] ^ P[5] ^ C[5];
        G[6] = add1[6] & add2[6];
        P[6] = add1[6] ^ add2[6];
        C[6] = G[5] |(P[5] & C[5]);
        sum[6] = G[6] ^ P[6] ^ C[6];
        G[7] = add1[7] & add2[7];
        P[7] = add1[7] ^ add2[7];
        C[7] = G[6] |(P[6] & C[6]);
        sum[7] = G[7] ^ P[7] ^ C[7];
        cout = G[7] |(P[7] & C[7]);
    end
    endmodule
    

    这是把上述原理复现了一边,上一步的进位输出,传入到下一位计算的进位输入。

    综合后的电路如下,48个元件,26IO口,65根线

    综合电路

    1c4b985b3a5059d63afde58b9d4a740c.png

    方式二

    上面的语句重复性太大,就用模块例化的方式来写

    module add_8_2(
        input wire [7:0] add1,add2,
        input wire cin,
        output wire [7:0] sum,
        output wire cout
    );
        wire [6:0] c;
        add_1_unit a1(add1[0],add2[0],cin,c[0],sum[0]);
        add_1_unit a2(add1[1],add2[1],c[0],c[1],sum[1]);
        add_1_unit a3(add1[2],add2[2],c[1],c[2],sum[2]);
        add_1_unit a4(add1[3],add2[3],c[2],c[3],sum[3]);
        add_1_unit a5(add1[4],add2[4],c[3],c[4],sum[4]);
        add_1_unit a6(add1[5],add2[5],c[4],c[5],sum[5]);
        add_1_unit a7(add1[6],add2[6],c[5],c[6],sum[6]);
        add_1_unit a8(add1[7],add2[7],c[6],cout,sum[7]);
    endmodule
    

    其中的add_1_unit模块如下:

    module add_1_unit(
        input wire add1,add2,cin,
        output wire cout,sum
        );
        assign cout = (add1 & add2) | (cin & (add1 ^ add2));
        assign sum = add1 ^ add2 ^ cin;    
    endmodule
    

    综合后的电路如下,全展开后有48个元件,26IO口,97根线

    综合电路

    9abebd1904a0ec22df7e2eedd58af1ee.png

    其中的每一个单元如下:

    6a554719df7e21f4a71d28dca645fe09.png

    全展开后如下:

    93dd7b7cf927ab415532bfc1cf3bc391.png

    两种写法

    数据总线的数量有区别:一个是65根线,一个是97根线。

    代码量有区别:一个40行左右,一个总共27行左右。

    优缺点不言而喻。

    测试文件

    都是八位加法器,与超前进位加法器也没区别

    还是放一下吧:

    `timescale 1ns / 1ps
    module add_tb();
        reg [7:0] add1,add2;
        reg cin;
        reg clk;
        wire [7:0] sum;
        wire cout;
        initial begin
            add1 <= 8'd10;
            add2 <= 8'd3;
            cin <= 1'b0;     
            clk <= 1'b0;   
        end
        
        always # 10 clk = ~clk;
        always @ (negedge clk) begin
            {add1,add2} <= {add1,add2} + 1'b1;
        end
    
        add_8_2 try(.add1(add1),.add2(add2),.cin(cin),.sum(sum),.cout(cout));
        
    endmodule
    

    仿真波形

    与超前进位一致,用二进制查看一下如下图:

    9106bb7156baeb6fd66228c45888076b.png

    总结

    行波进位加法器,由于后一位的进位依赖于前一位的进位,所以关键路径更长,限制速度,性能不高,

    超前进位加法器,由于进位计算是并行的,所以关键路径短,速度快,但是位宽越宽,也就代表会综合出更复杂的、面积更大的电路。

    展开全文
  • 半加器module 全加器module 行波进位加法器十分简单,直接串联n个全加器即可得到n位行波进位加法器,但字长较大时速度太慢module 超前进位加法器下面这篇文章讲清楚了原理如何用基本的逻辑门设计32bit的超前进位加法...

    半加器

    module 

    全加器

    module 

    行波进位加法器

    十分简单,直接串联n个全加器即可得到n位行波进位加法器,但字长较大时速度太慢

    module 

    超前进位加法器

    下面这篇文章讲清楚了原理

    如何用基本的逻辑门设计32bit的超前进位加法器?www.zhihu.com
    1b3a80636e6e0d67968f6e6b02bd04ab.png

    速度很快,但字长较大时面积太大

    module 

    复合加法器

    字长较大时,为了平衡面积和速度,同时采用行波进位和超前进位

    例如16位加法器将拆分为四个4位加法器,每个4位加法器内部使用超前进位,四个加法器之间使用行波进位,直接串联

    module 
    展开全文
  • 上期介绍了半加器、全加器以及行波进位加法器(RCA),本文介绍超前进位加法器(Lookahead Carry Adder,简称LCA)。在介绍超前进位加法器前,我们先来分析下行波进位加法器的关键路径。一、行波进位加法器关键路径...

    fd8dd27ba640d2598722289345ba5ffa.png

    上期介绍了半加器、全加器以及行波进位加法器(RCA),本文介绍超前进位加法器(Lookahead Carry Adder,简称LCA)。在介绍超前进位加法器前,我们先来分析下行波进位加法器的关键路径。

    一、行波进位加法器关键路径分析

    N比特行波进位加法器可由N个全加器级联而成,电路的延迟包括门延迟和线延迟等,分析忽略线延迟。

    ca5b40ee4dfc8bc84e78944642f62702.png
    单比特全加器门电路图

    从输入a,b,cin到输出s和cout,有以下路径:

    • a->s:经过xor1,xor2两个门电路
    • b->s:经过xor1,xor2两个门电路
    • cin->s:经过xor2一个门店路
    • a->cout:经过xor1,and1,or1三个门电路
    • b->cout:经过xor1,and1,or1三个门电路
    • cin->cout:经过and2,or1两个门电路

    由这些路径可知,从a,b,cin输入数据准备好,到所有的s和cout完成,a或b到cout共有三个门电路延迟,是全加器的最长路径,且s不参与下一级全加器运算,cout将作为下一个cin输入继续计算下一级的s和cout。

    e8abca31ba4427a7627a3fb57efc78d0.png
    4比特行波进位加法器关键路径

    由N个全加器级联的行波进位加法器除了第一个进位c1有3个门延迟外,剩余N-1个全加器生成进位需要2个门电路延迟,所以N比特行波进位加法器最长路径共有“(3+(N-1)*2)=2N+1”个门电路延迟,如上图4比特行波进位加法器,红色描绘的路径即是最长路径,共有2*4+1=9个门电路延迟。

    二、超前进位加法器

    对于更宽的加法器N,行波进位加法器关键路径越长,限制了加法器的性能,对于高速处理器等将是个极大的瓶颈。所以,本文介绍的超前进位加法器优化改进行波进位器的关键路径。RCA的缺点在于第k位的进位Ck必须依赖于前一级的Ck-1,所以最高位的进位将必须等待之前所有级进位计算完毕后才能计算出结果。所以,超前进位加法器的思想是并行计算进位Ck。

    416a4b709be9782432112c6c8e20fc56.png

    观察上式s和c,将共有部分分别定义:

    58f3ca24b953aeb1e423e73ce759f4a3.png

    对于N比特LCA加法器,进位与和公式将重新书写如下:

    a5675283a98275eb50ee48f12e79c62a.png

    其中:

    bd023acc31a45445279f38e3fdaa263f.png

    其门电路图如下,其实是个半加器:

    88cc6fdb35e8b99ac23a90349ed2ae27.png

    以4比特LCA加法器为例,其进位链与和公式分别计算如下:

    2a472f44c574418b9a586da63c317a18.png

    9b4bf7e010c2cd19ecbc96cec6eed2d9.png

    根据上述式子,可以计算出Ci和Si,其结构图为:

    c22e4c769cfa1cf4ad4dafe845a81c88.png
    4比特超前进位加法器结构图

    根据超前进位加法器中进位链c和输出s的物理实现方式不同,大致可分成以下三类:

    • 递归超前进位加法器(Recursive Lookahead Carry Adder,简称RLCA)
    • 分类超前进位加法器(Block Lookahead Carry Adder,BCLA),也称(section-carry-based carry-lookahead adder)
    • 混合型超前进位加法器

    以上不同种类LCA之后细讲。对于位宽更大的LCA如16,32,64比特LCA等可以并行生成所有的PG和进位C,但这会造成电路极大的扇入和扇出;另外可以根据4比特LCA级联而成,如16比特LCA可由如下图级联而成(属RLCA):

    a3bfe8a4343b2203505e0a16e09e24b0.png
    4比特LCA级联而成的16比特LCA

    三、超前进位加法器关键路径分析

    为什么超前进位加法器在速度方面相比行波进位加法器更胜一筹?当然,从进位链的生成上也可以看出,我们从进位链C4来对比一下。

    78a2a070ea27bb20f39d8bdf594865d1.png
    LCA进位的c4门电路图

    2b7e23604c23a3de42b62746806b01de.png
    LCA输出S3门电路图

    从输入所有的a,b和c0,LCA的输出进位c4只需要3级门电路延迟,c0,c1,c2,c3同时生成,同时由于S3=P3 xor c3,所以4比特LCA关键路径为4级门延迟。虽然经过了很多门电路,但他们的计算是同时的,而4比特RCA计算出c4需要9个门电路延迟。同样是32比特加法器,理想的LCA(全部展开所有的进位逻辑)关键路径延迟理论上只需要4个门电路,而RCA的关键路径延迟为65个门电路。如果采用4比特级联LCA,形成32比特LCA,则需要(3+7*2+1)=18级门电路延迟,相比RCA,缩短了关键路径的长度。

    以上比较忽略多输入门延迟,真正的门电路延迟计算需根据不同的门电路库文件,且对AND/OR/NAND等门电路输入数目有限制,如通常的4输入。此处只可意会。

    总而言之,RCA的缺点在于关键路径长,限制了速度,性能不高;LCA关键路径短,速度快,进位链计算依赖少,但对于位宽较大的加法器,PG和进位生成逻辑大,存在较大扇入扇出,变化信号多,会有较多的glitch,且面积与复杂度比同等的RCA大。

    四、Verilog描述

    以下参数化LCA基于4比特LCA设计,width可参数化定义为4的倍数,如20,24,32等。

    14465398392e25868a6691cef9cfe472.png

    verilog源码公众号回复003获取。

    更多阅读,关注“纸上谈芯”,不定期更新,共同学习:

    90803c4bef6782c3f6b9a965a4c80355.png
    展开全文
  • 文章目录八位超前进位加法器原理设计文件综合电路测试文件仿真波形八位行波进位加法器原理设计文件方式一综合电路方式二综合电路测试文件仿真波形总结 八位超前进位加法器 原理 有学弟问我,超前进位加法器中的p=...
  • 行波进位加法器设计

    千次阅读 2020-12-08 00:17:40
    在Logisim中,利用上一关设计的全加器FA级联设计一个4位的行波进位加法器。 行波进位是指进位信号从低位逐位向高位传递,特点是结构简单,但速度比较慢。原理示意图如下:
  • 前期已介绍了行波进位加法器(Ripple Carry Adder, RCA)依赖于低位进位,所以具有超长的进位链和关键路径。对于RCA的改进中,进位选择加法器(Carry Select Adder)是比较特别的一种,鉴于有太多的加法器缩写是CSA...
  • 一、半加器和全加器 二、行波进位加法器 三、超前进位加法器(Carry-Lookahead Adder,CLA) https://www.jianshu.com/p/6ce9cad8b467
  • Sklansky加法器是另一种并行高速的树形...一、进位选择加法器Sklansky加法器使用了进位选择加法器:进位选择加法器由2个行波进位加法器和1个选择器构成其中一个行波进位加法器假定进位进位为0另外一个行波进位加法...
  • 一、进位旁边加法器进位旁路加法器(Carry Skip Adder,CSA),...此前介绍了行波进位加法器RCA,第k位的进位Ck必须等待之前的Ck-1的结果才能计算出来,如下图进位c16必须等到前一级全加器的c15输出才可以计算,所以...
  • @[TOC]全加器和行波进位加法器的延迟时间 全加器和行波进位加法器的延迟时间的理解 这是我第一次写博客,有写的不好的请指教。 延迟时间的本质是找最长的传输路径。 首先要知道,一级门(如与门,或门,与非门...
  • 用Logisim制作一个四位行波进位加法器
  • 1. 行波进位实现方式:
  • 3-2 Verilog 4位行波进位加法器

    千次阅读 2016-04-23 13:02:52
    Verilog 学习过程 4位行波进位加法器
  • 来自微信公众号 “数字芯片实验室”加减法是一类非常基础的运算,本文分析最简单的行波进位加/减法(Ripple CarryAdder/Subtractor)的硬件开销和性能问题。在文章的开始控制变量,仅使用工艺库中的基本逻辑门AND-...
  • 三、行波进位加法器 加法器是算术运算的一种,在计算机和一些处理器中被运用于算术逻辑单元ALU中或者处理器的其他部分如计算地址,加减操作等类似操作。今天。我们来重温下数字电路中的加法器。 一、半加器 ...
  • 两个1二进制的加法运算如下表所示,其中S表示和数C表示进位数。由表中逻辑关系可见,这种加法运算只考虑了两个加数本身,而没有考虑由低位来的进位,所以称为半加。半加器就是实现下面这个真值表...
  • 加法器是算术运算的一种,在计算机和一些处理器中被运用于算术逻辑单元ALU中或者处理器的其他部分如计算地址,加减操作等类似操作。今天。我们来重温下数字电路中的加法器。一、半加器半加器用于计算2个单比特二进制...
  • 半加器、全加器和行波进位加法器原理与设计 HDLBits链接 半加器 定义: 半加器用于计算2个单比特二进制数a与b的和,输出结果sum(s)和进位carry(c)。在多比特数的计算中,进位c将作为下一相邻比特的加法运算中。...
  • 实验背景: 全加器是实现三位数相加的组合逻辑电路,共有三个输入,两个输出。输入变量中的两个用 X 和 Y 表示,代表两个加数,第三个输入 Z 表示低位产生的...四位行波进位加法器由四个全加器级联形成。被加数A和加
  • 硬件加法器种类繁多,对于不同的设计,加法器的需求也不一样。在前端设计中,使用符号“+”便可轻而易举地实现加法器。只是在特殊的情况下,指定选择加法器类型,或许可以用到。其他情况,可以当做科普学习加法器的...
  • 你真的可以在《城市:天际线》游戏中构建一个4位加法器(4-bit adder)。《城市:天际线》是一款城市模拟游戏,其复杂的游戏机制甚至允许玩家在当中建起通用逻辑门(universal logic gates )。以通用逻辑门为基础,我们...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 420
精华内容 168
关键字:

行波进位加法器