zhliao2

风雨兼程,一路向北-------fpga (Keep a quiet heart study)
乘法器的设计

以下代码是选自特权同学的《《深入浅出玩转FPGA》》

 

乘法器的设计方法有两种:组合逻辑设计方法和时序逻辑。

采用组合逻辑设计方法,电路事先将所有的乘积项全部计算出来,最后加法运算。

采用时序逻辑设计方法,电路将部分已经得到的乘积结果右移,然后与乘积项相加并保存和值,反复迭代上述步骤直到计算出最终乘积。好处:利用时序逻辑设计方法可以使整体设

具备流水线结构的特征,能适用在各种实际工程设计中。

数据吞吐量使指芯片在一定时钟频率条件下所能处理的有效数据量。假设时钟频率为300MHz,由于芯片完成一次乘法运算需要1个以上的时钟周期,因此,即使芯片采用300MHz的

时钟频率,它每秒钟所能处理的有效数据吞吐量也一定小于300M。

对于16位乘法器而言,ain和bin均为0xFFFF时,芯片的运算量最大,计算所需的时间也最长,这种情况才能作为我们计算数据吞吐量的依据。假设芯片在200MHz的条件下ain

和bin均为0xFFFF时需要16个时钟周期才能得到乘法结果,那么芯片在200MHz的条件下的数据吞吐量就为:200M/16=12.5M

`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:    23:08:36 04/21/08
// Design Name:    
// Module Name:    mux_16bit
// Project Name:   
// Target Device:  
// Tool versions:  
// Description:
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////
module mux16(
            clk,rst_n,
            start,ain,bin,yout,done
        );
        
    input clk;        //芯片的时钟信号。
    input rst_n;    //低电平复位、清零信号。定义为0表示芯片复位;定义为1表示复位信号无效。
    input start;     //芯片使能信号。定义为0表示信号无效;定义为1表示芯片读入输入管脚得乘数和被乘数,并将乘积复位清零。
    input[15:0] ain;    //输入a(被乘数),其数据位宽为16bit.
    input[15:0] bin;    //输入b(乘数),其数据位宽为16bit.
    output[31:0] yout;    //乘积输出,其数据位宽为32bit.
    output done;        //芯片输出标志信号。定义为1表示乘法运算完成.

    reg[15:0] areg;    //乘数a寄存器
    reg[15:0] breg;    //乘数b寄存器
    reg[31:0] yout_r;    //乘积寄存器
    reg done_r;
    reg[4:0] i;        //移位次数寄存器

    always@(posedge clk)
    begin
        if(!rst_n) begin 
                areg <= 16'h0000;
                breg <= 16'h0000;
                done_r <= 1'b0;
                yout_r <= 32'h00000000;
                i <= 5'd0;
            end
        else if(start)        //启动运算
            begin
            
                if(i < 5'd21) i <= i+1'b1;
                if(i == 5'd0) begin    //锁存乘数、被乘数
                        areg <= ain;
                        breg <= bin;
                    end
                else if(i > 5'd0 && i < 5'd16) begin
                            if(areg[i-1]) yout_r = {1'b0,yout[30:15]+breg,yout_r[14:1]}; //累加并移位,Didong补充:向左移位,开始在高位相加,移位完成后就变                                                                                         //成就变成了满足低位了,就得到了我们需要的结果
                            else yout_r <= yout_r>>1;    //移位不累加         
                        end
                else if(i == 5'd16 && areg[15]) yout_r[31:16] <= yout_r[31:16]+breg;    //累加不移位
                else if(i == 5'd18) done_r <= 1'b1;    //乘完成标志位置位
                else if(i == 5'd20) done_r <= 1'b0;     //乘完成标志位清除
            end
         else i <= 5'd0;
    end
    
    assign done = done_r;
    assign yout = yout_r;

endmodule

posted on 2012-05-16 17:04  zhliao  阅读(1624)  评论(0)    收藏  举报