前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分时复用的移位相加乘法器

分时复用的移位相加乘法器

作者头像
月见樽
发布2018-04-27 11:35:58
7690
发布2018-04-27 11:35:58
举报

基本算法

移位相加即是日常我们使用的手算算法,移位相加的描述如下

  • 设置积的初值为0
  • 若乘数的最低位为0,则积不变,否则累加被乘数
  • 若乘数的第一位为0,则积不变,否则累加向左移位一位的被乘数
  • ...
  • 若乘数的第n位(最高位)为0,则积不变,否则累加向左移位n位的被乘数

RTL代码

代码语言:javascript
复制
module serial_shiftadder_multipcation # (
    parameter WIDTH = 4
)(
    input clk,    // Clock
    input rst_n,  // Asynchronous reset active low

    input multiplier_valid,
    input [WIDTH - 1:0]multiplier1,
    input [WIDTH - 1:0]multiplier2,

    output reg product_valid,
    output reg [2 * WIDTH - 1:0]product
);

接口定义部分,采用参数化设计,WIDTH为乘数/被乘数的位宽,multiplier_valid拉高时表示输入有效,并开始计算。product_valid被拉高时表示计算完成,当前的输出是有效的

代码语言:javascript
复制
/*****************buffer and shift*******************/
reg [WIDTH - 1:0]min_mult;
reg [2 * WIDTH - 1:0]max_mult;
always @ (posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        {max_mult,min_mult} <= 'b0;
    end else if(multiplier_valid == 1'b1) begin
        if(multiplier1 > multiplier2) begin
            max_mult <= '{multiplier1};
            min_mult <= multiplier2;
        end else begin
            max_mult <= '{multiplier2};
            min_mult <= multiplier1;
        end
    end else if(min_mult != 'b0) begin
        max_mult <= max_mult << 1;
        min_mult <= min_mult >> 1;
    end else begin
        max_mult <= max_mult;
        min_mult <= min_mult;
    end
end

移位部分,有输入时比较两个输入的大小,使用小的数控制迭代数量,减小时间消耗。若较小的乘数不为0,则将较大的数向左移位,较小的的数向右位移。

代码语言:javascript
复制
/******************adder********************/
always @ (posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        {product_valid,product} <= 'b0;
    end else if(min_mult[0] == 1'b1) begin
        product <= product + max_mult;
        product_valid <= 1'b0;
    end else if(min_mult != 'b0) begin
        product <= product;
        product_valid <= 1'b0;
    end else if(multiplier_valid == 1'b1) begin
        product <= 'b0;
        product_valid <= 1'b0;
    end else begin
        product <= product;
        product_valid <= 1'b1;
    end
end

endmodule

累加部分,若较小的乘数最低位为0,保持积不变,否则累加当前的大乘数,当小乘数为0是,表示运算已经结束,输出有效拉高。

测试

使用自动化测试,使用高层次方法计算积,再与输出比较看是否相等

代码语言:javascript
复制
module mult_tb (
);

parameter WIDTH = 4;

logic clk,rst_n;
logic multiplier_valid;
logic [WIDTH - 1:0]multiplier1;
logic [WIDTH - 1:0]multiplier2;

logic product_valid;
logic [2 * WIDTH - 1:0]product;

serial_shiftadder_multipcation # (
    .WIDTH(WIDTH)
) dut (
    .clk(clk),    // Clock
    .rst_n(rst_n),  // Asynchronous reset active low

    .multiplier_valid(multiplier_valid),
    .multiplier1(multiplier1),
    .multiplier2(multiplier2),

    .product_valid(product_valid),
    .product(product)
);

initial begin
    clk = 1'b0;
    forever begin
        #50 clk = ~clk;
    end
end

initial begin
    rst_n = 1'b1;
    #5 rst_n = 1'b0;
    #10 rst_n = 1'b1;
end

initial begin
    {multiplier_valid,multiplier1,multiplier2} = 'b0;
    forever begin
        @(negedge clk);
        if(product_valid == 1'b1) begin
            multiplier1 = (WIDTH)'($urandom_range(0,2 ** WIDTH));
            multiplier2 = (WIDTH)'($urandom_range(0,2 ** WIDTH));
            multiplier_valid = 1'b1;
        end else begin
            multiplier_valid = 1'b0;
        end
    end
end

logic [2 * WIDTH - 1:0]exp;
initial begin
    forever begin
        @(posedge product_valid);
        exp = multiplier1 * multiplier2;
        if(exp == product) begin
            $display("successfully, mult1=%d mult2=%d product=%d",multiplier1,multiplier2,product);
        end else begin
            $display("failed,mult1=%d mult2=%d product=%d exp=%d",multiplier1,multiplier2,product,exp);
        end
    end
end

endmodule
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.08.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本算法
  • RTL代码
  • 测试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档