無符號乘法器的兩種寫法:移位相加和流水線


相比於有符號乘法器,無符號乘法器就不需要考慮符號位的判斷,直接計算即可。乘法器簡單理解也就是每一位相乘過后相加取和的結果,唯獨需要考慮的是:“每一位相乘”,這就需要考慮進行移位操作。而兩種不同的寫法就是是否添加了寄存器,有符號乘法器的詳細例子:https://www.cnblogs.com/shadow-fish/p/13368689.html

1:兩個N位二進制數相乘結果為2N位。

 out_c = out_c + ((b_in[i]==1'b1)?({4'b0,a_in}<<i):0); //這個跟下方的主要部分是一致的。

移位相加型乘法器

module shift_add(a,b,out);

input [3:0]a;
input [3:0]b;
output [7:0]out;

reg [7:0]out_c;
integer i;
always@(a or b) begin
    out_c = 8'b0;
    for(i=0;i<=3;i=i+1) begin
        out_c = out_c + ((b[i]==1'b1)?(a<<i):0);
    end
end
assign out = out_c;
endmodule

tb文件:

`timescale 1ns/1ps
module shift_add_tb;
reg [3:0]a;
reg [3:0]b;

wire [7:0]out;

shift_add u1(
    .a(a),
    .b(b),
    .out(out)
);
initial begin
    a=4'b1101;
    b=4'b0011;
    #20;
    a=4'b1011;
    b=4'b1100;
end
endmodule

 

 

流水線設計--添加寄存器:先將相鄰的乘積進行相加,然后再輸出最終結果

module pipline_add (
    clk,rst,a,b,out
);
    input clk;
    input rst;
    input [3:0]a; //被乘數
    input [3:0]b; //乘數
    output [7:0]out;

    reg [7:0]out;
    reg [7:0]out_1;
    reg [7:0]out_2;
    reg [7:0]out_3;
    reg [7:0]out_4;
    reg [7:0]out_5;
    reg [7:0]out_6;

    always @(posedge clk or negedge rst) begin
        if(!rst) begin
            out <= 8'b0;
            out_1 <= 8'b0;
            out_2 <= 8'b0;
            out_3 <= 8'b0;
            out_4 <= 8'b0;
            out_5 <= 8'b0;
            out_6 <= 8'b0;
        end
        else begin
            out_1 <= ((b[0]==1'b1)?({4'b0,a}):8'b0); //判斷乘數位是否為1,若是,則結果進行對應位的移位
            out_2 <= ((b[1]==1'b1)?({3'b0,a,1'b0}):8'b0);
            out_3 <= ((b[2]==1'b1)?({2'b0,a,2'b0}):8'b0);
            out_4 <= ((b[3]==1'b1)?({1'b0,a,3'b0}):8'b0);

            out_5 <= out_1 + out_2; //添加流水線
            out_6 <= out_3 + out_4;

            out <= out_5 + out_6;
        end
    end
endmodule

tb文件:

`timescale 1ns/1ps
module pipline_add_tb;

    reg clk;
    reg rst;
    reg [3:0]a;
    reg [3:0]b;
    
    wire [7:0]out;

    pipline_add u1(
        .clk(clk),
        .rst(rst),
        .a(a),
        .b(b),
        .out(out)
    );
    
    initial begin
        clk = 1'b0;
        rst = 1'b0;
        #5;
        rst = 1'b1;
    end

    always #5 clk = ~clk;

    initial begin
        a = 4'b1101;
        b = 4'b1000;
        #60;
        a = 4'b0110;
        b = 4'b1001;
        #80;
        $stop();
    end
endmodule

此上均是只進行了功能仿真,未進行時序仿真。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM