赞
踩
乘法器可以分为以下几种类型:
顺序乘法器(Sequential Multiplier
):顺序乘法器是最简单的乘法器类型,采用逐位相乘的方法实现。这种乘法器适用于小规模的乘法运算,但速度较慢。
(1) Booth
编码乘法器
并行乘法器(Parallel Multiplier
):
并行乘法器是采用并行计算的方法实现乘法运算,可以同时计算多个位的乘积。这种乘法器速度较快,适用于大规模的乘法运算。
(1) Wallace
树乘法器(Wallace Tree Multiplier
):
(2) Wallace
树带预编码的乘法器**(Wallace Tree with Pre-Encoding Multiplier
)
运算符*表示乘法操作。实际上,乘法器的具体实现取决于所使用的FPGA
或ASIC
技术。不同的FPGA
或ASIC
可能使用不同的乘法器结构,以实现乘法操作。常见的乘法器结构包括布斯乘法器、士脑乘法器和Wallace树乘法器等。具体使用哪种乘法器结构取决于设计的要求和可用的资源。
在通常情况下,我们可能会定义无符号数来表示数据。然而,如果我们接收到的数据实际上是有符号数,而且在计算时默认按照无符号数进行计算(将读取到的8位二进制数视为原码进行计算),那么我们需要对符号位进行扩展来进行乘法计算。我们需要注意在这种情况下对符号位进行扩展来正确计算乘法。
设计
module signed_fixed_point_multiplier #( parameter DATA_WIDTH = 32 ) ( input signed [DATA_WIDTH-1:0] operand_a, input signed [DATA_WIDTH-1:0] operand_b, input wire clk, output signed [2*DATA_WIDTH-1:0] result ); //做符号位扩展,再相乘 assign result = { { 32{ operand_a[31]}},operand_a} * { { 32{ operand_b[31]}},operand_b}; endmodule
测试
module signed_fixed_point_multiplier_tb; reg signed [31:0] operand_a; reg signed [31:0] operand_b; reg clk; wire signed [63:0] result; signed_fixed_point_multiplier #(.DATA_WIDTH(32)) uut ( .operand_a(operand_a), .operand_b(operand_b), .clk(clk), .result(result) ); // 时钟生成 initial begin clk = 0; operand_a = 5; operand_b = 3; #10; operand_a = -7; operand_b = -2; #10; operand_a = 10; operand_b = -4; #10; // 可以继续添加更多的测试用例 $finish; end initial begin $dumpfile("wave.vcd"); // 指定用作dumpfile的文件 $dumpvars; // dump all vars end endmodule
仿真结果
仿真结果符合预期。
Tips
: Reg
与 Wire
赋值区别?
reg
型变量必须在过程块内通过过程赋值语句赋值,而不能使用assign
语句进行赋值。过程赋值语句可以是非阻塞赋值语句(<=
)或阻塞赋值语句(=
),用于在时序逻辑中更新reg型变量的值。
相反,wire
型数据不能放在过程块内赋值。wire
型数据通常用于组合逻辑,其值由组合逻辑电路决定,而不是时钟驱动的。在组合逻辑中,可以使用assign
语句对wire
型数据进行赋值。
顺序乘法器(也叫串行乘法器)通过逐位相乘和累加的方式计算乘法结果。它需将被乘数和乘数进行二进制展开,然后逐位进行相乘和累加运算。最经典的例子是经典的Booth
乘法器。
Booth
编码乘法器参考文献[2]
(Booth Encoder Multiplier
):Booth
编码乘法器是将乘法运算转化为加法运算的一种技术,通过对乘数进行编码,可以减少乘法器的硬件复杂度。
其中,HA
表示半加器,FA
表示全加器,虚线表示进位链
上图红色和紫色线表示最长路径,代表了组合逻辑深度, 在此基础上可进一步优化。乘法运算由2
部分组成:生成部分积、通过加法树对数据压缩。
部分积生成
Radix-2
编码
Radix-2
编码可以消除2bit
连续的“1
”,但是对于硬件电路来说,加法树的层级并没有得到减少,反而引入了编码电路,由此引出radix-4编码
Radix-4
编码
A*B
可以写为:
我们只需要对A进行取补码或者移位操作,就可完成部分积的计算
相比于Radix-2 Booth
编码,Radix-4 Booth
编码将使得乘法累积的部分和数减少一半,部分积只涉及到移位和补码计算。
设计思路
使用 Booth 算法实现乘法的模块。该模块具有以下输入和输出:
这是一个使用 Booth 算法实现乘法的模块。该模块具有以下输入和输出:
输入:
clk
:时钟信号rst_n
:复位信号,低电平有效start
:启动信号,用于触发乘法运算的开始mul_A
:被乘数,8 位无符号数mul_B
:乘数,8 位无符号数输出:
done
:乘法运算完成信号Product
:乘法结果,16 位无符号数内部信号:
state
:状态寄存器,用于控制乘法过程的状态转移mult_A
:mul_A
的补零扩展结果,用于 Booth 算法中的加法操作mult_B
:mul_B
的补零扩展结果,用于 Booth 算法中的移位操作inv_A
:mult_A
的补码结果,用于 Booth 算法中的加法操作result_tmp
:乘法结果的暂存器,用于 Booth 算法中的加法操作具体实现思路如下:
rst_n
信号将所有寄存器和输出信号重置为初始值。start
信号为高电平时,进入状态机。mul_A
进行补零扩展得到 mult_A
,并计算出 inv_A
。booth_code
的值选择加法操作的项,并进行加法操作。mult_A
和 inv_A
进行移位操作,将 mult_B
进行右移操作。done
置为高电平。done
置为低电平,将状态机重置为状态 0,等待下一次启动。这个模块使用 Booth 算法实现乘法,通过有符号数的运算规则减少乘法的位数。具体的 Booth 算法实现在状态 1 中,根据 booth_code
的值选择加法操作的项,以此减少加法的次数。这是一个使用 Booth 算法实现乘法的模块。该模块具有以下输入和输出:
输入:
clk
:时钟信号rst_n
:复位信号,低电平有效start
:启动信号,用于触发乘法运算的开始mul_A
:被乘数,8 位无符号数mul_B
:乘数,8 位无符号数输出:
done
:乘法运算完成信号Product
:乘法结果,16 位无符号数内部信号:
state
:状态寄存器,用于控制乘法过程的状态转移mult_A
:mul_A
的补零扩展结果,用于 Booth 算法中的加法操作mult_B
:mul_B
的补零扩展结果,用于 Booth 算法中的移位操作inv_A
:mult_A
的补码结果,用于 Booth 算法中的加法操作result_tmp
:乘法结果的暂存器,用于 Booth 算法中的加法操作具体实现思路如下:
rst_n
信号将所有寄存器和输出信号重置为初始值。start
信号为高电平时,进入状态机。mul_A
进行补零扩展得到 mult_A
,并计算出 inv_A
。booth_code
的值选择加法操作的项,并进行加法操作。mult_A
和 inv_A
进行移位操作,将
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。