八位“Booth二位乘算法”乘法器
原理
补码乘法器
之前介绍了几篇无符号乘法器或加法器的写法,当然,稍作修改也就可以改成符合有符号数的乘法器或加法器。
但是呢,我们之前写的乘法器或加法器,其实都是默认是很奇怪?如果没办法理解的话,我建议你可以尝试对它求补码,看看是不是可以保持首位符号位不变,余位取反加一。惊叹于设计师的机智。
补码乘法器的原理讲明白了,具体电路实现的话,大家可以尝试一下,本节重点不在于此。
Booth一位乘
在上面已经讨论了补码乘法器的原理,那么什么是Booth
乘法器呢?Booth
乘法器是由英国的Booth
夫妇提出的,并没有什么特殊含义,所以我们直接快进到内容。
经过补码乘法器的推导:
\[[X*Y]_补=X_补*(-y_7*2^7+(y_6*2^6+y_5*2^5+……+y_0*2^0))\]
参考中学数学:
\[2^n=2*2^{n-1}\]
其核心计算思想是括号里的形式,也就是~
综合电路
37
个元件,36
个IO口,318
根线
测试文件
`timescale 1ns / 1ps
module mul_tb(
);
reg [7:0] mul1,mul2;
wire [15:0] res;
reg clk;
wire clk_en;
reg [2:0] clk_cnt;
initial begin
mul1 <= -8'd7;
mul2 <= -8'd3;
clk <= 0;
clk_cnt <= 3'b0;
end
always # 10 clk = ~clk;
//clk_cnt发生器,懒人版
always @(posedge clk) begin
clk_cnt <= clk_cnt + 1'b1;
if (clk_cnt == 3'b100)
clk_cnt <= 3'b00;
end
//每次运算结束后,让乘数变化,以便产生不同的数据用以观察
assign clk_en = (clk_cnt == 3'b100) ? 1'b1 : 1'b0;
always @ (posedge clk_en) begin
mul2 <= mul2 + 1'b1;
end
mul_booth_signed try(.mul1(mul1),.mul2(mul2),.res(res),.clk(clk),.clk_cnt(clk_cnt));
endmodule
仿真波形
将其改成有符号十进制数形式显示,可以验证电路设计正确。