发布时间:2024-09-05 13:01
两个数相乘,无论是同号相乘还是异号相乘,其实最后结果的数值与符号无关,只取两个数的绝对值相乘,最后结果的符号为被乘数与乘数的符号异或即可。
然后乘法可以看成累加操作,累加次数为乘数的数值大小,累加值为被乘数。每累加一次,乘数减一,直到乘数减到0,则相乘结束。
该乘法器的大致操作如下:
(一)在初始化之际,取乘数和被乘数的正负关系,然后取被乘数和乘数的正值。
(二)每一次累加操作,递减一次乘数。直到乘数的值为零,表示操作结束。
(三)输出结果根据正负关系取得。
实现代码如下:
module multiplier_module
(
input CLK,
input RSTn,
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 RSTn )
if( !RSTn )
begin
i <= 2\'d0;
Mcand <= 8\'d0; // Register for Multiplicand
Mer <= 8\'d0; // Register ofr Multipier
Temp <= 8\'d0; // Sum of pratocal product
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: // Multipling
if( Mer == 0 ) i <= i + 1\'b1;
else begin Temp <= Temp + Mcand; Mer <= Mer - 1\'b1; end
2:
begin isDone <= 1\'b1; i <= i + 1\'b1; end
3:
begin isDone <= 1\'b0; i <= 2\'d0; end
endcase
/*************************/
assign Done_Sig = isDone;
assign Product = isNeg ? ( ~Temp + 1\'b1 ) : Temp;
/*************************/
endmodule
但是这种方法的缺点也是显而易见的,当乘数很大时(绝对值很大时),需要累加的次数也随之增大
这篇文章写的挺好的booth乘法器
但这篇并没有说到booth算法的原理
下面这篇文章说到了
booth算法原理
就是提前吧结果存在存储器中,乘法的结果以查表的方式取得。是典型的用空间换时间的方法。
[2101] [ICCV 2021] Tokens-to-Token ViT: Training Vision Transformers from Scratch on ImageNet
中国电信发布运营商行业首个云原生关系型数据库TeleDB for openGauss
openCV项目实战-信用卡数字识别PyCharm版(唐宇迪)
独立产品灵感周刊 DecoHack #022 - 截图应用如何在一个月收入 8000 美元
Docker Compose安装使用,及搭建nginx+php+mysql基础应用实例