乘法器分类:
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
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/211356.html原文链接:https://javaforall.net
