精华内容
下载资源
问答
  • 串行加法器 并行加法器 超前进位加法器

    万次阅读 多人点赞 2018-03-27 14:05:55
    1.串行加法器串行加法器加法器执行位串行行操作,利用个时钟周期完成一次加法运算,即输入操作数和输出结果方式为随时钟串行输入/输出。位并行加法器速度高,但是占用资源。在许多实际应用中并不需要这样高的...

    1.串行加法器

    串行加法器即加法器执行位串行行操作,利用多个时钟周期完成一次加法运算,即输入操作数和输出结果方式为随时钟串行输入/输出。位并行加法器速度高,但是占用资源多。在许多实际应用中并不需要这样高的速度,而是希望减少硬件资源占用率,这时就可以使用位串行加法器。


    在串行加法器中,只有一个全加器,数据逐位串行送入加法器进行运算,如图所示。图中FA是全加器,A、B是两个具有右移功能的寄存器,C为进位触发器。由移位寄存器从低位到高位逐位串行提供操作数相加。如果操作数长n位,加法就要分n次进行,每次产生一位和,并串行地送回A寄存器。进位触发器用来寄存进位信号,以便参与下一次的运算。


    2.串行进位的并行加法器

    并行加法器由多个全加器组成,其全加器个数的多少取决于机器的字长,由于并行加法器可同时对数据的各位相加,读者可能会认为数据的各位能同时运算,其实并不是这样的。这是因为虽然操作数的各位是同时提供的,但低位运算所产生的进位会影响高位的运算结果。例如:11…11和00…01相加,最低位产生的进位将逐位影响至最高位,因此,串行进位的并行加法器需要一个最长运算时间,它主要是由进位信号的传递时间决定的,而每个全加器本身的求和延迟只是次要因素。很明显,提高并行加法器速度的关键是尽量加快进位产生和传递的速度。 
    并行加法器中的每一个全加器都有一个从低位送来的进位输入和一个传送给高位的进位输出。通常将传递进位信号的逻辑线路连接起来构成的进位网络称为进位链。每一位的进位表达式为:

    Ci=AiBi+(Ai⊕Bi)Ci-1

    其中,“AiBi”取决于本位参加运算的两个数,而与低位进位无关,因此称AiBi为进位产生函数(本次进位产生),用Gi表示,其含义是:若本位的两个输入均为1,必然要向高位产生进位。“(Ai⊕Bi)Ci-1”则不但与本位的两个数有关,还依赖于低位送来的进位,因此称Ai⊕Bi为进位传递函数(低位进位传递),用Pi表示,其含义是:当两个输入中有一个为1,低位传来的进位Ci-1将向更高位传送,所以进位表达式又可以写成:

    Ci=Gi+PiCi-1

    把n个全加器串接起来,就可进行两个n位数的相加。这种加法器称为串行进位的并行加法器,如图2-16所示。串行进位又称行波进位,每一级进位直接依赖于前一级的进位,即进位信号是逐级形成的。


    其中:C1=G1+P1C0 
    C2=G2+P2C
    … 
    Cn=Gn+PnCn-1 

    串行进位的并行加法器的总延迟时间与字长成正比,字长越长,总延迟时间就越长。假设将一级与门、或门的延迟时间定为ty,从上述公式中可以看出,每一级全加器的进位延迟时间为2ty。在字长为n位的情况下,若不考虑Gi、Pi的形成时间,从C0→Cn的最长延迟时间为2nty(设C0为加法器最低位的进位输入,Cn为加法器最高位的进位输出)。 


    显然,串行进位方式的进位延迟时间太长了,要提高加法运算的速度,就要尽可能地减少进位延迟时间,也就是要改进进位方式,这就产生了并行进位方式和分组并行进位方式


    3.超前进位加法器

    可以想象最简单的加法计算就是每一位都进行一次全加器计算,然后产生一个进行c,下一个全加器在取得进位以后再进行他的位的计算,循环下去直到最后一位。这样的问题是进行一次32位的加法计算就需要至少串行的经过32个全加器,如果CPU的频率是3Ghz,那么一个时钟周期,大约333皮秒内,是无法完成一次简单的加法运算的。


    那么超前进位加法器是如何做到高速计算的,可以想象肯定是把计算平行化了,而且是用数量来换了速度。但是具体是怎么做的呢。我们来一起分析下。

    首先考虑所有的加法情况

    Rowxycincouts
    000000
    100101
    201001
    301110
    410001
    510110
    611010
    711111


    ci+1 = xiyi + xici + yici
    这里c表示的是进位,举个列子来说就是第一位的进位c1他是由第零位的x0*y0+x0*c0+y0*c0, 这里很明显c0是始终为0的。那么c1=x0*y0
    然后这个提取公因子公式就变成了
    ci+1 = xiyi + ci(xi + yi)
    然后是不是发现,这样一来只有ci是不确定的。其他的xi和yi都是直接输入。
    但是ci其实呢通过循环inline的一个替换,其实会变成类似
    Ci+1 = Xiyi + (Xi + yi)(Xi-1yi-1 + Ci-1(Xi-1 + yi-1)
    然后可以一直这样替换下去,直到c0这一层。或者是最右端的输入。
    一般的通常会把这几个变量成为g,p变量
     gi = xiyi 
     pi = xi + yi
    这样理论上可以实现任何位数都在有限次内完成,但是这样的代价是位数越多需要的电路也就越多。
    以四位超前加法器为例:
    第一步,所有的4个全加器对每一位计算出自身的和Si, gi和pi
    然后第二步,超前进位器计算出c1,c2,c3,c4,当然这里的c1,c2,c3,c4计算需要的逻辑门数量是逐步递增的。
    然后c1,c2,c3对S1,S2,S3进行进位,C4会传递给更上面的位。
    但是由于成本的问题一般都会把32位或者64位的切割成多个16位的超前进位来进行计算,能保证在一个时钟周期内完成基本就可以了。
    取得一个成本和性能上得平衡。


       四位超前进位加法器


                                                                                十六位超前进位加法器


                                                                            三十二位超前进位加法器





    展开全文
  • 如果对速度要求不高,我们也可以使用串行加法器。下面通过状态机来实现串行加法器的功能。 设A=an-1an-2…a0, B=bn-1bn-2…b0,是要相加的两个无符号数,相加的和为:sum=sn-1sn-2…s0。我们现在要设计一个电路,在...

          如果对速度要求不高,我们也可以使用串行加法器。下面通过状态机来实现串行加法器的功能。

         设A=an-1an-2…a0, B=bn-1bn-2…b0,是要相加的两个无符号数,相加的和为:sum=sn-1sn-2…s0。我们现在要设计一个电路,在时钟周期内处理一位相加的串行加法。加法过程一开始进行a0,b0的相加,在下一个时钟周期完成 a1,b1和第0位进位的相加,并依次完成所有的加法。

          下图的方案中,3个移位寄存器用来保存A,B以及和Sum。假设这些寄存器有并行加载功能,先将加A,B的值载入这些寄存器,在时钟的每个周期,通过加法器FSM控制每位相加,在周期的最后把输出的结果移入Sum寄存器。我们使用上升沿触发的触发器,这样所有数据在时钟的上升沿及各个触发器的传播延迟后发生变化,此时三个移位寄存器内容右移:将加法结果移入Sum,并将下一对 ai,bi加载至加法器FSM。


    image


          下面是加法器FSM的图:

    image



          我们来设计状态机,假设有两个状态:状态G,进位为0,状态H,进位为1。则状态图如下,输出s取绝与当前状态(进位)和输入a,b的值,所以这是mealy型状态机。

          在状态G中,输入00,则仍在状态G,输出为0,为01和10时候,仍在状态G,输出为1,如果输入为11,则转到状态H,输出0。

          在状态H中,输入11,仍在状态H,输出1,输入为01和10时候,仍在状态H,输出为0,如果输入为00,则转到状态G,输出为1。


    image


       这个mealy型串行加法器的状态表如下:

       根据状态表,利用卡诺图简化,有下列表达式,显然它就是全加器的输出表达式。

            Y = ab+ay+by

            s = a^b^y


    现在状态 下一状态(ab) 输出s 00 01 10 11 00 01 10 11 G G G G H 0 1 1 0 H G H G G 1 0 0 1


    现在状态 下一状态(ab) 输出(ab) 00 01 11 10 00 01 11 10 y Y s 0 0 0 1 0 0 1 0 1 1 0 1 1 1 1 0 1 0

          下面是verilog实现代码,首先是移位寄存器的代码,该移位寄存器带有使能输入E,E=1时,寄存器的内容将在时钟的上升沿开始从左到右。E=0,可以阻止移位寄存器内容发生改变。

    module shiftrne(R,L,E,w,clk,Q);
    
       parameter n=8;
    	input [n-1:0] R;
    	input L,E,w,clk;
    	output reg [n-1:0] Q;
    
    	integer k;
    
    	always @(posedge clk) begin
    	   if(L)
    		  Q<=R;
    		else if(E) begin
    		   for(k=n-1; k>0; k=k-1)
    			   Q[k-1] <= Q[k];
    			Q[n-1] <=w;
    		end
    
    
    	end
    
    
    endmodule

    下面是mealy型串行加法的代码,代码中首先例化了三个移位寄存器。代码中还包括一个递减计数器,用来完成n位加法并输出至移位寄存器后,停止加法器。

    代码中我们采用高电平复位信号。输出端的使能信号为Run信号,只要Run信号为1,递减计数器每个时钟周期都会递减。

    module serialadd(A,B,Rst,clk,S);
      input [7:0] A,B;
      input Rst,clk;
      output wire [7:0] S;
    
      reg [3:0] Count;
      reg s,y,Y;
      wire [7:0] QA,QB;
      wire Run;
      parameter G=1'b0, H=1'b1;
    
      shiftrne #(.n(8)) shift_A(.R(A),.L(Rst),.E(1'b1),.w(1'b0),.clk(clk),.Q(QA));
      shiftrne #(.n(8)) shift_B(.R(B),.L(Rst),.E(1'b1),.w(1'b0),.clk(clk),.Q(QB));
      shiftrne #(.n(8)) shift_S(.R(8'b0),.L(Rst),.E(Run),.w(s),.clk(clk),.Q(S));
    
      //adder FSM
      //output and next state cominatioal circuit
    
      always @(QA,QB,y) begin
    
          case (y)
    		  G:
    		  begin
    		    s = QA[0]^QB[0];
    			 if(QA[0]&QB[0]) Y=H;
    			 else  Y=G;
    
    		  end
    		  H:
    		  begin
    		    s = QA[0]~^QB[0];
    			 if(~QA[0]&~QB[0]) Y=G;
    			 else  Y=H;
    
    		  end
    		 default:
    		    Y  = G;
    		endcase
      end
    
      //sequential block
      always @(posedge clk)
        if(Rst)
    	   y<=G;
    	 else
    	    y<=Y;
    
      //control shift proecess
      always @(posedge clk)
        if(Rst) Count=8;
    	 else if(Run) Count = Count-1;
    
      assign Run = |Count;
    endmodule


    testbench代码为:

    `timescale 1ns/1ns
    `define clock_period 20
    
    module serialadd_tb;
     reg clk;
     reg Rst;
    
     reg [7:0] A,B;
     wire [7:0] S;
    
     serialadd serialadd0(.A(A),.B(B),.Rst(Rst),.clk(clk),.S(S));
     //serialadd_moore serialadd_moore0(.A(A),.B(B),.Rst(Rst),.clk(clk),.S(S));
     always #(`clock_period/2) clk = ~clk;
    
     initial begin
       clk=0;
       A = 8'd35;
    	B = 8'd99;
    	Rst = 0;
    	#(`clock_period)
    	Rst = 1;
    	#(`clock_period)
    	Rst = 0;
    
    	#(`clock_period*10)
    
       $stop;
    
     end
    
    
    
    
    endmodule


    下面是mealy型串行加法的波形,输入35,99,输出134

    image


        我们把状态图做如下调整,拆分G为G0,G1,拆分H为H0,H1, 则输出之和状态有关,为moore型串行加法器状态图。

    image



    下面是该状态机的状态表:



    现在状态 下一状态(ab) 输出 00 01 10 11 s G 0 G 0 G 1 G 1 H 0 0 G 1 G 0 G 1 G 1 H 0 1 H 0 G 1 H 0 H 0 H 1 0 H 1 G 1 H 0 H 0 H 1 1


    现在状态 下一状态(ab) 输出 00 01 10 11 s y2y1 Y2Y1 00 00 01 01 10 0 01 00 01 01 10 1 10 01 10 10 11 0 11 01 10 10 11 1

    可以推导出

    Y1=a^b^y2

    Y2=ab+ay2+by2

    s=y1

    下面是其可能的实现电路。moore型加法输出比mealy型加法多了一个时钟周期的时延。

    image


    moore型串行加法器verilog代码如下,其中也例化了3个移位寄存器。注意Count复位后为9,

    module serialadd_moore(A,B,Rst,clk,S);
      input [7:0] A,B;
      input Rst,clk;
      output wire [7:0] S;
    
      reg [3:0] Count;
      reg [1:0] y,Y;
      wire [7:0] QA,QB;
      wire s,Run;
      parameter G0=2'b00, G1=2'b01,H0=2'b10, H1=2'b11;
    
      shiftrne #(.n(8)) shift_A(.R(A),.L(Rst),.E(1'b1),.w(1'b0),.clk(clk),.Q(QA));
      shiftrne #(.n(8)) shift_B(.R(B),.L(Rst),.E(1'b1),.w(1'b0),.clk(clk),.Q(QB));
      shiftrne #(.n(8)) shift_S(.R(8'b0),.L(Rst),.E(Run),.w(s),.clk(clk),.Q(S));
    
      //adder FSM
      //output and next state cominatioal circuit
    
      always @(QA,QB,y) begin
    
          case (y)
    		  G0:
    		  begin
    			 if(QA[0]&QB[0]) Y=H0;
    			 else if(~QA[0]&~QB[0]) Y=G0;
    			 else  Y=G1;
    
    		  end
    		  G1:
    		  begin
    			 if(~QA[0]&~QB[0]) Y=G0;
    			 else if (QA[0]&QB[0])Y=H0;
    			 else  Y=G1;
    
    		  end
    		  H0:
    		  begin
    			 if(QA[0]&QB[0]) Y=H1;
    			 else if(~QA[0]&~QB[0]) Y=G1;
    			 else  Y=H0;
    
    		  end
    		  H1:
    		  begin
    			 if(~QA[0]&~QB[0]) Y=G1;
    			 else if (QA[0]&QB[0])Y=H1;
    			 else  Y=H0;
    
    		  end
    		endcase
      end
    
      //sequential block
      always @(posedge clk)
        if(Rst)
    	   y<=G0;
    	 else
    	    y<=Y;
    
      //control shift proecess
      always @(posedge clk)
        if(Rst) Count=9;
    	 else if(Run) Count = Count-1;
    
      assign Run = |Count;
      assign s = (y==H0?1'b0:(y==G0?1'b0:1'b1));
    endmodule
    `timescale 1ns/1ns
    `define clock_period 20
    
    module serialadd_tb;
     reg clk;
     reg Rst;
    
     reg [7:0] A,B;
     wire [7:0] S;
    
     //serialadd serialadd0(.A(A),.B(B),.Rst(Rst),.clk(clk),.S(S));
     serialadd_moore serialadd_moore0(.A(A),.B(B),.Rst(Rst),.clk(clk),.S(S));
     always #(`clock_period/2) clk = ~clk;
    
     initial begin
       clk=0;
       A = 8'd35;
    	B = 8'd99;
    	Rst = 0;
    	#(`clock_period)
    	Rst = 1;
    	#(`clock_period)
    	Rst = 0;
    
    	#(`clock_period*10)
    
       $stop;
    
     end
    
    
    
    
    endmodule

    输出波形为:

    image

    转载于:https://www.cnblogs.com/mikewolf2002/p/10309202.html

    展开全文
  • 常见的加法器是位并行的(Bit-parallel),在一个时钟周期内完成加法运算。其速度较高,占用的资源较。但是,在很应用中,并不需要这么高的速度,而且希望减小资源消耗。这时可以采用数字串行...
  • 流水线加法器verilog

    2020-04-30 10:27:34
    流水线加法器verilog 对于位数比较小的数值相加,计算机可以在一个时钟...我们可以使用两个32位的加法器,其中一个加法器执行低32位的加法,在一个时钟周期之后第二个加法器执行高32位的加法,与此同时,下一个64位...

    流水线加法器verilog

    对于位数比较小的数值相加,计算机可以在一个时钟周期内完成相加的过程,比如32位的加法器,我们比较容易满足其定时需求。但是如果我们需要将两个64位的数值相加,计算机就可能不能在一个时钟周期内完成。此时我们可以考虑流水线来解决这个问题。
    我们可以使用两个32位的加法器,其中一个加法器执行低32位的加法,在一个时钟周期之后第二个加法器执行高32位的加法,与此同时,下一个64位加法器的低32位加法也在执行。这样,第一组计算结果会出现在两个时钟周期后,但之后的每个时钟周期都会得到一个新值。
    代码实现:
    语言:verilog
    环境:modelsim10.4
    加法器:

    module adder_pipelined(A,B,clk,reset,FinalSum);
    input clk,reset;
    input [63:0] A,B;
    output [64:0] FinalSum;
    /**************************************/
    wire carry_d1;
    reg [32:0] Lsum_d1;
    wire [32:0] Lsum_d1_nxt;
    reg [31:0] Lsum_d2;
    reg [31:0] Aup_d1,Bup_d2;
    reg [32:0] Usum_d2;
    wire [32:0] Usum_d2_nxt;
    wire [64:0] FinalSum;
    /**************************************/
    assign Lsum_d1_nxt = A[31:0] + B[31:0];
    assign carry_d1 = Lsum_d1[32];
    assign Usum_d2_nxt = carry_d1 + Aup_d1 + Bup_d2;
    assign FinalSum = {Usum_d2,Lsum_d2};
    /**************************************/
    always@(posedge clk or negedge reset)begin
     if(!reset)begin
      Lsum_d1 <= 0;
      Lsum_d2 <= 0;
      Aup_d1 <= 0;
      Bup_d2 <= 0;
      Usum_d2 <= 0;
     end
     else begin
      Lsum_d1 <= Lsum_d1_nxt;
      Lsum_d2 <= Lsum_d1_nxt[31:0];
      Aup_d1 <= A[63:32];
      Bup_d2 <= B[63:32];
      Usum_d2 <= Usum_d2_nxt;
     end
    end
    endmodule

    测试代码:

    `timescale 1ns/1ns
    module testbech;
    reg[63:0] A_tb,B_tb;
    reg clk_tb,reset_tb;
    wire [64:0] FinalSum_tb;
    parameter HALF_CLK_PERIOD = 5;
    /**************************************/
    initial begin
     clk_tb = 0;
     forever #HALF_CLK_PERIOD clk_tb = ~clk_tb;
    end
    initial begin
     reset_tb = 0;
     #20 reset_tb = 1;
    end
    initial begin
     A_tb = 64'h2344321432112341;
     B_tb = 64'h1234432143211234;
    end
    adder_pipelined adder_pipelined_test
      (.A(A_tb),
      .B(B_tb),
      .clk(clk_tb),
      .reset(reset_tb),
      .FinalSum(FinalSum_tb));
    endmodule

    仿真结果:

    在这里插入图片描述

    展开全文
  • verilog 多种方法实现加法器

    千次阅读 2020-02-20 10:15:36
    一位全加器原理 法1 串行一位加法器法 一位全加器 module adder_1bit( input din_one, //第一个加数 input din_two, //第二个加数 input cin, //进位输入 output sum, //和输出 output cout //进位输出 );...

    一位全加器原理
    在这里插入图片描述

    法1 串行一位加法器法

    一位全加器

    module adder_1bit(
        input din_one, //第一个加数
        input din_two, //第二个加数
        input cin,     //进位输入
        
        output sum,    //和输出
        output cout    //进位输出
        );
        
    
    //利用连续赋值语句实现全加操作    
       assign sum = din_one ^ din_two ^ cin;
       assign cout = (din_one & din_two) | (din_two & cin) | (din_one & cin);    
    endmodule
    

    2bit

    module adder_2bit(
        input [1 : 0] din_one,  //第一个加数
        input [1 : 0] din_two,  //第二个加数
        input cin,              //进位输入
        
        output [1 : 0] sum,     //和输出
        output cout             //进位输出
        );
        
        wire cin_0bit;          //低位加法的进位输出
    
    //实例化adder_1bit实现低位加法    
        adder_1bit U1_low_bit(
            .din_one(din_one[0]),
            .din_two(din_two[0]),
            .cin(cin),
            .sum(sum[0]),
            .cout(cin_0bit)
            );
        
    //实例化adder_1bit实现高位加法       
        adder_1bit U2_high_bit(
            .din_one(din_one[1]),
            .din_two(din_two[1]),
            .cin(cin_0bit),
            .sum(sum[1]),
            .cout(cout)
            );
            
    
    //利用模块实例化语句实现2位全加操作    
    endmodule
    

    4bit

    module adder_4bit(
        input [3 : 0] din_one,  //第一个加数
        input [3 : 0] din_two,  //第二个加数
        input cin,              //进位输入
        
        output [3 : 0] sum,     //和输出
        output cout             //进位输出
        );
        
        wire cin_0bit;          //低位加法的进位输出
    
    //实例化adder_1bit实现低位加法    
        adder_2bit U1_low_bit(
            .din_one(din_one[1 : 0]),
            .din_two(din_two[1 : 0]),
            .cin(cin),
            .sum(sum[1 : 0]),
            .cout(cin_0bit)
            );
        
    //实例化adder_1bit实现高位加法       
        adder_2bit U2_high_bit(
            .din_one(din_one[3 : 2]),
            .din_two(din_two[3 : 2]),
            .cin(cin_0bit),
            .sum(sum[3 : 2]),
            .cout(cout)
            );
            
    
    //利用模块实例化语句实现2位全加操作    
    endmodule
    

    法2 并行加法器

    思路 :直接用加法运算符“+”实现。直接表示

    /*******************8位加法器 ***********************/
    module adder_nonpipe(cout, sum, ina, inb, cin, enable);
     
    output cout;
    output [7:0] sum;
    input [7:0] ina, inb;
    input cin, enable;
     
    reg cout;
    reg [7:0] sum;
    reg [7:0] tempa, tempb;
    reg tempc;
     
    always @(posedge enable)
    begin
        tempa <= ina;
        tempb <= inb;
        tempc <= cin;
    end
     
    always @(posedge enable)
    begin
        {cout,sum} <= tempa + tempb + tempc;
    end
     
    endmodule
    

    法3 参数化

    module N_bit_add(
        clk    ,
        rst_n  ,
        //其他信号,举例dout
        A ,
        B ,
        Cin ,
        dout ,
        sout
        );
        //参数定义
        parameter      DATA_W =         8;
    
        //输入信号定义
        input               clk    ;
    
        input               rst_n  ;
        input               Cin  ;
        input[DATA_W-1:0]        A ;
        input[DATA_W-1:0]        B ;
        //输出信号定义
        output[DATA_W-1:0]  dout   ;
        output              sout   ;
    
        //进位位,S[7]为输出最后进位
        reg   [DATA_W-1:0]  S   ;
    
    
        genvar i;
        generate for(i=0;i<DATA_W;i=i+1)
            begin:one_bit_add
                if(i==0)begin
                    assign dout[i]=A[i]^B[i]^Cin;
                    assign S[i]=(A[i]&B[i])|(A[i]&Cin)|(Cin&B[i]);
                end
                else begin
                    assign dout[i]=A[i]^B[i]^S[i-1];
                    assign S[i]=(A[i]&B[i])|(A[i]&Cin;)|(Cin&B[i]);
                end
                
            end
        endgenerate
        assign sout=S[7];
    
        endmodule
    
    
    

    法4流水线

     1 /*******************8位2级流水加法器*************************/
     2 module adder_pipeline(cout, sum, ina, inb, cin, enable);
     3 
     4 output cout;
     5 output [7:0] sum;
     6 input [7:0] ina, inb;
     7 input cin, enable;
     8 
     9 reg cout;
    10 reg [7:0] sum;
    11 
    12 reg [3:0] tempa, tempb, firsts;
    13 reg firstc;
    14 always @(posedge enable)
    15 begin
    16     {firstc,firsts} = ina[3:0] + inb[3:0] + cin;
    17     tempa = ina[7:4];        //高4位输入寄存,使其与sum低4位在下级流水线同步输入。
    tempb = inb[7:4];        //否则sum的高4位,与低四位分两个时钟周期输出
    18 end
    19 
    20 always @(posedge enable)
    21 begin
    22     {cout,sum[7:4]} = tempa + tempb + firstc;
    23     sum[3:0] = firsts;       //不能合并为{cout, sum} = {tempa + tempb + firstc, firsts}; 位宽不匹配
    24 end
    25 
    26 endmodule
    

    四级流水线

    module adder_pipeline(rst_n,
                                    clk,
                                    a,
                                    b,
                                    cin,
                                    sum
                                         );
         
    parameter     DATA_SIZE = 8;
         
    input rst_n;
    input clk;
    input [DATA_SIZE - 1 : 0] a;
    input [DATA_SIZE - 1 : 0] b;    
    input cin;
    
    output [DATA_SIZE : 0] sum;
    
    reg [DATA_SIZE - 1 : 0] a_r;
    reg [DATA_SIZE - 1 : 0] b_r;
    reg cin_r;
    
    reg [DATA_SIZE : 0] sum;
    
    reg [1:0] stage0_sum;
    reg stage0_cout;
    reg [DATA_SIZE - 1 : 0] stage0_a_r;
    reg [DATA_SIZE - 1 : 0] stage0_b_r;
    
    //reg [4:0] stage1_sum;
    reg [3:0] stage1_sum;
    reg stage1_cout;
    reg [DATA_SIZE - 1 : 0] stage1_a_r;
    reg [DATA_SIZE - 1 : 0] stage1_b_r;
    
    //reg [6:0] stage2_sum;
    reg [5:0] stage2_sum;
    reg stage2_cout;
    reg [DATA_SIZE - 1 : 0] stage2_a_r;
    reg [DATA_SIZE - 1 : 0] stage2_b_r;
    
    //reg [8:0] stage3_sum;
    reg [7:0] stage3_sum;
    reg stage3_cout;
    
    always@(posedge clk)
        if(!rst_n)
            begin
                a_r <= 8'd0;
                b_r <= 8'd0;
                cin_r <= 1'b0;
            end
        else
            begin
                a_r <= a;
                b_r <= b;
                cin_r <= cin;
            end
    
    always@(posedge clk)
        if(!rst_n)
            begin
                {stage0_cout,stage0_sum} <= 3'd0;
                stage0_a_r <= 8'd0;
                stage0_b_r <= 8'd0;        
            end
        else
            begin
                //{stage0_cout,stage0_sum} <= a_r[1:0] + b_r[1:0] + cin_r;    
                {stage0_cout,stage0_sum} <= {1'b0,a_r[1:0]} + {1'b0,b_r[1:0]} + cin_r;                
                stage0_a_r <= a_r;
                stage0_b_r <= b_r;        
            end
            
    always@(posedge clk)
        if(!rst_n)
            begin
                {stage1_cout,stage1_sum} <= 5'd0;
                stage1_a_r <= 8'd0;
                stage1_b_r <= 8'd0;    
            end
        else
            begin
                //{stage1_cout,stage1_sum} <= { {a_r[3:2] + b_r[3:2] + stage0_cout},{stage0_sum} };
                //{stage1_cout,stage1_sum} <= { {{1'b0,a_r[3:2]} + {1'b0,b_r[3:2]} + stage0_cout},{stage0_sum} };    
                //{stage1_cout,stage1_sum} <= { {1'b0,a_r[3:2]} + {1'b0,b_r[3:2]} + stage0_cout,stage0_sum };
                //{stage1_cout,stage1_sum} = { {a_r[3],a_r[3:2]} + {b_r[3],b_r[3:2]} + stage0_cout,stage0_sum };
                {stage1_cout,stage1_sum} <= { {1'b0,stage0_a_r[3:2]} + {1'b0,stage0_b_r[3:2]} + stage0_cout,stage0_sum };
                stage1_a_r <= stage0_a_r;
                stage1_b_r <= stage0_b_r;
            end        
    
    always@(posedge clk)
        if(!rst_n)
            begin
                {stage2_cout,stage2_sum} <= 7'd0;
                stage2_a_r <= 8'd0;
                stage2_b_r <= 8'd0;    
            end
        else
            begin
                {stage2_cout,stage2_sum} <= { {1'b0,stage1_a_r[5:4]} + {1'b0,stage1_b_r[5:4]} + stage1_cout,stage1_sum };            
                stage2_a_r <= stage1_a_r;
                stage2_b_r <= stage1_b_r;
            end        
    
    always@(posedge clk)
        if(!rst_n)
            begin
                {stage3_cout,stage3_sum} <= 9'd0;
            end
        else
            begin
                {stage3_cout,stage3_sum} <= { {stage2_a_r[7],stage2_a_r[7:6]} + {stage2_b_r[7],stage2_b_r[7:6]} + stage2_cout,stage2_sum };    
            end
    
    always@(posedge clk)
        if(!rst_n)
            begin
                sum <= 9'd0;
            end
        else
            begin
                sum <= {stage3_cout,stage3_sum};        
            end
            
    endmodule
    

    testbench

     `timescale 1 ns/1 ns
    
     module tb();
    
     //时钟周期,单位为ns,可在此修改时钟周期。
     parameter CYCLE    = 20;
    
     //复位时间,此时表示复位3个时钟周期的时间。
     parameter RST_TIME = 3 ;
    
     parameter DATA_W    = 4;
    
    
     //时钟和复位
     reg clk  ;
     reg rst_n;
    
     //uut的输入信号
     reg[DATA_W-1:0]  A  ;
     reg[DATA_W-1:0]  B  ;
    
     reg              Cin;
         //uut的输出信号
         wire      sout;
         wire[DATA_W-1:0] dout;
    
             //待测试的模块例化
             N_bit_add #(.DATA_W(4))uut(
                 .clk          (clk     ), 
                 .rst_n        (rst_n   ),
                 .A               (A    ),
                 .B               (B    ),
    	         .Cin               (Cin),
                 .dout          (dout   ),
                 .sout          (sout   )
                 );
    
    
                 //生成本地时钟50M
                 initial begin
                     clk = 0;
                     forever
                     #(CYCLE/2)
                     clk=~clk;
                 end
    
                 //产生复位信号
                 initial begin
                     rst_n = 1;
                     #2;
                     rst_n = 0;
                     #(CYCLE*RST_TIME);
                     rst_n = 1;
                 end
                 integer i;
                 //输入信号a赋值方式
                 initial begin
    	        	i=0;
                      #1;
                     //赋初值
    	          	Cin=0;
    	        	 A= 0;
                     #(10*CYCLE);
                     //开始赋值
                     for (i=0;i<16;i=i+1)begin
                         A=i;
                         #(CYCLE/2);
                     end
                 end
    	             integer j;	
                 initial begin
    	        	j=0;
                     #1;
                     //赋初值
    		         B = 0;
                     #(10*CYCLE);
                     //开始赋值
                     for (j=0;j<16;j=j+1)begin
                         B=j;
                         #(CYCLE/2);
                     end
                 end
         endmodule
    
    
    

    ref
    https://www.cnblogs.com/youngforever/archive/2013/06/08/3127204.html

    展开全文
  • 加法器的优化

    2020-01-22 10:11:54
    ALU提供的加法和减法,究其本质都是由加法器来实现的。我们现在学习的加法器,是由一个一个的全加器串联而成,它在性能上存在着很大的问题,而这个问题究竟是什么?我们又该如何解决?在这一节,我们将来一起探讨这...
  • 1.组合逻辑控制的时序系统 (1)依靠不同的时间标志,让CPU分布工作,通常采用工作周期、时钟周期和工作脉冲三级时序 (2)工作周期:设置6个触发器分别作为周期的状态标志,1为工作周期开始,0为工作周期结束 ...
  • 4.6 加法器的优化

    2019-09-20 21:02:08
    计算机组成 4 算术逻辑单元 4.6 加法器的优化 ALU提供的加法和减法,究其本质都...我们还是来看这个四位加法器的例子,在实现中我们是用四个全加器构成了这个四位的加法器。我们注意到,当把这个加法器的输入都准备...
  • 加法器与乘法器

    千次阅读 2015-06-07 21:06:58
    http://pan.baidu.com/share/link?shareid=1314112584&uk=4161162592&app=zd
  • 由于浮点数系统操作比较复杂,需要专用硬件来完成相关的操作(在浮点运算中的浮点加法运算几乎占到全部运算操作的一半以上),所以,浮点加法器是现代信号处理系统中重要的部件之一。FPGA是当前数字电路研究开发的一种...
  • forahead adder 超前进位加法器

    千次阅读 2017-09-26 10:31:41
    数电书上说道超前进位加法器,没有仔细讲。上网搜了这篇资料,摘抄下来 串行进位加法器需要一级一级的进位,进位延迟很大。先行进位加法器(也叫超前进位加法器)可以有效的减少进位延迟。 设二进制加法器的第i...
  • 由于浮点数系统操作比较复杂,需要专用硬件来完成相关的操作(在浮点运算中的浮点加法运算几乎占到全部运算操作的一半以上),所以,浮点加法器是现代信号处理系统中最重要的部件之一。FPGA是当前数字电路研究开发的一...
  • 目录加法器相关半加器全加器使用加法器计算7bit中1的数量,最少用几个?行波进位加法器超前进位加法器分频电路相关偶数分频奇数分频分数分频 加法器相关 半加器和全加器的区别在于,是否有进位输入端,可以直观地...
  • verilog代码设计一个有符号累加,每个累加输入-8~+7范围有符号数i_data共四个,i_valid在输入数据有效时置高,无效时置低,当接收到4哥数据后,进行有符号数累加运算并输出累加结果o_data,同时拉高o_ready线(此时也...
  • vhdl加法器和减法器A Subtractor is a digital circuit which performs subtraction operation. 减法器是执行减法运算的数字电路。 半减法器 (Half Subtractor) It is a combinational circuit that performs ...
  • 超前进位加法器的理解

    万次阅读 2013-08-21 23:39:23
    目前在所有的cpu中,为了提高加法的计算速度。都采用了超前进位加法器。 普通的加法器我们很好理解,
  • 带控制端口的加法器进程死锁 第55例 地址计数器 第56例 指令预读计数器 第78例ccAm2901四位微处理器的ALU输入 第79例ccAm2901四位微处理器的ALU 第80例ccAm2901四位微处理器的RAM 第99例 多周期指令的描述 第100例 ...
  • 16位2级流水灯加法器

    2017-05-09 15:38:46
    在无线通信的信号处理中,常常要用到位数字量的加法运算,但串行加法器速度较慢,并行加法器则能满足要求,且结构不复杂,但在使用了并行加法器后,仍然只有在输出稳定后才能输入新的数据进行下一次计算,即计算的...
  • Verilog 加法器和减法器(7)

    千次阅读 2018-12-18 19:58:00
    在计算机中浮点数 表示通常采用IEEE754规定的...这个实现是多周期的单精度浮点加法。浮点加法分为以下几个步骤:1.初始化阶段,分离指数和尾数以及符号位。判断加数和被加数是否是规约浮点数,不是话,直接置over...
  • 第一章 加法器

    万次阅读 2014-04-02 15:07:54
    第一章 加法器 一、数据格式 1. 定点数表示法:x=x0x1x2…xn ,x0: 符号位,0代表正,1代表负。 2. 浮点表示法:  一个机器浮点数由阶码和尾数及其符号位组成(尾数:用定点小数表示,给出有效数字的位数...
  • 半加器的输入为a,b,输出为结果s和进位c,则其关系为 全加器的输入了一个进位cin,输出为结果位s和进位输出cout,则其关系为使用个全加器级联,把每一级的进位输出作为下一级的进位输入即构成了行波进位加法器,...
  • 4级流水线64位加法器

    2014-10-07 16:06:00
    这是第一个算法实现:使用四级流水线,提高64位加法器的速度。 使用流水线提高运算速度是以面积换取速度的做发。算法的思想是:如果使用一个64位的加法器实现,延时肯定比16位的加法器延时要大。也就是说16位的加法...
  • RTL就是一个带时序的1bit加法器,然后验证是否功能正确。理论上的正确功能应该是输入数据a和数据b之后的下个周期输出结果sum等于a+b。 2 UVM验证平台建立 将整个UVM验证平台分为4个部分agent、env、test、tb,逐层...
  • 对于一个8位的超前进位加法器,若要产生进位那么只需要3个周期就好,如果还要算最后的结果当然要4个. 那么当4个8位超前进位加法器拼在一起的是时候 需要算c8 c16 c24 顺序是算了c8算c16再算c24 每个要算3t由于是用...
  • SV的testbench例子-加法器

    千次阅读 2019-05-26 21:11:56
    下图是一个加法器的框图: 输入管脚包括a、b、valid和clk、reset,以及一个输出管脚c。 TestBench Without Monitor, Agent and Scoreboard 不带monitor、agent和scoreboard的结构如下: (1)定义...
  • 加法器的实现及优化

    千次阅读 2019-07-07 00:34:40
    但是半加器是无法完成加法运算的。 需要完成加法运算,需要用到全加器 2、全加器 全加器由两个半加器组成,绿色的为一个半加器,橙色的为另一个半加器。三个输入,两个输出。 两个输出表示了他能表示的范围为0...
  • FPGA之流水线算法实现八位加法器

    千次阅读 2018-03-26 20:56:11
    1.普通方法实现八位加法器/*******************8位加法器(非流水线)***********************/ module adder_nonpipe(cout, sum, ina, inb, cin, enable); output cout; output [7:0] sum; input [7:0] ina, inb; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,383
精华内容 7,353
关键字:

多周期加法器