最近一直在读 《计算机系统要素:从零开始构造现代计算机》,昨天晚上把前两章读完了,做完了一个简单的 ALU(算数逻辑单元)。这本书感觉还不错,讲的通俗易懂,当然只是我读完前两章的感觉。
写这篇文章的目的是,在写这个 ALU 的时候感觉之前的部分逻辑门有点忘记了,并且基础的逻辑门比较重要,所以做个笔记整理一下前两章出现的所有的基础的逻辑门。
基础的逻辑门
1. Nand 门: 首先是所有的逻辑门的基础,
Nand 门这个图很清楚了,这个门的内部实现跟它的名字一样,先 And 所有 a 与 b,再将结果取反。之后所有的门构建都从而且仅从这个逻辑门开始
2. Not 门:这个门我不就放图了,取反而已
实现思路:Nand(a,a) = ~(And(a,a)) = ~a,把 Not 门的输入同时输入 Nand 门就行了
3. And 门:与门
实现思路:And = Not (Nand), 这样应该都能懂,Not 门前面已经实现了,直接用就行了
4. Or 门:或门
实现思路:~a = Not(a), ~b = Not(b), Or(a,b) = Nand(~a, ~b)
5. Xor 门:异或门
实现思路:Xor(a, b) = And( Nand(a, b), And(a, b) )
6. Mux 门:Multiplexor,数据选择器或者多路复用器
Mux 门可以看到有三个输入,两个数据位和选择位,由选择位来选择输出是哪个数据位。计算机么所有的数都是二进制的,可以看出如果有个 n 个输入位,则应该 log2n 个选择位
实现思路: Mux = And(~sel, a) or And(sel, b)
7. DMux 门:Demultiplexor,分路器或者解多用器,我也不知道该怎么翻译
DMux 门这个逻辑门跟上面的那个门是一个相对的过程。两个输入,一个数据位和一个选择位。
实现思路:a = And(~sel, in) b = And(sel, b)
上述的都是处理一位的门,现在的计算机都是 32 或者 64 位,所以逻辑的门肯定也要能处理多位的。但是一位的会处理了,多位的本质还是一样的。书上是以16位为例子
8. Not16 门:输入是 16 位的 Not 门
Chip name: Not16
Inputs: in[16]
outputs; out[16]
Function: For i=0..15 out[i] = Not(in[i])
实现思路:用我们上面实现的 Not 门,手动的把 把每一位取反,没有循环,要手动写16次
9. And16 门
Chip name: And16
Inputs: a[16], b[16]
outputs; out[16]
Function: For i=0..15 out[i] = And(a[i], b[i])
实现思路:用 And 门把每一位 and 一下,挺麻烦的
10. Or16 门
Chip name: Or16
Inputs: a[16], b[16]
outputs; out[16]
Function: For i=.0.15 out[i] = Or(a[i], b[i])
实现思路:这个也是同样道理
11. Mux16 门
实现思路:跟 Mux 是一样的
12. Or8Way 门
这个逻辑门当时没注意,导致在实现 ALU 的时候遇到了一点麻烦
Chip name: Or8Way
Inputs: in[8]
outputs; out[8]
Function: out = Or(in[0], in[1],...in[7])
8 位的输入经过 Or 门 输出一位。
13. Mux4Way16 门
Mux4way16 门这里的 4 Way 指有多少输入,不包括选择位。16代表每个输入的位数
实现思路:a 和 b, c 和 d 之间的选择是由 sel[0] 决定的,sel[1]决定了 选择 ab 集合还是 cd 集合。所以就是个多次利用 Mux16 做选择的过程
14. Mux8Way16 门
这个跟 Mux4Way16 门是同样的道理,只是输入位和选择位增加了
15. DMux4Way 门
DMux4Way 门了解过了 DMux 门与 Mux 门,这个应该不难理解,只是输入输出和选择位的变化。
实现思路:sel[1] 决定了 in 在 ab 输出位还是 cd 输出位,sel[0]在分别确定 a b c d 的值。多次调用 DMux16.
15. DMux8Way 门
这个跟 DMux4Way 门是一样的,只是输出变成8个了,选择位增加一个。
有了这些门就可以具体去做些东西了。因为要利用这些逻辑门做些算数运算,这里涉及到有符号的数表示方法,补码,二进制加法等等。这些知识本篇文章不做介绍,自己去看书或者搜一下。
加法器
加法器有四种,HalfAdder, Full-Adder, Add16, Incrementer。
(1)HalfAdder: 一位的与一位相加
HalfAdder实现思路:这就是一个异或门阿,Xor,carry 位其实就是 And 的结果
(2)Full-Adder: 三个一位的相加
Full-Adder加法需要记录进位,这个就是为有进为的加法做准备
实现思路:调用两次 Half-Adder
(3) Add16:两个16位的输入相加
Add16实现过了 Half-Adder 与 Full-Adder 这个就很简单了
实现思路:先一次 Half-Adder,剩下的就是重复调用 Full-Adder
(4)Inc16: 16位的输入,然后执行 + 1,这种操作蛮多的到后面,所以为了方便弄了个自增器,这个是16位的
实现思路:用下 Add16 只是一个输入是b[0]=1,b[1..15]=0。
最后就是实现一个简单的 ALU 了
ALU(算数逻辑单元)
ALU有上面那些逻辑门,加法器,这个大家自己解决吧。
PS:
所有都是以 Nand 门为基础的,你也可以以其他门为基础,一直扩展(我还没这么做,等看完这本书在说)。每个逻辑门的实现都有不同的方法,最优的方法就是所用的逻辑门越少越好。
这门课所有的资料,包括工具阿,书本阿,测试脚本阿都在
The Elements of Computing Systems / Nisan & Schocken
你可以自己去了解详细资料。
我自己写的 Code,我放在了 github 上:
GitHub - xxx50236/The-Elements-of-Computing-Systems: Just Some note
如果某个逻辑门你有更好的方案,欢迎提 PR
网友评论