设计思想
“移位后加”,加法运算采用加法器树的形式。
乘法运算过程:被乘数与乘数的每位相乘,由于需要移位,将其乘以相应权值实现,例如二进制数乘以2的一次幂可实现整体移动一位(在代码中使用扩展0,进行移位)。最后将所得结果相加,得到最终的乘法结果。
Verilong HDL设计
module mul_addtree(mul_a,mul_b,mul_out);
input [3:0] mul_a,mul_b; //IO declaration,a:乘数 b:被乘数
output [7:0] mul_out;
wire [7:0] mul_out; //Wire declaration
wire [7:0] stored0,stored1,stored2,stored3;
wire [7:0] add01,add23;
assign
stored3 = mul_b[3]?{1'b0,mul_a,3'b0}:8'b0;
assign
stored2 = mul_b[2]?{2'b0,mul_a,2'b0}:8'b0;
assign
stored1 = mul_b[1]?{3'b0,mul_a,1'b0}:8'b0;
assign
stored0 = mul_b[0]?{4'b0,mul_a}:8'b0;
assign
add01 = stored1 + stored0;
assign
add23 = stored3 + stored2;
assign
mul_out = add01 + add23;
endmodule
//----------testbench----------
module mult_addtree_tb;
reg [3:0]mult_a;
reg [3:0]mult_b;
wire [7:0]mult_out;
mul_addtree U1(.mul_a(mult_a),.mul_b(mult_b),.mul_out(mult_out)); //moudule instance
initial //Stimull signal
begin
mult_a = 0 ; mult_b = 0;
repeat(9)
begin
#20 mult_a = mult_a + 1;
mult_b = mult_b + 1;
end
end
endmodule
流水线结构
两级流水线加法器树4位乘法器结构如图所示,通过在第一级与第二级、第二级与第三级加法器之间插入D触发器组,可以实现两级流水线设计。
module mul_addtree_2_stage(clk,clr,mul_a,mul_b,mul_out);
input clk,clr;
input [3:0] mul_a,mul_b; //IO declaration,a:乘数 b:被乘数
output [7:0] mul_out;
reg [7:0] add_tmp_1,add_tmp_2,mul_out; //Wire declaration
wire [7:0] stored0,stored1,stored2,stored3;
assign
stored3 = mul_b[3]?{1'b0,mul_a,3'b0}:8'b0;
assign
stored2 = mul_b[2]?{2'b0,mul_a,2'b0}:8'b0;
assign
stored1 = mul_b[1]?{3'b0,mul_a,1'b0}:8'b0;
assign
stored0 = mul_b[0]?{4'b0,mul_a}:8'b0;
always@(posedge clk or negedge clk) //Timing control
begin
if(!clr) begin
add_tmp_1 <= 8'b0000_0000;
add_tmp_2 <= 8'b0000_0000;
mul_out <= 8'b0000_0000;
end
else begin
add_tmp_1 <= stored3 + stored2;
add_tmp_2 <= stored1 + stored0;
mul_out <= add_tmp_1 + add_tmp_2;
end
end
endmodule
//----------testbench----------
module mult_addtree_2_stag_tb;
reg clk,clr;
reg [3:0]mult_a;
reg [3:0]mult_b;
wire [7:0]mult_out;
mul_addtree_2_stage U1(.mul_a(mult_a),.mul_b(mult_b),.mul_out(mult_out),.clk(clk),.clr(clr));
initial //Stimull signal
begin
clk = 0,clr = 0, mult_a = 0 ; mult_b = 0;
# 5 clr = 1;
end
always #10 clk = ~clk;
initial
begin
repeat(5)
begin
#20 mult_a = mult_a + 1; mult_b = mult_b + 1;
end
end
endmodule