顺序乘法器,含verilog代码

顺序乘法器,含verilog代码

我们需要明确的是两个D_WIDTH位宽的数相乘,结果位宽为2D_WIDTH, 对于负数乘法,可以利用乘数和被乘数的符号位进行异或得到积的符号位,通过判断符号位得到乘数和被乘数的绝对值,将负数乘法转为无符号数乘法进行运算,首先初始化乘数寄存器和被乘数寄存器Multiplicand,被乘数寄存器的低D_WIDTH位为输入的被乘数的绝对值,高D_WIDTH位为0,初始化乘积寄存器product[2D_WIDTH-1:0]=0,
if (Multiplier>0)
product< = Multiplier[0]? Multiplicand+ product : product;
Multiplicand <={ Multiplicand [2*D_WIDTH-2:0] ,1’b0}
Multiplier<= {1’b0,Multiplier[D_WIDTH-1:1]};
end
在这里插入图片描述
上图中可以看到,二进制计算乘法比较简单,由于每一位上只有0和1,乘法计算其实就简化成了位移和加法,乘数每一位和被乘数相乘,结果不是完全复制就是0,只不过对应着不同的位移。
为了节约晶体管,只需从低位开始将被乘数逐次左移一位,乘数逐次右移一位,不断将计算结果加在上一步的结果上,直到乘数为0不能再右移为止。
这种方式虽然节约了电路但由于下一步加法依赖上一步加法计算结果,下一步位移也依赖上一步位移结果,因此只能顺序进行,结果就是运算比较慢。无法用单纯的组合逻辑电路形成,因为被乘数寄存器和乘积寄存器内容发生变化需要时序控制
在这里插入图片描述

module multi_seq#(parameter D_WIDTH=8)(
	input 						clk,
	input 						rst_n,
	input [D_WIDTH-1:0]			mul_A, 
//被乘数,5位,有符号补码
	input [D_WIDTH-1:0]			mul_B,	
//乘数5位,有符号补码
	input 						start,
	output reg [2*D_WIDTH-1:0]	result,
	output reg 					done
);
  reg[1:0] 						state;
  reg[2*D_WIDTH-1:0]			multi_A;
  reg[D_WIDTH-1:0]				multi_B;
  reg[2*D_WIDTH-1:0]		    result_tmp;
  reg 							neg;
  wire [D_WIDTH-1:0]			abs_A;
  wire [D_WIDTH-1:0]			abs_B;

assign abs_A = mul_A[D_WIDTH-1] ? ~mul_A+1 : mul_A ;
assign abs_B = mul_B[D_WIDTH-1] ? ~mul_B[D_WIDTH-1:0]+1 : mul_B ;
  
always@(posedge clk)
	if(~rst_n) begin
		multi_A <= 0;
		multi_B <= 0;
		neg <= 0;
		done <= 0;
		result_tmp <= 0;
		state <= 0;
		result <= 0;
	end
	else if(start) 
		case(state)
			0: begin	//{D_WIDTH{1'b0}}
				multi_A <= {{D_WIDTH{1'b0}},abs_A};
				multi_B <= abs_B;
				neg <= mul_A[D_WIDTH-1]^mul_B[D_WIDTH-1];
				done <= 0;
				state <= state+1;
				result_tmp <= 0;
			end
			1:begin
				if(multi_B>0) begin
					result_tmp<=multi_B[0]?(result_tmp + multi_A) : result_tmp;
					multi_B <= {1'b0,multi_B[D_WIDTH-1:1]};
					multi_A <={multi_A[2*D_WIDTH-2:0],1'b0};
				end
				else begin
					state <= state + 1;
				end
			end
			2:begin
				done<=1'b1;
				result<= neg ? (~result_tmp+1): result_tmp;
				state <= state+1;
			end
			3: begin
				done<=1'b0;
				state<=0;
			end
		endcase
endmodule

至于testbench,可以用上一篇的,在此记录一下

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值