Verilog HDL:使用移位操作符实现无符号数乘法(位宽可修改)

目录

1、原理分析

2、源程序代码

3、仿真代码

4、仿真结果


1、原理分析

这里以二进制数data_a[3:0]与data_b[2:0]的乘法为例,

其中可以看出,data_a [ i ] ( i = 0,1,2,3 )分别对 data_b [2:0] 进行了乘法操作,但是 data_a [ 1 ] 比data_a [ 0 ] 对data_b的操作结果高一位,所以每次 data_a [ i ] 进行乘法操作后需要对 data_b 左移一位,再和 data_a [ i+1 ] 进行乘法操作,总共进行的乘法操作次数为 data_a 的位宽,移位操作次数为 data_a 的位宽减1。

由于 data_b 为三位宽,进行左移操作的时候会导致首位丢失,如1 1 1<<1 = 1 1 0,故我们需要对data_b 进行补零操作,补零个数为移位操作次数。同时为了保证data_a [ i ] 同 data_b 的每一位进行运算,需要将data_a [ i ] 拓展后和data_b(或补零移位后的 data_b )进行与(&)操作。如

最后,将每一次与(&)的结果相加得最后乘法器结果。

2、源程序代码

//方案1
module  shift_mult
#(
    parameter  sizea  = 8,
    parameter  sizeb  = 8
)
(
    input   wire    [sizea-1:0]         a     ,
    input   wire    [sizeb-1:0]         b     ,
    output  reg     [sizea+sizeb-1:0]   result
);

integer                 index  ;
reg   [sizea+sizeb-1:0] reg_b  ;

always@(*) begin
    result= 0;
    reg_b = {{(sizea-1){1'b0}}, b };
    for(index = 0;index < sizea;index = index + 1) begin
        result= result + ({ (sizea+sizeb){a[index]}} & (reg_b << index));
    end
end

endmodule
//方案2
module shift_mult
#(
    parameter sizea = 8,
    parameter sizeb = 8
)
(
    input   wire [sizea-1:0]        a       ,
    input   wire [sizeb-1:0]        b       ,
    output  reg  [sizea+sizeb-1:0]  result
);

reg [sizea+sizeb-1:0] shift_a;
reg [sizeb-1:0] shift_b;

always@(*)begin
    shift_a = a;
    shift_b = b;
    result = 0;
    repeat(sizeb) begin
        if(shift_b[0])
            result = result + shift_a;
        else
            result = result;
        
        shift_a = shift_a <<1;
        shift_b = shift_b >>1;
    end
end

endmodule

3、仿真代码

`timescale 1ns/1ns
 
module shift_mult_tb();
 
parameter  sizea  = 8;
parameter  sizeb  = 8;

reg       [sizea-1:0]           a;
reg       [sizeb-1:0]           b;
wire      [sizea+sizeb-1:0]     res_ture;
wire      [sizea+sizeb-1:0]     result;
wire                            t_or_f;
 
initial begin   
    repeat(100) begin
        a <= $random;
        b <= $random; 
        #20;        
    end
end
 
assign  res_ture = a * b;
assign  t_or_f = (res_ture == result) ? 1'b1 : 1'b0;

shift_mult
#(
    .sizea(sizea),
    .sizeb(sizeb)
)
shift_mult_inst
(
    .a(a),
    .b(b),
    .result(result)
);
endmodule

4、仿真结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值