整数乘法器

module multipier_module
(
	input clk,
	input rst_n,
	input Start_Sig,
	input [7:0]Multiplicand,
	input [7:0]Multiplier,
	output Done_Sig,
	output [15:0]Product
);

	reg[1:0]i;
	reg[7:0]Mcand;
	reg[7:0]Mer;
	reg[15:0]Temp;
	reg isNeg;
	reg isDone;
	
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			begin  //初始化
				i<=2'd0;
				Mcand<=8'd0;
				Mer<=8'd0;
				Temp<=8'd0;
				isNeg<=1'b0;
				isDone<=1'b0;
			end
		else if(Start_Sig)
			case(i)
				0:
				begin
					isNeg<=Multiplicand[7]^Multiplier[7];    //判断符号
					Mcand<=Multiplicand[7]?(~Multiplicand+1'b1):Multiplicand;  //取乘数的整数部分
					Mer<=Multiplier[7]?(~Multiplier+1'b1):Multiplier;
					Temp<=16'd0;
					i<=i+1'b1;
				end
				
				1:		//重复加几次的操作
				if(Mer==0)i<=i+1'b1;
				else begin Temp<=Temp+Mcand;Mer<=Mer-1'b1;end
				
				2:		//产生完成信号
				begin isDone <= 1'b0; i<=2'd0; end
				
				3:
				begin isDone <= 1'b0; i<=2'd0; end
			endcase
			
	assign Done_Sig=isDone;
	assign product=isNeg?(~Temp + 1'b1):Temp;   //如果isNeg是负值,取反加1 否则就是Temp的值
endmodule

				
					
//multipier_module.vt
module multipier_module_simulation();

	reg clk;
	reg rst_n;
	
	reg Start_Sig;
	reg[7:0]Multiplicand;
	reg[7:0]Multiplier;
	
	wire Done_Sig;
	wire[15:0]Product;
	
	initial 
	begin
		rst_n=0; #10; rst_n=1;
		clk=1;forever #10 clk=~clk;
	end
	
	multiplier_module U1
	(
		.clk(clk),
		.rst_n(rst_n),
		.Start_Sig(Start_Sig),
		.Multiplicand(Multiplicand),
		.Multiplier(Mulitiplier),
		.Done_Sig(Done_Sig),
		.product(Product)
	);
	
	reg[3:0]i;
	
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			begin 
				i<=4'd0;
				Start_Sig<=1'b0;
				Multiplicand<=8'd0;
				Multiplier<=8'd0;
			end
		else 
			case(i)
				0:
				if(Done_Sig)begin Start_Sig<=1'b0;i<=i+1’b1;end
				else begin Multiplicand<=8'd10; Multiplilier<=8'd2;Start_Sig<=1'b1;end
				
				1:
				if(Done_Sig)begin Start_Sig<=1'b0;i<=i+1'b1;end
				else begin Multiplicand<=8'd2;Multiplier<=8'd10;Start_Sig<=1'b1;end
				
				2:
				if(Done_Sig)begin Start_Sig<=1'b0;i<=i+1'b1;end
				else begin Multiplicand<=8'd11;Mulitiplier<=8'b11111011;Start_Sig<=1'b1;end
				
				3:
				if(Done_Sig)begin Start_Sig<=1'b0;i<=i+1'b1; end
				else begin Multiplicand<=8'b11111011;Mulitiplier<=8'b11110101;Start_Sig<=1'b1;end
				
				4:
				begin i<=4'd4;end
			endcase
endmodule		

上述实验是传统乘法器,的编写及其例化,但verilog的执行时间取决于被乘数,因此在实验二中对传统乘法器进行改进,即在累加操作之间,对乘数和被乘数进行比较大小,累加二者较小的次数 。

实验二改进的传统乘法器

1 初始化之际,取乘数和被乘数的正负关系,然后取乘数和被乘数的正值。

2 乘数和被乘数比较,如果被乘数小于乘数,则乘数和被乘数互换。

3 每一次累加操作,递减一次乘数,直到乘数的值为0,表示操作结束。

4 输出结果根据正负关系取得。

//multiplier_module_2.v
module multiplier_module_2
(
	input clk,
	input rst_n,
	input Start_Sig, 	//这是一个开始标志的寄存器
	
	input [7:0]Multiplicand,
	input [7:0]Multiplier,
	
	output Done_Sig,
	output [15:0]Product
);

	reg[2:0]i;
	reg[7:0]Mcand;		//乘数的数值部分(去掉符号)
	reg[7:0]Mer;		//被乘数的数值部分
	
	reg[15:0]Temp;		//乘积16位
	reg isNeg;
	reg isDone;
	
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			begin 
				i<=3'd0;
				Mcand<=8'd0;
				Mer<=8'd0;
				Temp<=16'd0;
				isNeg<=1'b0;
				isDone<=1'b0;
			end
		else if(Start_Sig)
			case(i)
				0:
				begin		//算出来符号,并且对乘数和被乘数都取整数准备计算
					isNeg<=Multiplicand[7]^Multiplier[7];
					Mcand<=Multiplicand[7]?(~Multiplicand+1'b1):Multiplicand;
					Mer<=Multiplier[7]?(~Multiplier+1'b1):Multiplier;
					Temp<=16'd0;
					i<=i+1'b1;
				end
				
				1:
				begin 		//比较乘数和被乘数的大小并交换位置
					{Mcand,Mer}<=Mcand<Mer?{Mer,Mcand}:{Mcand,Mer};  
					i<=i+1'b1;
				end
				
				2:		//交换后的乘数累加次数
				if(Mer==0)i<=i+1'b1;
				else begin Temp<=Temp+Mcand;Mer<=Mer-1'b1;end
				
				3:		//回0步骤
				begin isDone<=1'b1;i<=i+1'b1;end
				
				4:		//回0步骤
				begin isDone<=1'b0;i<=3'd0;end
				
			endcase
			
	assign Done_Sig=isDone;		//结束信号
	assign Product=isNeg?(~Temp+1'b1):Temp;		//如果乘积Temp是负数同样需要在原来的基础上进行取反后+!操作
emdmodule 

补码存在的意义就是避免计算机做减法。为啥要避免计算机做减法?因为已经有加法器,且用加法器就能够实现减法,所以就将减法操作转换为加法操作。

实验三:Booth算法乘法器

module booth_multiplier_module
(
	input clk, input rst_n,input Start_Sig, input[7:0]A, input [7:0]B,
	output [15:0]Product, output Done_Sig,
	output [7:0]SQ_a, output[7:0]SQ_s, output [16:0]SQ_p
);
	
	reg[3:0]i;
	reg[7:0]a;		//a寄存器用来寄存A值
	reg[7:0]s;		//s寄存器用来寄存-1(A)的值
	reg[16:0]p;
	reg[3:0]X;		//X表示n位,表示n次循环
	reg isDone;
	
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			begin 	
				i<=4'd0;
				a<=8'd0;
				s<=8'd0;
				s<=8'd0;
				p<=17'd0;
				X<=4'd0;
			end
		else if(Start_Sig)
			case(i)
				0:
				//初始化a,s的值,将P[8:1]位给B,其余位均为0
				begin a<=A;s<=(~A+1'b1);p<={8’d0,B,1'b0};i<=i+1'b1;end
				
				1:	//判断p[1:0]的操作
				if(X==8)begin X<=4'd0; i<=i+4'd2;end
				else if(p[1:0]==2'b01)begin p<={p[16:9]+a,p[8:0]};i<=i+1'b1;end
				else if(p[1:0]==2'b10)begin p<={p[16:9]+s,p[8:0]};i<=i+1'b1;end
				else i<=i+1'b1;
				
				2:	//向右移动1位是补0还是补1,完全取决于p[16]
				begin p<={p[16],p[16:1]};X<=X+1'b1;i<=i-1'b1;end
				
				3:
				begin isDone<=1'b1;i<=i+1'b1;end
				
				4:
				begin isDone<=1'b0;i<=4'd0;end
				
			endcase
	assign Done_Sig=isDone;
	assign product=p[16:1];
	
	assign SQ_a=a;
	assign SQ_s=S;
	assign SQ_p=p;
	
endmodule 

// Booth算法乘法器改进
module booth_multiplier_module_2
(
	input clk, input rst_n, input Start_Sig, input [7:0]A, input [7:0]B.
	output Done_Sig, output [15:0]Product, output [7:0]SQ_a, output [7:0]SQ_s, output [16:0]SQ_p	
);

	reg[3:0]i;
	reg[7:0]a;
	reg[7:0]s;
	reg[16:0]p;
	reg[7:0]Diff1;
	reg[7:0]Diff2;
	reg isDone;
	
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			begin 
				i<=4'd0;
				a<=8'd0;
				s<=8'd0;
				p<=17'd0;
				Diff1<=8'd0;
				Diff2<=8'd0;
				isDone<=1'b0;
			end
		else if(Start_Sig)
			case(i)
				0:
				begin 
					a<=A;
					s<=(~A+1'b1);
					p<={8'd0,B,1'b0};
					Diff<=8'd0;
					Diff<=8'd0;
					i<=i+1'b1;
				end
				1,2,3,4,5,6,7,8:    //8个循环操作使p空间的操作和移位可以在同一个时钟内完成
				begin	
					Diff1=p[16:9]+a;
					Diff2=p[16:9]+s;
					
					if(p[1:0]==2'b01)p<={Diff1[7],Diff1,p[8:1]};
					else if(p[1:0]==2'b10)p<={Diff2[7],Diff2,p[8:1]};
					else p<={p[16],p[16:1]};
					
					i<=i+1'b1;
				end
				9:
				begin isDone<=1'b1;i<=i+1'b1;end
				10:
				begin isDone<=1'b0;i<=4'd0;end
			endcase
	assign Done_Sig=isDone;
	assign Product=p[16:1];
	assign SQ_a=a;
	assign SQ_p=s;
	assign SQ_p=p;
endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小菜鸡变形记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值