4bit流水线乘法器的设计采用乘法竖式运算的思想,本质是将乘法运算转换为加法运算。具体实现思路如下图: 最后的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