Bootstrap

计算机组成原理(九):乘法器

乘法器原理

乘法器的工作原理可以用二进制乘法来说明。二进制乘法和十进制乘法类似,通过部分积的累加得到结果。

部分积的生成

在二进制乘法中,每一位的乘积是两个二进制数位的 与运算(0 × 0 = 0,1 × 0 = 0,0 × 1 = 0,1 × 1 = 1)。例如:

  A = 1101  (13 in decimal)
× B = 1011  (11 in decimal)
--------------
      1101   (部分积1,对应 B 的最低位)
+    0000    (部分积2,B 的次低位为 0)
+   1101     (部分积3,B 的次高位为 1)
+  1101      (部分积4,B 的最高位为 1)
--------------
  10011111   (143 in decimal)

累加器的使用

乘法器通过生成部分积,并使用一个累加器不断相加最终得到结果。

乘法器的分类

串行乘法器

  • 特点
    • 使用移位寄存器和一个累加器。
    • 部分积逐位生成并累加。
  • 优点
    • 硬件简单,占用资源少。
  • 缺点
    • 速度慢,每次操作需要多个时钟周期。
  • 算法
    • 从最低有效位到最高有效位逐位处理乘数。
    • 每处理一位,若该位为1,则累加乘数。
    • 移位操作用来对应权重增加。
+-----------------+
|  被乘数寄存器  | --> 左移
+-----------------+
       ^
       |       +----------------+
       +------>+ 累加器寄存器   |  (累加部分积)
       +------>+----------------+
       ^
       |       +----------------+
       +------>+ 乘数寄存器     | --> 右移
               +----------------+

并行乘法器

  • 特点
    • 同时生成所有部分积并进行累加。
  • 优点
    • 速度快,只需少量时钟周期。
  • 缺点
    • 硬件复杂,资源占用高。
  • 实现方式
    • 使用逻辑门实现。
    • 可使用加法器树(如Wallace树)优化部分积的累加过程,减少延迟。
乘数位  --> 部分积生成器 --> 加法器树 --> 最终结果
被乘数位

Booth 乘法器

  • 特点:
    • 针对有符号数优化,减少部分积的数量。
    • 通过对乘数进行编码(Booth 编码)减少操作次数。
  • 优点:
    • 适合处理有符号乘法。
    • 可以有效减少硬件复杂度。
  • 算法核心:
    • 检测乘数的相邻位变化,避免逐位处理部分积。

阵列乘法器

  • 特点:
    • 使用一个阵列结构,将乘法分解成多个加法和移位操作。
  • 优点:
    • 可并行计算,提高运算速度。
    • 适合在硬件中实现。
  • 缺点:
    • 硬件资源消耗较多。
被乘数
 × 乘数
--------------
  部分积阵列 --> 加法阵列 --> 最终结果

乘法器的实现步骤

部分积生成

  • 通过对每位乘数和乘数位的与运算生成部分积。

部分积对齐

  • 通过移位操作,使部分积对应权重正确对齐。

部分积累加

  • 串行乘法器使用一个累加器逐步累加部分积。
  • 并行乘法器使用多个加法器或加法器树快速完成部分积累加。

乘法器在硬件中的实现

逻辑门实现

  • 使用基本的逻辑门(如与门、或门、异或门)实现部分积的生成。
  • 加法器用于部分积的累加。

FPGA 或 ASIC 实现

  • 在 FPGA 中,可以通过硬件描述语言(如 Verilog 或 VHDL)实现乘法器。
  • 硬件平台中,现代编译器通常会将乘法优化为内置乘法器单元。

浮点数乘法器

  • 对于浮点数,需要处理尾数的乘法、指数的加法,并对结果进行规格化。

示例(c++模拟乘法器)

#include <iostream>

int multiply(int multiplicand, int multiplier) {
    int result = 0;
    while (multiplier != 0) {
        if (multiplier & 1) { // 如果当前位为1
            result += multiplicand;
        }
        multiplicand <<= 1;   // 左移乘数
        multiplier >>= 1;    // 右移乘数
    }
    return result;
}

int main() {
    int a = 13, b = 11;
    std::cout << "Result: " << multiply(a, b) << std::endl; // 输出 143
    return 0;
}
;