Verilog编程-2. 流水线乘法器设计

Verilog编程-2. 流水线乘法器设计

1. 背景

​ 在Verilog中,我们一般使用乘法器时直接用*来直接完成,或者调用相关IP核来生成高性能乘法器,但是归根到底Verilog描述的是硬件电路,从数字电路而不是高层次语法角度来实现乘法器可以让我们对于乘法器的运行有着更深入的理解。

2. 设计思路

​ 二进制乘法与我们熟悉的十进制乘法类似,其原理都是被乘数与乘数的每一位按位相乘并进行移位,其原理示意图如下图所示:

在这里插入图片描述

据此,我们自然可以想到,先将被乘数进行扩位到乘积的位宽,同时被乘数和乘数进行移位(被乘数左移,乘数右移),通过判断乘数最低位进而累加被乘数,从而可以得到最终的乘积结果。由于乘积的宽度不会大于被乘数和乘数位宽之和,所以就首先将被乘数扩位到两者之和的位宽即可。再向前一步,由于移位累加需要的周期数至少是乘数的位宽,所以我们可以采用流水线的方式,将每一步累加的结果都保存下来,进而给下次的乘法腾出计算空间,这样可以提升乘法器运行的效率。

3. 代码

​ 所有程序编辑平台为vscode,仿真平台为ubuntu系统中的vcs工具,分别包括源文件mult_low.vmult_cell.vmult_pipeline.v,仿真文件mult_low_tb.vmult_pipeline_tb.v,路径名列表文件mult_low.fmult_pipeline.fmakefile文件,其中源文件和仿真文件的原始来源是 6.7 Verilog流水线。文件具体内容如下

源文件 mult_low.v

module mult_low #(
    parameter N = 4,
    parameter M = 4 ) (

    input               clk,
    input               rstn,
    input               data_rdy,   // 数据输入使能
    input  [N-1:0]      mult1,
    input  [M-1:0]      mult2,

    output              res_rdy,   // 数据输出使能
    output [N+M-1:0]    res
);
    
    // 下面的always过程块很重要,会让cnt=0保持两个时钟周期,从而让计算不出错
    reg [31:0] cnt;
    wire [31:0]          cnt_temp = (cnt == M)? 'b0 : cnt + 1'b1 ;
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            cnt    <= 'b0 ;
        end
        else if (data_rdy) begin    //数据使能时开始计数
            cnt    <= cnt_temp ;
        end
        else if (cnt != 0 ) begin  //防止输入使能端持续时间过短
            cnt    <= cnt_temp ;
        end
        else begin
            cnt    <= 'b0 ;
        end
    end

    reg [M-1:0]     mult2_shift;
    reg [N+M-1:0]   mult1_shift;
    reg [N+M-1:0]   mult1_acc;
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            mult2_shift <= 'b0;
            mult1_shift <= 'b0;
            mult1_acc   <= 'b0;            
        end

        // 初始化的过程,所以在前
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值