从零构造一台计算机——布尔代数到逻辑电路
最近在学习coursera上的一门课:Build a Modern Computer from First Principles: From Nand to Tetris,我会坚持更新这一系列的博客,作为记录自己学习的过程,同时也倒逼自己去把学会的东西再讲出来,来深入理解。
其实我们生活中所有的电子设备都是基于逻辑门电路(后面会解释)来构造的。这是很神奇的一件事情,我在中学的时候就好奇计算机是如何完成这一些复杂的操作的,我相信很多人也都好奇过。这门课的愿景就是带我们从一个最基础的电路开始,构造出一个完整的计算机。
布尔代数
在数学和数理逻辑中,逻辑代数(有时也称开关代数、布尔代数)是代数的一个分支,其变量的值仅为真和假两种真值(通常记作 1 和 0)。逻辑代数是乔治·布尔(George Boole)在他的第一本书《逻辑的数学分析》(1847年)中引入的,并在他的《思想规律的研究》(1854年)中更充分的提出了逻辑代数。
这段话来自维基百科,布尔其实是一个人名,因为布尔代数就是他提出的,所以用他的名字来命名。这里不会深入讲解布尔代数,我们只讲我们用得到的部分。
还是以数学为例,数学中最基础的四则运算是加
,减
,乘
,除
,同样的,布尔代数也有很多计算方式,最基础的是应该是:与
,或
,非
。
在开始讲具体的计算之前,我们需要把前提记住:布尔代数变量的值仅为真和假两种真值(通常记作 1 和 0,真为1,假为0)。
与
因为布尔代数变量的值仅为真和假两种真值,所以我们其实可以把所有的情况都列出来,形成一张表,这张表就是我们平时所说的真值表。
与
的真值表如下:
x | y | x与y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
从上面也可以看出,对于\(n\)个变量的真值表,会有\(2^n\)种情况。
x与y
其实就是当x
和y
都是1的时候,结果为1,也就是x
和y
都是真的时候,结果为真。
你也可以有你自己的理解方式,比如我们一开始学加法的时候,老师告诉我们1+1=2
其实就是一个苹果加一个苹果等于2个苹果。那么x与y
你也可以这么理解:假如你想出去旅游要征询爸爸妈妈的意见,x代表爸爸的意见,x=1代表爸爸同意,y代表妈妈的意见,y=1代表妈妈同意,为0则是不同意。那么与
的意思就是,爸爸与妈妈都同意了,才是通过。
我们平时表述x加y
用符号+
来表示:x+y
;同样的,与
也有它的符号:\(x\)与\(y\) \(\Rightarrow\) \(x \cdot y\)
或
或
的真值表如下:
x | y | x或y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
用上面的例子来说,或
就是爸爸或妈妈同意了,就算是通过了。
同样地,符号表示如下:\(x\)或\(y\) \(\Rightarrow\) \(x + y\)
非
非
和上面的与
,或
有点不一样,真值表如下:
x | 非x |
---|---|
0 | 1 |
1 | 0 |
非
其实就是对x
去相反的值,从字面意思也可以理解。
符号表示如下:非\(x\) \(\Rightarrow\) \(\overline{x}\)
与非
与非
的字面意思是与
运算和非
运算的结合。
与非
的真值表如下:
x | y | x与非y |
---|---|---|
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
与非
就是对与
计算出来的结果,再做非
计算。其符号表示如下:\(x\)与非\(y\) \(\Rightarrow\) \(\overline{x \cdot y}\)
这里把与非
单独拿出来讲,是因为在电路中,我们可以用一个与非
组件,构造出其余所有的组件。这样我们只需要弄懂一个电路图即可。我们这节课的主旨是搞明白,如何从用电路表达布尔逻辑,至于电路的效率等方面,则是硬件工程师们考虑的内容了。其实学习就是这样,我们需要抓住主线,明确目的。如果我们陷入布尔逻辑或者电路图的细节中不可自拔,那就是路走偏了。
逻辑电路
逻辑电路是指完成逻辑运算的电路。这种电路,一般有若干个输入端和一个 或几个输出端,当输入信号之间满足某一特定逻辑关系时,电路就开通,有输 出;否则,电路就关闭,无输出。所以,这种电路又叫逻辑门电路,简称门电路。
这段话来自百度百科,可能比较拗口,我们直接来看实现。
与非门
如图所示,I1
,I2
是输入,NPN
是一个三极管(当I1
或I2
加电的时候,上下两端连通),我们用1表示有电,用0表示没电,那么只有当I1
,I2
都是1的时候,Output
才是0。我们可以用真值表中的例子来验证一下。
为了简化表示,我们用如下的符号来表示与非门:
到这里我们迈出了第一步,我们用一个物理上真实存在的电路图,表示出了一种布尔运算逻辑。那么下面我们就用这个电路图来构造其余的电路图。
非门
非门的实现如下:
也就是我们只需要在电路图上把与非门的2个输入连起来,就可以得到一个非门:这个时候与非门的2个输入永远都是相等的,当2个输入都是1的时候,输出为0,当2个输入都是0的时候,输出为1。
非门的符号如下所示:
与门
类似地,与门的实现如下:
符号表示如下:
或门
或门的实现如下:
符号表示如下:
回顾
这一节我们实现了用电路去表示基础的门电路。迈出了关键的一步,但是一直用画图的方式去表达电路也比较麻烦,下一节我们会简单学习一门硬件描述语言(HDL:hardware description language)来表示电路的实现方式,一步一步去抽象,实现更多的组件。从而构造出一个完整的电脑。
再聊一个题外话:抽象。抽象是软件工程师很重要的一个技能。在这里,我们用或非门
构造出了非门
,与门
,或门
,那么我们可以把构造的过程理解成一个抽象的过程,构造出的门电路可以直接供我们使用,而不必每次去画几个或非门,然后把他们连起来。当然目前的门电路比较简单,我们的感知不是很强烈,如果我们构造了一个由几十个或非门构造出的某门
,那么抽象就显得尤为重要了。其实平时写代码也是如此,我们应该把公用的部分,抽象出一个模块或者一个工具类。