原创 流水线4位(4bit)加法器

2009-2-17 17:24 7414 5 5 分类: FPGA/CPLD

流水线4(4bit)加法器<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


代码如下:


 


`timescale 1ns / 1ps


 


module pipeline_add(a,b,cin,cout,sum,clk);


 


input[3:0] a,b;


input clk,cin;


output[3:0]sum;


output cout;


 


reg[3:0] tempa,tempb;


reg tempci;


 


reg cout;


reg firstco;


reg[1:0] firstsum;


reg[2:0] firsta,firstb;              //空出fista[2]firstn[2]放进位


reg[3:0] sum;


 


always@(posedge clk)


   begin


      tempa=a;                 //输入数据缓存


      tempb=b;


      tempci=cin;


   end


 


always@(posedge clk)


   begin


      {firstco,firstsum}=tempa[1:0]+tempb[1:0]+tempci;   //第一级加(低2位)


       firsta=tempa[3:2];                   //未参加计算的数据缓存


       firstb=tempb[3:2];


   end


 


always@(posedge clk)


   begin


      {cout,sum}={firsta[2:0]+firstb[2:0]+firstco,firstsum};  //第二级加(高2位)


   end


 


endmodule


 


顶层测试模块代码


`timescale 1ns/1ps


 


module pipeline_add_test;


    reg [3:0] a = 4'b0000;


    reg [3:0] b = 4'b0000;


    reg cin = 1'b0;


    wire cout;


    wire [3:0] sum;


    reg clk = 1'b0;


 


    parameter PERIOD = 200;


    parameter real DUTY_CYCLE = 0.5;


    parameter OFFSET = 100;


 


    initial    // Clock process for clk


    begin


        #OFFSET;


        forever


        begin


            clk = 1'b0;


            #(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1;


            #(PERIOD*DUTY_CYCLE);


        end


    end


 


    pipeline_add UUT (


        .a(a),


        .b(b),


        .cin(cin),


        .cout(cout),


        .sum(sum),


        .clk(clk));


 


    initial begin


        // -------------  Current Time:  100ns


        #100;


        cin = 1'b1;


        // -------------------------------------


        // -------------  Current Time:  185ns


        #85;


        a = 4'b0010;


        b = 4'b0011;


        // -------------------------------------


        // -------------  Current Time:  385ns


        #200;


        a = 4'b0100;


        b = 4'b0010;


        // -------------------------------------


        // -------------  Current Time:  585ns


        #200;


        cin = 1'b0;


        a = 4'b1010;


        b = 4'b0011;


        // -------------------------------------


        // -------------  Current Time:  785ns


        #200;


        a = 4'b1011;


        b = 4'b1010;


        // -------------------------------------


        // -------------  Current Time:  985ns


        #200;


        a = 4'b1111;


        b = 4'b1110;


        // -------------------------------------


        // -------------  Current Time:  1185ns


        #200;


        a = 4'b1101;


        b = 4'b0100;


        // -------------------------------------


        // -------------  Current Time:  1585ns


        #400;


        a = 4'b0011;


        // -------------------------------------


        // -------------  Current Time:  1785ns


        #200;


        b = 4'b1101;


        // -------------------------------------


        // -------------  Current Time:  1985ns


        #200;


        cin = 1'b1;


        a = 4'b0101;


        b = 4'b1111;


        // -------------------------------------


        // -------------  Current Time:  2385ns


        #400;


        a = 4'b0100;


        b = 4'b1101;


        // -------------------------------------


    end


 


endmodule


 


布线-布局仿真(Post-Route Simulate


 


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />


点击看大图 


 


水线加法器延时3个时钟周期得到两数相加的值。


 下面是综合器综合后的RTL视图。从下图也能很好解释2级流水线的工作原理和延时3个时钟周期的原因。因为经过了三个寄存器(D触发器)。



 


点击看大图           


 


要注意的是,不能用前仿真验证,因为前仿真没有考虑器件延时,仿真出来的波形与实际不符。下面是前仿真(行为仿真Behavioral Simulation



 

点击看大图


 


    可以看到两个加数(ab)没有经过延时就得到结果(sumcout),这个可以从RTL中知道,寄存器FD在时钟上升沿,数据就从输入到输出,没仿真出来流水线的特点。


    下面再认真看看程序高2位相加代码为


{cout,sum}={firsta[2:0]+firstb[2:0]+firstco,firstsum};


不能用下面代码:


{cout,sum}={firsta[1:0]+firstb[1:0]+firstco,firstsum};


这是由于”{}”就已经限定等号右边为4位,由于等号左边为5位,这造成cout没用,综合的时候会把cout综合掉


综合报告(Synthesis Report)会出现这样的信息:


WARNING:Xst:1710 - FF/Latch  <cout> (without init value) has a constant value of <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0 in block <pipeline_add>.


RTL视图可以看到cout接地了,都表明cout没用到。


 

b76c8730-2a35-4678-bff3-12311342668e.JPG 



 


之前参考了书《FPGA开发实用教程》第六节《Verilog 常用程序示例2


(http://www.eefocus.com/article/08-03/37234s.html )写成下面的样子,结果也出错


{cout,sum}={{firsta[1],firsta[1:0]}+{firstb[1],firstb[1:0]}+firstco,firstsum};


 


   这段代码解决了位数问题,但结果还是不正确,这是由于进位cout不单单是由firsta[1]firstb[1]决定的:01+11=100,与firsta[1:0]firstb[1:0]都有关系。


 


采用流水线设计的加法器,有效提高了系统的最高运行频率,提高了工作速度,尤其是对于FPGA器件,效果跟明显。


采用流水线设计的4位加法器时序分析:(XC3S500E)



 

be10ef79-f5aa-4c3c-b921-48dee038f6e0.JPG


 


   串行加法器和超前进位加法器的时序分析可参考下面两篇博文:


加法器设计(三)超前进位加法器(Verilog


加法器设计(二)串行加法器(Verilog


 


参考资料:


1)            Verilog数字系统设计教程,夏宇闻,北京航空航天大学出版社,P105 2.6流水线


2)            Verilog HDL程序设计教程,P151页,10.2流水线设计技术 (程序不能综合,具体参考上文)


      下载地址:http://bbs.ednchina.com/ShowTopic.aspx?id=73098


3)            FPGA开发实用教程》第六节《Verilog 常用程序示例2(程序不能综合,具体参考上文)


       http://www.eefocus.com/article/08-03/37234s.html


 
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条