ALU是算术逻辑单元,是CPU中重要的一部分,因为CPU本质上就是不断重复最简单的计算。而我们这一版CPU的ALU部分更为简单,是一个只能做加法的ALU。
理论部分
我们需要一个能帮我们进行数学计算的电路设计。一旦打通了这一关,可以说你已经了解了计算机的全部,因为计算机所做的一切,就只有计算,更绝对一点说,计算的一切,也就只有加法。在这里我做一个大胆的假设,正在阅读这篇文章的你已经知道了二进制的含义,那如何给自己做一个8位二进制数的加法计算器呢?它大概应该是这个样子。
其实这不是一个新知识,我相信给你足够的时间你一定会设计出来,你不妨在此暂停一段时间拿出一张纸试试。我们先从最简单的一位数相加开始,如何设计出一个一位数相加的计算器呢?我们首先应该整理出这样一张清晰的表,它列出了对每一种可能的输入情况所对应的输出结果,即 0+0=00;0+1=01;1+0=01;1+1=10,这种表叫做真值表。这里我们直接将进位也考虑进来。
加数A | 加数B | 加和输出S | 进位输出C1 |
0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
有了真值表之后,我们就可以通过基本的逻辑运算来得到一个逻辑表达式。运算过程如下:
其中,加号(+)表示“或”运算,而输入项之间省略的乘号则表示“与”运算。我们选出所有能使结果为1的输入项组合,再进行取反操作和与运算,再使每项之间通过或运算相连。对此有疑惑的同学可以自己模拟一遍上面的运算过程,大概就能知道为什么要这么做了。
由运算结果我们得知,和就是异或门,进位就是与门。画出来就是下面这个样子,由于我们只考虑了向后进位,而没有考虑前一个数的进位,因此我们称这种装置为半加器。
如果将前一个进位考虑进来,只需再多一个半加器就可以了,至于为什么进位输出的加和没有用半加器而是用了一个或门,请暂停一分钟思考一下。这回我们已经建立好了一个完美的一位计算器,我们便可以自豪地称之为全加器。
全加器的逻辑实现我们同样可以用上面提到的真值表来完成。下面是全加器的真值表。
进位输入C0 | 加数A | 加数B | 进位输出C1 | 加和输出S |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 0 | 1 |
0 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 1 | 0 |
1 | 1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 | 1 |
对应的逻辑表达式如下:
一位计算器做出来之后,8位计算器就只需将全加器逐个拼起来即可,并且再次抽象整体,我们称之为8位加法器。
OK,大功告成。我不知道你此时的感受如何,不知不觉我们连续进行了3次抽象(即把之前的器件封装起来),有没有深刻体会到之前所说的你必须开始习惯这种抽象。每当一个复杂的构造被装进一个黑盒子里时,你便再也不要考虑里面的构造了,只要你做到了这一点,这三步的抽象便会是so easy。有了加法计算器,减法也就不是问题了,在本博客中将略去这部分内容,如果有兴趣,可以去了解一下计算机是如何用补码表示减法的,之后你会发现,减法就是加法。
实操部分
同8位的寄存器一样,插在我们面包板上的ALU,同样直接用一个集成电路实现,74LS283,以下为针脚图:
- A1-A4:加数A
- B1-B4:加数B
- C0:进位输入
- S1-S4:加和输出
- C4:进位输出
将两个拼一起则就是一个8位的加法器,同之前做的寄存器(两个)接在一起,输出到总线端再接一个三态控制,就完成了整个电路。
这个加法器不像之前的寄存器,有控制是否存入数据的信号,它无论如何都直接将加和计算出并从输出端输出。我们开启clk,手动将寄存器A(红色灯泡)和B(蓝色灯泡)设置几个数,就会看到ALU输出加和结果(黄色的灯泡,挤死了。。。)
参考视频:eater.net