【Logisim 本地搭建】手动版无符号 8 位乘法器的详细教程

【Logisim 本地搭建】手动版无符号 8 位乘法器的详细教程

1. 引言

在数字逻辑与计算机组成原理的学习中,乘法器是一个核心组件,它展示了如何利用基本的逻辑门来实现复杂的算术运算。本教程将带领你在 Logisim 中构建一个手动版的无符号 8 位乘法器,通过清晰的步骤和原理讲解,让你掌握其设计与验证方法。

本教程将使用Logisim Evolution 3.9.0Logisim 2.7.1两个版本进行演示。

*注:如果出现连线正确不知道什么原因报错保存重新打开即可。

2. 原理

核心原理(原码一位乘法):

  • 无符号二进制乘法的原理与十进制乘法类似,都是基于移位相加。对于一个8 位被乘数和一个8 位乘数,其乘积最多为 16 位
  • 本教程实现的乘法器采用“原码一位乘法”算法,该算法将被乘数和乘数视为无符号整数
  • 由于二进制只有“0”和“1”,所以我们可以把乘法理解为加法,将被乘数或是将“00000000”加到部分积上。
  • 逐位(从低到高)检查乘数每一位,如果乘数的这一位是“1”,则加上被乘数,否则加上“00000000”,然后用同样的方法继续判断乘数的下一位
  • 每次使用的那个乘数位,用完后可以直接丢弃
  • 每次加法结果的最后一位(即下图蓝色数字),在后续步骤不再参与运算,所以我们可以提前存起来,这样下一步就只用算8 位加法(本教材的方法只使用 8 位加法器)。
  • 例子如下图,我们计算183 × 166 = 30378,最终结果为 16 位(0111011010101010=30378),绿色为高 8 位(01110110),蓝色为低 8 位(10101010)。

核心算法(移位相加法):

  1. 初始化:用三个寄存器分别存储乘数 A(最后会寄存积的低 8 位)被乘数 B部分积 P(最后会寄存积的高 8 位)。其中P 初始为 0B在整个计算过程中保持不变P 、A每轮循环后右移一位

  2. 检查乘数最低位:观察A 寄存器最低位(即最右边一位)是1 还是 0

  3. 条件选择加法:如果 A 的最低位为 1,则执行P = P + B;如果为 0,则P = P + 0(即不变)。

  4. 整体右移:将 P 和 A 拼接成一个 16 位的整体,然后整体向右移动一位

    • P 的最低位移出后,补入 A 的最高位(这样 A 同时寄存未使用的乘数位部分积的低位,节省寄存器)。

    • A 的最低位(即刚才已经检查过的那一位)被直接丢弃

  5. 循环控制:重复步骤 2~4,共循环 8 次。

  6. 输出结果:8 次循环结束后,P 中存储的是乘积的高 8 位,A 中存储的是乘积的低 8 位。分别输出,即得到 16 位最终结果。

3. 准备工作

在开始搭建之前,请确保你已经准备好以下子电路:

  1. 8 位寄存器:【Logisim 本地搭建】带时钟信号的简单 8 位寄存器的详细教程
  2. 8 位三态门:【Logisim 本地搭建】三态门的详细教程
  3. 8 位加法器:【Logisim 本地搭建】半加器、全加器与 8 位加法器的详细教程

4. 搭建步骤

  1. 新建电路:新建一个电路,命名为“Multiplier_8”
  2. 初始化寄存器:从上到下放置 3 个8 位寄存器,分别命名为“P”(用于保存部分积)、“A”(用于保存乘数)、“B”(用于保存被乘数)
    1. Logisim Evolution:
    2. Logisim:
  3. 布置 P 寄存器
    • 放置 1 个多路复用器/数据选择器(为了控制 P 的初始化),设置选择位为 1数据位为 8。
    • “输入0”端连接 8 位常量“0”。
    • “输入1”端暂时置空。
    • 其“输出”端通过分线器/分离器连接P 寄存器的输入“D7~D0”
    • “选择”端连接一个输入引脚“Load_P_Reg”。
    • 放置 1 个输入引脚“Clock_P_Reg”连接P 寄存器输入“Clock”。
    • Logisim Evolution:
    • Logisim:
  4. 布置 A 寄存器:
    • 放置 1 个多路复用器/数据选择器(为了控制 A 的初始化),设置选择位为 1数据位为 8。
    • “输入0”端通过分线器/分离器连接 8 个输入引脚“A_Reg7~A_Reg0”
    • “输入1”端暂时置空。
    • 其“输出”端通过分线器/分离器连接A 寄存器的输入“D7~D0”
    • “选择”端连接一个输入引脚“Load_A_Reg”。
    • 放置 1 个输入引脚“Clock_A_Reg”,连接 A 寄存器的输入“Clock”。(Logisim版A 寄存器的“Clock”“输入引脚”连接后续会报错,必须换成“按钮”,其他寄存器的“Clock”可以根据自己的习惯使用“按钮”或“输入引脚”
    • Logisim Evolution:
    • Logisim:
  5. 布置 B 寄存器:
    • 放置 8 个输入引脚,分别命名为“B_Reg7~B_Reg0”,连接B 寄存器的输入“D7~D0”。
    • 放置 1 个输入引脚“Clock_B_Reg”,连接 B 寄存器的输入“Clock”。
    • Logisim Evolution:
    • Logisim:
  6. 构建条件选择逻辑:
    • B 存储器右边放置8 个与门,各个与门的一个输入端分别连接B 寄存器的输出“Q7~Q0”,另一个输入端连接A 寄存器的输出“Q0”
    • Logisim Evolution:
    • Logisim:
  7. 构建寄存部分积逻辑:
    • P 寄存器右边放置一个8 位寄存器,命名为“P_Buffer”,用于缓冲数据
    • P_Buffer 寄存器输入“D7~D0”连接P 寄存器输出“Q7~Q0”
    • 放置 1 个输入引脚“Clock_PB_Reg”连接P_Buffer 寄存器输入“Clock”。
    • P 寄存器P_Buffer 寄存器中间的导线称为“线路1”,部分积将寄存到这段导线中,切断了组合逻辑反馈环路,为加法器提供稳定的输入
    • Logisim Evolution:
    • Logisim:
  8. 构建加法逻辑:
    • 放置一个8 位加法器
    • P_Buffer 寄存器输出“Q7~Q0”连接到加法器输入“A7~A0”
    • 8 个与门的输出端连接到加法器输入“B7~B0”
    • 加法器的进位输入“Cin”可以置空(Logisim版不能置空,可以接一个常量“0”或接地)。
    • 加法器输出“Cout~S0”连接 1 个9 位分线器/分离器(高位在上低位在下)。
    • 为了方便观察数据,可以在加法器分线器中间加上 9 个LED 灯
    • Logisim Evolution:
    • Logisim:
  9. 构建移位逻辑:
    • P 寄存器左边放置 1 个9 位分线器①和 1 个8 位分线器②
    • A 寄存器右边放置 1 个8 位分线器③
    • 9 位分线器①输入端连接加法器分线器输出。
    • “8~1”位输出端连接8 位分线器“7~0”位输入
    • “0”位输出端连接8 位分线器③的“7”位输入。
    • 8 位分线器②输出连接P 寄存器多路复用器“输入1”端。
    • 8 位分线器③“6~0”位输入连接A 寄存器输出“Q7~Q1”
    • 输出端连接A 寄存器多路复用器“输入1”端。
    • Logisim Evolution:
    • Logisim:
  10. 构建输出逻辑:
    • 放置 2 个8 位三态门,分别命名为“High”“Low”
    • High 8 位三态门输入端“A7~A0”连接P_Buffer 寄存器输出“Q7~Q0”输入端“EN”连接 1 个输入引脚“EN_H”。
    • Low 8 位三态门输入端“A7~A0”连接A 寄存器输出“Q7~Q0”输入端“EN”连接 1 个输入引脚“EN_​​​​​L”
    • 两个8 位三态门输出端同时连接8 个输出引脚“Q7~Q0”
    • Logisim Evolution:
    • Logisim:

5. 成果验证

我们可以尝试计算183 × 166 = 30378,步骤如下:

  1. 输入乘数和被乘数:
    1. 在乘数寄存器 A 的键盘中输入“166”(A_Reg7~A_Reg0=10100110
    2. 在被乘数寄存器 B 的键盘中输入“183”(B_Reg7~B_Reg0=10110111
  2. 初始化 A 寄存器:
    1. 打开乘数寄存器 A ,给它一个上升沿,寄存初始数据(Clock_A_Reg=1
    2. 关闭乘数寄存器 A(Clock_A_Reg=0)
    3. 如果你使用按钮,把以上两步变为:点击一下按钮
    4. 给乘数寄存器 A 上锁,代表我们已存入初始值(Load_A_Reg=1
  3. 初始化 B 寄存器:
    1. 打开被乘数寄存器 B,给它一个上升沿,寄存初始数据(Clock_B_Reg=1
    2. 此时,乘数最后一位和被乘数相与的结果已自动送入加法器
    3. 关闭被乘数寄存器 B(Clock_B_Reg=0)
  4. 初始化 P 寄存器:
    1. 打开部分积寄存器 P ,给它一个上升沿,把常数 0 寄存到线路 1 (Clock_P_Reg=1
    2. 关闭部分积寄存器 P(Clock_P_Reg=0)
    3. 给部分积寄存器 P 上锁,代表我们已存入初始值(Load_P_Reg=1
  5. 把部分积送入加法器:
    1. 打开缓冲寄存器 P_Buffer ,给它一个上升沿,把部分积送入加法器(Clock_PB_Reg=1
    2. 关闭缓冲寄存器 P_Buffer(Clock_PB_Reg=0)
  6. 第一次加法结果:此时加法器已算出结果, LED 灯显示“0 00000000”
  7. 第一次循环寄存:
    1. 打开部分积寄存器 P ,给它一个上升沿,将加法结果寄存到线路 1(Clock_P_Reg=1
    2. 关闭部分积寄存器 P(Clock_P_Reg=0)
    3. 打开乘数寄存器 A ,给它一个上升沿,整体右移一位,并寄存加法结果的最低位(Clock_A_Reg=1
    4. 此时,乘数最后一位和被乘数相与的结果已自动送入加法器
    5. 关闭乘数寄存器 A(Clock_A_Reg=0)
    6. 打开缓冲寄存器 P_Buffer ,给它一个上升沿,把部分积送入加法器(Clock_PB_Reg=1
    7. 关闭缓冲寄存器 P_Buffer(Clock_PB_Reg=0)
  8. 第二次加法结果:此时 LED 灯显示“0 10110111”
  9. 第二次循环寄存:步骤同第一次循环寄存
  10. 第三次加法结果:此时 LED 灯显示“1 00010010”
  11. 第三次循环寄存:步骤同上
  12. 第四次加法结果:此时 LED 灯显示“0 10001001”
  13. 第四次循环寄存:步骤同上
  14. 第五次加法结果:此时 LED 灯显示“0 01000100”
  15. 第五次循环寄存:步骤同上
  16. 第六次加法结果:此时 LED 灯显示“0 11011001”
  17. 第六次循环寄存:步骤同上
  18. 第七次加法结果:此时 LED 灯显示“0 01101100”
  19. 第七次循环寄存:步骤同上
  20. 第八次加法结果:此时 LED 灯显示“0 11101101”
  21. 第八次循环寄存:步骤同上
  22. 输出高位乘法结果:
    1. 打开高位三态门 High,输出结果,此时输出为“01110110”(EN_H=1
    2. 关闭高位三态门HighEN_H=0
  23. 输出低位乘法结果:
    1. 打开低位三态门 Low,输出结果,此时输出为“10101010”(EN_L=1
    2. 关闭低位三态门LowEN_L=0

6. 总结

通过本教程,你成功在 Logisim 中构建了一个手动版的无符号 8 位乘法器。这个过程让你掌握了二进制乘法的硬件实现原理,并熟悉了 Logisim 中寄存器、加法器、多路选择器等基本元件的使用。

你可以在此基础上进行扩展,例如实现有符号乘法(Booth算法)、增加流水线、或将其封装为一个子电路(Subcircuit)供更大系统调用。