FPGA中乘法器的流水线实现

乘法器系列:


一、流水线乘法器设计

1.1 流水线设计思想简介

📄流水线是一种经典的设计思想,它是将一个处理过程分为若干个子过程,每个子过程由专门的模块进行处理;然后多个过程在时间上错开,这样就可以实现每个子过程和其它过程的子过程并行运行。在输入数据量很多时,使用流水线设计可以大幅减少处理时间,有效地解决了多周期串行计算效率低的问题。

可参考:Verilog流水线设计——Pipeline

1.2 程序设计

①顶层模块:multiply_top.v

module multiply_top
    #(parameter N=5,
      parameter M=5)//N>=M,M决定了流水线的级数
     (
      input                    clk             ,//输入时钟
      input                    rstn            ,//复位信号     
      input         [N-1:0]    multiplicand    ,//被乘数
      input         [M-1:0]    multiplier      ,//乘数
      input                    mult_en         ,//输入使能信号
      output        [M+N-1:0]  result          ,//最后结果
      output                   mult_end_f       //第一次运算结束标志
      );
//各级间传递数据的数组      
wire [N+M-1:0] result_acco_t [M-1:0];
wire [N+M-1:0]   multiplicand_t [M-1:0];
wire [M-1:0]   multiplier_t [M-1:0];
wire           mult_end_t[M-1:0] ;

//第一级需单独例化
multiply_cell #(.N(N), .M(M))
        mult_u0
     (
        .clk           (clk)  ,
        .rstn          (rstn)  ,
        .multiplicand  ({{(M){0}},multiplicand})  ,
        .multiplier    (multiplier)  ,
        .result_acci   (0)  ,
        .mult_en       (mult_en)  ,

        .mult_end      (mult_end_t[0])  ,
        .result_acco   (result_acco_t[0])  ,
        .multiplicand_r(multiplicand_t[0])  ,
        .multiplier_r  (multiplier_t[0])    
);
//其余各级例化
genvar i;
generate 
    for(i=1;i<=M-1;i=i+1)begin
        multiply_cell #(.N(N), .M(M))
            u_mult_step
     (
        .clk           (clk)  ,
        .rstn          (rstn)  ,
        .multiplicand  (multiplicand_t[i-1])  ,
        .multiplier    (multiplier_t[i-1])  ,
        .result_acci   (result_acco_t[i-1])  ,
        .mult_en       (mult_end_t[i-1])  ,

        .mult_end      (mult_end_t[i])  ,
        .result_acco   (result_acco_t[i])  ,
        .multiplicand_r(multiplicand_t[i])  ,
        .multiplier_r  (multiplier_t[i])            
);        
    end
endgenerate

assign result=result_acco_t[M-1];
assign mult_end_f=mult_end_t[M-1];

endmodule


📄通过generate语句和数组实现各级间信号的传递。

②子模块:multiply_cell.v

/**********************************
=========multiply_cell.v==========
Description : 子级模块
***********************************/

module multiply_cell
    #(parameter N=5,
      parameter M=5)//N>=M
     (
     input                   clk             ,
     input                   rstn            ,
     input         [N+M-1:0] multiplicand    ,
     input         [M-1:0]   multiplier      ,
     input         [N+M-1:0] result_acci     ,//上一级的运算结果输入
     input                   mult_en         ,
     
     output  reg             mult_end        ,
     output  reg   [N+M-1:0] result_acco     ,//这一级的运算结果输出
     //移位的中间结果
     output  reg   [N+M-1:0] multiplicand_r  ,
     output  reg   [M-1:0]   multiplier_r      
);

//一次运算
always @(posedge clk or negedge rstn)begin
    if(!rstn)begin
        mult_end<='b0;
        result_acco<='b0;
        multiplicand_r<='b0;
        multiplier_r<='b0;
    end
    else if(mult_en)begin
        multiplicand_r<=multiplicand<<1;
        multiplier_r<=multiplier>>1;
        mult_end<=1'b1;
        result_acco<=multiplier[0] ? result_acci+multiplicand:result_acci;
    end
    else begin
        mult_end<='b0;
        result_acco<='b0;
        multiplicand_r<='b0;
        multiplier_r<='b0;
    end
end
    
endmodule


📄子模块中实现了整个乘法过程中的一次运算,包括一次乘数、被乘数的移位和一次累加

1.3 仿真

在这里插入图片描述

📄将M设为5,可以看出,开始时经过5个时钟周期,输出第一个运算结果;而后续每次运算输出都只需要一个时钟周期,实现了流水输出

注:由于后续结果输出需要一个时钟周期,所以仿真时输入不同运算数据的时间间隔不能小于一个时钟周期。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hi小瑞同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值