八位“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根线

八位“Booth二位乘算法”乘法器-LMLPHP

测试文件

`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

仿真波形

八位“Booth二位乘算法”乘法器-LMLPHP

将其改成有符号十进制数形式显示,可以验证电路设计正确。

11-14 02:45