alt

4bit流水线乘法器的设计采用乘法竖式运算的思想,本质是将乘法运算转换为加法运算。具体实现思路如下图: alt 最后的temp0、temp1、temp2、temp3的相加结果就是相乘结果。

可以这么写:

reg [7:0] addr01;

reg [7:0] addr23;

 

wire [7:0] temp0 ;

wire [7:0] temp1 ;

wire [7:0] temp2 ;

wire [7:0] temp3 ;

 

assign temp0 = mul_b[0]? {4'b0, mul_a} : 'd0;

assign temp1 = mul_b[1]? {3'b0, mul_a, 1'b0} : 'd0;

assign temp2 = mul_b[2]? {2'b0, mul_a, 2'b0} : 'd0;

assign temp3 = mul_b[3]? {1'b0, mul_a, 3'b0} : 'd0;

 

always @(posedge clk or negedge rst_n) begin

       if(~rst_n) begin

              addr01  <= 'd0;

              addr23  <= 'd0;

              mul_out <= 'd0;

       end

       else begin

              addr01 <= temp0 + temp1;

              addr23 <= temp2 + temp3;

 

              mul_out <= addr01 + addr23;

       end

end

移位部分可以用组合逻辑实现,这里用了generate简化了代码。

`timescale 1ns/1ns

module multi_pipe#(
	parameter size = 4
)(
	input 						clk 		,   
	input 						rst_n		,
	input	[size-1:0]			mul_a		,
	input	[size-1:0]			mul_b		,
 
 	output	reg	[size*2-1:0]	mul_out		
);
    parameter N = size * 2;
    wire [N-1:0] temp [size-1:0];
    reg  [N-1:0] adder_0;
    reg  [N-1:0] adder_1;
    
    genvar i;
    generate
        for(i = 0;i < size; i = i + 1) begin: loop
            assign temp[i] = mul_b[i] ? mul_a << i : 'b0;
        end
    endgenerate
    
    always@(posedge clk or negedge rst_n) begin: adder0
        if(~rst_n)
            adder_0 <= 'b0;
        else
            adder_0 <= temp[0] + temp[1];
    end
    
    always@(posedge clk or negedge rst_n) begin: adder1
        if(~rst_n)
            adder_1 <= 'b0;
        else
            adder_1 <= temp[2] + temp[3];
    end
    
    always@(posedge clk or negedge rst_n) begin: gen_out
        if(~rst_n)
            mul_out <= 'b0;
        else
            mul_out <= adder_0 + adder_1;
    end
    
endmodule