[Verilog语言入门教程] 乘法器(顺序 Booth & 并行 Wallace) 原理与实现

乘法器可以分为以下几种类型:

顺序乘法器Sequential Multiplier):顺序乘法器是最简单的乘法器类型,采用逐位相乘的方法实现。这种乘法器适用于小规模的乘法运算,但速度较慢。
(1) Booth编码乘法器

并行乘法器Parallel Multiplier):
并行乘法器是采用并行计算的方法实现乘法运算,可以同时计算多个位的乘积。这种乘法器速度较快,适用于大规模的乘法运算。

(1) Wallace树乘法器(Wallace Tree Multiplier):

(2) Wallace树带预编码的乘法器**(Wallace Tree with Pre-Encoding Multiplier

1 运算符 * 实现乘法器

运算符*表示乘法操作。实际上,乘法器的具体实现取决于所使用的FPGAASIC技术。不同的FPGAASIC可能使用不同的乘法器结构,以实现乘法操作。常见的乘法器结构包括布斯乘法器、士脑乘法器和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: RegWire 赋值区别
reg型变量必须在过程块内通过过程赋值语句赋值,而不能使用assign语句进行赋值。过程赋值语句可以是非阻塞赋值语句(<=)或阻塞赋值语句(=),用于在时序逻辑中更新reg型变量的值。

相反,wire型数据不能放在过程块内赋值。wire型数据通常用于组合逻辑,其值由组合逻辑电路决定,而不是时钟驱动的。在组合逻辑中,可以使用assign语句对wire型数据进行赋值。

1 顺序乘法器

顺序乘法器(也叫串行乘法器)通过逐位相乘和累加的方式计算乘法结果。它需将被乘数和乘数进行二进制展开,然后逐位进行相乘和累加运算。最经典的例子是经典的Booth乘法器。
在这里插入图片描述

1.1 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编码乘法器,含verilog 代码|

设计思路
使用 Booth 算法实现乘法的模块。该模块具有以下输入和输出:
这是一个使用 Booth 算法实现乘法的模块。该模块具有以下输入和输出:

输入:

  • clk:时钟信号
  • rst_n:复位信号,低电平有效
  • start:启动信号,用于触发乘法运算的开始
  • mul_A:被乘数,8 位无符号数
  • mul_B:乘数,8 位无符号数

输出:

  • done:乘法运算完成信号
  • Product:乘法结果,16 位无符号数

内部信号:

  • state:状态寄存器,用于控制乘法过程的状态转移
  • mult_Amul_A 的补零扩展结果,用于 Booth 算法中的加法操作
  • mult_Bmul_B 的补零扩展结果,用于 Booth 算法中的移位操作
  • inv_Amult_A 的补码结果,用于 Booth 算法中的加法操作
  • result_tmp:乘法结果的暂存器,用于 Booth 算法中的加法操作

具体实现思路如下:

  1. 通过 rst_n 信号将所有寄存器和输出信号重置为初始值。
  2. start 信号为高电平时,进入状态机。
  3. 在状态 0 中,将 mul_A 进行补零扩展得到 mult_A,并计算出 inv_A
  4. 在状态 1 中,根据 booth_code 的值选择加法操作的项,并进行加法操作。
  5. 每次加法操作后,将 mult_Ainv_A 进行移位操作,将 mult_B 进行右移操作。
  6. 判断是否需要跳转到下一个状态,如果需要,则跳转到状态 2,完成乘法运算。
  7. 在状态 2 中,将乘法结果赋值给输出信号,并将 done 置为高电平。
  8. 在状态 3 中,将 done 置为低电平,将状态机重置为状态 0,等待下一次启动。

这个模块使用 Booth 算法实现乘法,通过有符号数的运算规则减少乘法的位数。具体的 Booth 算法实现在状态 1 中,根据 booth_code 的值选择加法操作的项,以此减少加法的次数。这是一个使用 Booth 算法实现乘法的模块。该模块具有以下输入和输出:

输入:

  • clk:时钟信号
  • rst_n:复位信号,低电平有效
  • start:启动信号,用于触发乘法运算的开始
  • mul_A:被乘数,8 位无符号数
  • mul_B:乘数,8 位无符号数

输出:

  • done:乘法运算完成信号
  • Product:乘法结果,16 位无符号数

内部信号:

  • state:状态寄存器,用于控制乘法过程的状态转移
  • mult_Amul_A 的补零扩展结果,用于 Booth 算法中的加法操作
  • mult_Bmul_B 的补零扩展结果,用于 Booth 算法中的移位操作
  • inv_Amult_A 的补码结果,用于 Booth 算法中的加法操作
  • result_tmp:乘法结果的暂存器,用于 Booth 算法中的加法操作

具体实现思路如下:

  1. 通过 rst_n 信号将所有寄存器和输出信号重置为初始值。
  2. start 信号为高电平时,进入状态机。
  3. 在状态 0 中,将 mul_A 进行补零扩展得到 mult_A,并计算出 inv_A
  4. 在状态 1 中,根据 booth_code 的值选择加法操作的项,并进行加法操作。
  5. 每次加法操作后,将 mult_Ainv_A 进行移位操作,将
  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Verilog是一种硬件描述语言(HDL),用于设计和描述数字电路和系统。下面是一个简单的Verilog语言入门教程的概述: 1. Verilog简介:了解Verilog的背景和用途,以及它在数字电路设计中的作用。 2. 模块和端口:学习如何定义Verilog模块,并定义内部信号和外部端口。 3. 数据类型和变量:了解Verilog中的数据类型(包括位、整数和实数)以及如何声明和使用变量。 4. 运算符和表达式:熟悉Verilog中的运算符和表达式,包括算术、逻辑和位运算符。 5. 控制结构:学习如何使用条件语句(如if-else和case语句)和循环语句(如for和while循环)来控制Verilog代码的执行。 6. 组合逻辑:了解如何使用逻辑门和逻辑运算符来实现组合逻辑电路。 7. 时序逻辑:学习如何使用时钟信号、触发器和寄存器来实现时序逻辑电路。 8. 模块实例化:了解如何在Verilog代码中实例化其他模块,并将它们连接起来。 9. 仿真和测试:学习如何使用Verilog模拟器来测试和验证设计。 10. 高级主题:进一步学习Verilog的高级特性,如多层次层次化设计、参数化模块和系统任务。 这只是一个简要的概述,你可以通过阅读Verilog语言的教程和参考资料来深入学习。一些常用的Verilog教程和资源包括CSDN、EDAboard和ASIC World等网站上的教程、书籍和在线课程。希望这些信息对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值