Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

乘法器

复习

  • ALU 能完成多位二进制加法
  • 寄存器能保存被乘数、乘数和中间结果
  • 状态机能按时钟推动一轮轮操作

TL;DR

  • 二进制乘法就是“检查乘数的每一位,再决定是否累加”
  • 左移一位相当于乘 2
  • 一个加法器配合移位与重复控制,就能完成乘法

正文

  要算 3 × 5,最笨的办法是把 3 加五次。这个办法能算,但 5 如果变成五百万,我们大概会先失去耐心。

  二进制给了我们一条近路。先把两个数写出来:

3 = 0011
5 = 0101

  0101 表示 1 + 4,所以 3 × 5 也可以写成:

3 × (1 + 4) = 3 + (3 × 4)

  在二进制里,乘 2 只需左移一位,乘 4 就左移两位:

0000 0011        3
0000 1100       12
---------
0000 1111       15

  这和十进制竖式乘法其实是一回事,只是二进制的每一位只有 0 和 1:遇到 0 就什么也不加,遇到 1 才把当前的被乘数加进结果。

让加法器反复工作

  我们可以准备三个位置:

  • 被乘数:开始放 3,每轮左移一位
  • 乘数:开始放 5,每轮右移一位
  • 结果:开始为 0,用来保存已经累加的部分

  每一轮只做三件事:

  1. 看乘数最右边是不是 1
  2. 如果是 1,就把被乘数加进结果
  3. 被乘数左移、乘数右移,继续下一轮

  对 3 × 5 来说:

轮次乘数最低位要不要加结果
开始--0000
1100110011
20不加0011
3111001111

  三轮以后,结果就是 15。

为什么结果要更宽

  两个 4 位无符号数最大都是 15,而 15 × 15 = 225,需要 8 位才能装下。所以 n 位乘 n 位,通常要为完整乘积准备 2n 位。

补充:愿意多花电路,就能少等几拍

  上面的做法复用一个加法器,电路省,却要逐位检查乘数。追求速度的乘法器会让多个部分积同时相加,或者用 Booth 编码减少连续多个 1 带来的重复累加。它们没有改变乘法的结果,只是在用更多电路换更少时间。

  极简机器保留最朴素的移位加法已经够用。以后再遇到硬件优化,也可以先问一句:它是在减少步骤,还是让更多步骤同时进行?

  现在,“三个位置”可以各由寄存器承担,ALU 负责加法,简单的移位线路负责移动各位,状态机则依次发出“检查、累加、移位、继续”的控制信号。时钟每走一拍,乘法器就前进一步,直到所有乘数位都检查完毕。

  这一次,我们不是先描述算法、以后再补零件,而是已经拥有了组成它的全部部件。下一章,用同样的寄存器、ALU 和状态机完成除法。

思考题

  用“检查最低位、按需累加、左右移位”的方法,计算 0010 × 0110。哪些轮次真的发生了加法?

小结

知识点

  • 二进制竖式乘法
  • 左移一位相当于乘 2
  • 移位加法乘法器
  • n 位乘法的完整结果最多需要 2n 位

思考题答案(仅供参考)

  0110 从右向左的位是 0、1、1、0,所以第 2、3 轮发生加法:0100 + 1000 = 1100,也就是 12。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪