Booth算法乘法器

乘法器分类:
A. 传统乘法器(及其改进)
传统乘法器的实现很简单,第一步就是去被乘数和乘数的正负关系然后去被乘数和乘数的正值;第二步:乘法本就是累加,乘多少就是累加多少次,所以第二步是累加操作,每加一次被乘数,递减一次乘数,直到乘数为0,表示操作结束;第三步:输出结果根据正负关系取得。
主要代码:
在这里插入图片描述
改进:
如果传统的乘法器乘数与被乘数固定,就导致时钟完全由乘数定,这就有问题了:比如2×10就是把2累加10次,这样乘数递减,时钟就为10,太浪费时钟了。所以可以在乘法操作之前先进行被乘数和乘数大小得比对,让大的做被乘数,小的做乘数,这样时钟小号就尽可能的小
主要代码:
在这里插入图片描述
B. Booth算法乘法器(及其改进)
以下主要解释。
C. LUT查表法乘法器(及其改进)
很简单,就是提前算好存到一个ROM中,要计算时取出。当然也有很多的优化,不做赘述了。

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
被乘数和乘数为N位,就循环N位。

module Booth_multiplier#(
	parameter DATAWIDTH = 8
)
(
	input                            CLK,
	input                            RSTn,
	input                            START,
	input  [ DATAWIDTH - 1 : 0 ]     A,
	input  [ DATAWIDTH - 1 : 0 ]     B,
	
	output [ DATAWIDTH * 2 - 1 : 0 ] RESULT,
	output                           Done
);

reg [ DATAWIDTH - 1 : 0 ] i;
reg [ DATAWIDTH * 2 : 0 ] P;
reg [ DATAWIDTH - 1 : 0 ] A_reg;
reg [ DATAWIDTH - 1 : 0 ] A_bm;
reg [ DATAWIDTH - 1 : 0 ] N;
reg                       isDone;

always @ ( posedge CLK or negedge RSTn )
begin
	if (!RSTn)
	begin
		i <= 0;
		P <= 0;
		A_reg <= 0;
		A_bm <= 0;
		N <=0;
		isDone <= 0;
	end
	else if (START)
	begin
		case (i)
		
			0:
				begin
					A_reg <= A;
					A_bm <= ~A + 1'b1;    //complement code of A
					P <= { 8'd0, B, 1'b0 };  //B add to last 8bit of P
					i <= i + 1'b1;
					N <= 0;
				end
			1://operating
				begin
					if (N == 8)
						begin
							N <= 0;
							i <= i + 2'b10;
						end
					else if (P[1:0] == 2'b00 | P[1:0] == 2'b11)
						begin
							P <= P;
							i <= i + 1'b1;
						end
					else if (P[1:0] == 2'b01)
						begin
							P <= {P[16:9] + A_reg,P[8:0]};
							i <= i + 1'b1;
						end
					else if (P[1:0] == 2'b10)
						begin
							P <= {P[16:9] + A_bm,P[8:0]};
							i <= i + 1'b1;
						end

				end
			2://shift
				begin
					P <= {P[16],P[16:1]};
					N <= N + 1'b1;
					i <= i - 1'b1;
				end
			3:
				begin
					isDone <= 1;
					i <= i + 1'b1;
				end
			4:
				begin
					isDone <= 0;
					i <= 0;
				end
		
		endcase
	end
end

assign Done = isDone;
assign RESULT = P[16:1];

endmodule
module Booth_multiplier_tb();

	parameter DATAWIDTH = 8;
	
	reg                           CLK;
	reg                           RSTn;
	reg                           START;
	reg  [ DATAWIDTH - 1 : 0 ]    A;
	reg  [ DATAWIDTH - 1 : 0 ]    B;
	wire [ DATAWIDTH * 2 - 1 : 0 ]RESULT;
	wire                          Done;
	
	
initial 
begin
	CLK = 0;
	forever #10 CLK = ~CLK;
end

initial
begin
	RSTn = 0;
	START = 0;
	#10 RSTn = 1;START = 1;
	A = 2;
	B = 4;
	#400
	A = 3;
	B = 5;
	#400
	A = 4;
	B = 6;
	#400
	A = 10;
	B = 19;
	#400
	A = 32;
	B = 45;
	#400
	A = 23;
	B = 45;
	#400
	A = 32;
	B = 12;
	#400
	A = 32;
	B = 15;
	#400
	$stop;
end

Booth_multiplier BM(.CLK(CLK),
                    .RSTn(RSTn),
					.START(START),
					.A(A),
					.B(B),
					.RESULT(RESULT),
					.Done(Done));
endmodule

仿真结果:
在这里插入图片描述
在这里插入图片描述

posted @ 2019-09-11 17:42  晨青  阅读(2296)  评论(1编辑  收藏  举报