乘法器分類:
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
仿真結果:


