例如,三位数 abc
与 xyz
相乘(每一个字母代表相应数位上的数字):
abc * xyz = x * abc * 100 + y * abc * 10 + z * abc * 1
在数字系统中,乘法运算是以二进制的形式进行的,不妨研究一位二进制数相乘的情况:
000 * 000 = 000;
000 * 001 = 000;
001 * 000 = 000;
001 * 001 = 001;
不难看出,一位二进制数相乘,实质上是进行逻辑与运算。
接下来考虑两位二进制数与一位二进制数相乘:
010 * 000 = 000;
010 * 001 = 010;
011 * 000 = 000;
011 * 001 = 011;
也不难看出,以上运算事实上是一位二进制数对两位二进制数按位取逻辑与运算。
接下来再考虑两位二进制数相乘:
010 * 010 = 100 = 10 * 1 * 10 + 10 * 0 * 1 = 100 + 0;
010 * 011 = 110 = 10 * 1 * 10 + 10 * 1 * 1 = 100 + 10;
011 * 010 = 110 = 11 * 1 * 10 + 11 * 0 * 1 = 110 + 0;
011 * 011 = 1001 = 11 * 1 * 10 + 11 * 1 * 1 = 110 + 11;
仔细感受运算过程,我们能够朴素地感知。对二进制数进行相乘操作,本质上可以被归纳为如下流程:
部分积追加位权的细节
因为高一位的乘数乘得的部分积与低一位的乘数乘得的部分积相比,对于二进制来说,前者是后者的两倍,所以对应的高一位的部分积要乘以2,也就是二进制下的“10”(记错“
”)。
对于二进制,一个数乘以“”,就是将这个二进制数左移了一位,并为最后一位补 0(例如: )。
我们可以通过一个Python位运算的例子来理解移位操作。
Python中的二进制乘法可以通过位运算符实现。具体来说,就是使用 &
运算符进行按位与操作,使用 <<
运算符进行左移操作。
例如,将二进制数1010左移两位,即可得到101000,相当于将原数乘以2的2次方。
我们尝试在 Python 中实现一个简单的二进制乘法函数,来理解乘法器的原理:
a
和 b
分别表示要相乘的两个二进制数result
表示最终的乘积b
的最低位是否为1
a
加到 result
中;否则,我们什么也不做。a
左移一位,b
右移一位,进入下一次循环,直到 b == 0
。print
函数来输出中间结果。def binary_multiply(a: int, b: int) -> int:
result: int = 0
while (b > 0):
if (b & 1):
result += a
a <<= 1
b >>= 1
return result
阵列乘法器模拟了上述 Python 程序的二进制乘法运算过程:
图为我们的阵列乘法器的示意图。
A
和 B
。result
,表示 A
和 B
的乘积。在这个 Exercise 里,我们需要用结合之前所学的知识(选择器、加法器、减法器等),搭建一个 ALU。
ALU(Arithmetic & Logic Unit,算术逻辑单元)是计算机中进行所有数字计算和逻辑操作的核心部件。它根据选择信号执行不同的操作,包括算术运算、位逻辑运算和移位运算等。
在本题中,我们需要设计一个 共11 位输入的 ALU:
输入端:
A
:一个 4 位数(A[3:0]
)B
:一个 4 位数(B[3:0]
)ALU_sel
:一个 3 位数,用于选择 8 种不同的操作(ALU_sel[2:0]
)。输出端:
result
:一个 4 位数,根据选择信号的不同,ALU 执行以下 8 种操作:通过设计这个 ALU,你将能够实现多种算术和逻辑操作,从而为计算机系统中的数据处理提供基础支持。
ALU_sel
信号的 3 位二进制数可以选择 8 种不同的操作。
ALU_sel |
操作 | 输出结果 result |
---|---|---|
000 | 加法 | result = A + B |
001 | 减法 | result = A - B |
010 | 乘法(低四位) | result = (A * B)[3:0] |
011 | 乘法(高四位) | result = (A * B)[7:4] |
100 | 比较(A > B) | result = (A > B) ? 1 : 0 |
101 | 左移(A) | result = A << 1 |
110 | 右移(A) | result = A >> 1 |
111 | 按位与 | result = A & B |
ALU_sel = 000
时,ALU 执行加法运算,result = A + B
。ALU_sel = 001
时,ALU 执行减法运算,result = A - B
。ALU_sel = 010
时,ALU 输出乘法结果的低四位,即 (A * B)[3:0]
;当 ALU_sel = 011
时,ALU 输出乘法结果的高四位,即 (A * B)[7:4]
。ALU_sel = 100
时,ALU 比较 A 和 B 的大小。如果 A 大于 B,输出 1,否则输出 0。
unsigned
,而默认的操作是补码比较,其英文为 complement
。ALU_sel = 101
时,ALU 对 A
执行左移操作,result = A << 1
。ALU_sel = 110
时,ALU 对 A
执行右移操作,result = A >> 1
。ALU_sel = 111
时,ALU 执行按位与操作,result = A & B
。以下是著名的74LS181计算逻辑单元:
ALU_sel
。result
,它是根据选择信号 ALU_sel
所指定的运算结果。