一、实验原理图
二、实验步骤
本次实验的目的是将乘法器改成被乘数每次左移两位,从而减少一半的运算周期。multiply.v的代码修改如下:
对被乘数代码的修改
//加载被乘数,运算时每次左移两位
reg [63:0] multiplicand;
always @ (posedge clk)
begin
if (mult_valid)
begin // 如果正在进行乘法,则被乘数每时钟左移两位
multiplicand <= {multiplicand[61:0],2'b00};
end
else if (mult_begin)
begin // 乘法开始,加载被乘数,为乘数1的绝对值
multiplicand <= {32'd0,op1_absolute};
end
end
对乘数代码的修改
//加载乘数,运算时每次右移一位
reg [31:0] multiplier;
always @ (posedge clk)
begin
if (mult_valid)
begin // 如果正在进行乘法,则乘数每时钟右移两位
multiplier <= {2'b00,multiplier[31:2]};
end
else if (mult_begin)
begin // 乘法开始,加载乘数,为乘数2的绝对值
multiplier <= op2_absolute;
end
end
对部分积的运算代码的修改
// 部分积
wire [63:0] partial_product1;
wire [63:0] partial_product2; //定义两个临时变量
assign partial_product1 = multiplier[0] ? multiplicand : 64'd0;
//乘数末位为1,临时变量1是乘数本身;乘数末位为0,临时变量1是0
assign partial_product2 = multiplier[1]?{multiplicand[62:0],1'b0} : 64'd0;
//乘数倒数第二位为1,临时变量2由被乘数左移一位得到;乘数倒数第二位为0,临时变量2是0
对累加器的修改
//累加器
reg [63:0] product_temp;
always @ (posedge clk)
begin
if (mult_valid)
begin
product_temp <= product_temp + partial_product1+ partial_product2;
end
else if (mult_begin)
begin
product_temp <= 64'd0; // 乘法开始,乘积清零
end
end
由于改进后的代码比源代码只多增加了一个wire的临时变量,故对multiply.xdc、 multiply_display.v等文件不需要修改
三、实验结果分析
testbench结果
由testbech波形可知,经过修改的乘法器可以节省一半的周期
FPGA结果
经计算器验证后可知答案正确
四、总结感悟
经过这次简单的修改我感受到了对数据运算的改进有很大的空间,在这次实验中我也学会了新知识。