当前位置: 华文问答 > 科学

人类制造的最不可思议的机器有哪些?

2014-12-06科学

//2015.1.20 更新多路选择器,锁存器,你们都以为我要太监了吧!我会更完的!

我决定占个坑准备写我人生中第一个长答案。

我心目中最不可思议的机器大概是 计算机 。这里计算机的概念包括所有涉及 数字电路 的东西,自从我上了数字逻辑设计之后我就对这一类的东西感到无比敬畏。这一类东西的终极体现,就是现在的家用计算机,手机,单片机,超级计算机等等的具有编程能力的计算设备了。我一直以为这类计算设备是人类历史上工程学的顶峰,处处体现着人类智慧的伟大之处,精巧得无与伦比。

为什么呢?

可能因为我对计算机这个东西了解比较深吧,毕竟大学上过课,所以可能觉得它真是神奇,而对于其他的东西比如火箭和航空发动机,我就没什么了解,啥都不知道自然不理解它的复杂性。

评论区

@阿傩

提到,计算机其实从结构上不复杂,它由很多大的部分组成,每个大的部分里面有很多重复的东西。我其实还蛮同意这个观点的。不过我还是坚持我的看法。在我有限的知识范围内,我觉得计算机最为不可思议的逻辑其实是这样的:

我们不能用一样东西的功能集成度来判断一个东西复不复杂,你肯定不能仅仅因为一辆汽车里面有行车电脑就认为汽车比计算机来得更加精巧对吧。为什么我觉得计算机非常精巧,是因为计算机的每一个小部件,都是为计算机整体服务的,你把内存拆出来,它什么事也干不了;你把8253计时器单独拿出来,它也没什么用,你必须把它加到一个计算机系统里面,它才能发挥作用。计算机的每一个部件,从高级的主板,CPU直到三极管级别,都是为计算机整体服务的。这里当然涉及了很多层的抽象:从三级管到门,从门到全加器和多路选择器这类数字电路器件,从数字电路器件到比如ALU和控制器这样的中型集成器件,再到CPU和内存这样的高级集成器件等等。其中每一层的设计都很精巧,足够让人赞叹。这里每一层的抽象,目的都只有一个:计算机,或者像我上面所说,可编程的数字电路计算设备。当一个工程设计涉及了无数层的集成和抽象,其中每一层都很美妙的时候,最终产品的精妙真的只能用脏话来形容了。这个答案也就是为了展现其中每一层抽象设计的精巧所在。

我会试图用最简单的语言把它讲清楚。

目录

三极管

二元布尔代数和逻辑门

全加器和多路选择器

锁存器和触发器

时序逻辑和自动机理论

模型机和控制器

CPU结构

储存器结构

总线

现代计算机架构


appendix

有关半导体的初步知识和光刻技术

图灵机和可计算性理论初步


那么,我们从 三极管 开始慢慢讲起…

//12月26日更新

这是一个电子管:

这是一个晶体管:

这是一个MOSFET的示意图:

严格来说,MOSFET其实是晶体管的一种。

这三样东西都可以被叫做 三极管(Triode) ,一种电气器件。

这三样东西在历史上都曾经被用作数字电路的基本部分,先是电子管,然后是BJT晶体管,然后是MOSFET,现在常用在集成电路里面的就是MOSFET了,因为它能做的特别小,小到几十纳米(怎么做出来这种很小很小的三极管我后面会介绍一下)。具体它们怎么工作的大家不用知道,涉及半导体物理,这个我也不是很懂,只需要知道它们的功能:能够做成一个电子开关。电子开关就是能用电信号控制电路通断的一个开关。啥意思呢,假设你家里现在装了一盏灯,如果它装了一个电子开关,那么你就需要给这盏灯的开关施加一个电压才能把灯打开。这显得特别蠢,因为为啥我不直接把电压加到灯泡上呢?这是因为:我只需要给这个开关施加一个很小的电压就能让开关打开,而这个电压未必能足够让灯亮起来,这是三级管的放大作用,不过在数字电路里边不会用到;另一个原因是有一类电子开关是反着来的,高电压断路,低电压接通。这两种电子开关就是我们用来做计算机的玩意儿了。

用电子开关去焊一台计算机出来貌似很遥不可及,不过现在我们手头有了电子开关,我们可以做一些简单的东西了:

逻辑门

大家耳熟能详的一句话叫做计算机只认识0和1,这个是什么意思呢。计算机里面的数字电路是基于某一种特殊的 布尔代数 的,布尔代数这个名字听上去有点吊吊的,但是这种特殊的布尔代数其实就是在0和1上的运算,只有0和1,这个概念和二进制有点不一样,二进制是一种计数法,二元布尔代数只有0和1两个东西,没有2啊3的,也没有10,11。计算机使用布尔代数的原因倒是不难想,因为高电平和低电平(电平这个词大家就理解成一个电压标准好了)天然适合表示0和1,你要它表示一个新的数,你得弄个中电平出来,这个东西在电路设计里面就很麻烦了。不如用高低电平来表示,这样直接用电路通断就能很方便的控制了。 布尔代数这玩意牛逼就牛逼在弄出布尔代数的时候可还没有计算机啊,那个时候才1850年,研究这东西没有物理背景的,谁能想到这玩意以后因为计算机大红大紫了呢。很多现在研究的数学问题也没有什么物理背景,千万别去嘲讽数学家们弄这个,没准哪天就用上了。

感谢

@高建

的补充:

"给一点纠正和补充吧,布尔代数不必须只有0和1,详细参考近世代数和/或离散数学的内容。逻辑电路使用的是一个特殊的布尔代数系统。"

实在抱歉,不过不影响理解我后面的内容就暂时不改了,大家知道是错的就好。

布尔代数里面最基本的三个运算是与、或、非,与和或是二元运算,代表着它需要使用两个数来算出一个数,非是一元运算,代表着它只需要一个数就能算答案了我把这三个运算的真值表列在下面:

与:

或:

非:

这三个运算构成了一个布尔运算的完备集(是这个词吗?我离散数学的书不在手边查不到...),意思就是只要用这三个运算的组合,就能完成这世界上所有可能的布尔运算,你怎么定义这个运算都可以。其实使用一点简单的代数知识我们可以证明其实只要非和与,或者非和或,也能做到。

那么,如果我们想要实现一个运算,比如一个三元布尔代数运算,就是有三个数输入,一个数输出的运算,我们只需要用一大堆与或非,然后凑吧凑吧就能把这个运算写出来。这个功能其实就很强大啦,比如,我们想要做一个四位二进制加法,四位数加四位数,输出一个四位数加一个进位,我们只需要五个八元布尔代数运算就行了,每一个运算对应答案上的一位,还有一个对应进位。

为了实现这样强大的功能,我们只需要做出三种对应最基本的三种运算的电子器件,我们再使用这些东西组合一下,就能实现非常复杂的逻辑了对吧?这些对应最基本运算的电子器件,就叫做 逻辑门(Logic Gates)

与门有两个输入端,两个输入端都是高电平的时候输出端也是高电平,否则就是低电平,非门当输入端是高电平的时候输出端是低电平,输入端是低电平的时候输出端是高电平,或门就不用说了。

怎么做呢?

我们最先考虑一个简单的东西,与门。

我们回顾一下最基本的初中物理:串联和并联

恩,这是两个开关串连在一起,最左边接电压源。我们发现只有两个开关都接通的时候,输出端是高电压。非常合适。我们把这两个开关变成上面说的,通电就通的电子开关,分别引出两个输入端,我们就有一个与门了。

但其实这还不够,在输出为低电平的时候,输出端不能像现在一样啥都不接,得接一个低电平,所以这只是一个与门的一半,另外一半是这样的:


0这一端表示接地,这两个电子开关是那种反着来的电子开关,加电压就断,不加电才通。

我们把这两个东西写到一起来。

开关变了个样子,大家不要激动,忽略那些参数,箭头向下指的是PMOS,就是M3和M4,相当于我们说的反着来的电子开关。箭头向上指的那两个(M1和M2)是NMOS,相当于我们说的正着来的电子开关。这两种MOS一起组成的电路就叫 CMOS 电路。我们现在就有了一个与门。

但其实现实中也不是这样做的。因为PMOS和NMOS本身的一些电气特性,这样做出来的与门稳定性很差,现实中我们是这样做的:

把0和1反一下。

这样做出来的输出正好和与门是反过来的,相当于与门后面跟了一个非门,所以它叫 与非门(NAND Gate) ,写成符号的话是这样的:

它很牛逼,原因如下:

这是一个非门:

这是一个与门:

这是一个或门:

根据上面的内容,只要有这三个门就能完成所有的二元布尔运算。也就是说,它一个门就能搞定所有的二元布尔运算。

实际上在操作中我们是直接使用原理相似的或非门和非门去搭电路,而不是用与非门做出来的这种复杂玩意儿,但是这也足够神奇了不是么。

接下来我们就可以尝试做做最简单的计算器了。

全加器(Full Adder)


全加器是用来计算加法的电路,顾名思义。既然有全加器,那么就应该有对应的半加器。半加器是不带进位的加法,如果是一个一位半加器,就只有两位输入,一位输出,如果有进位的话就丢弃掉。全加器表示的是带进位的加法。一位全加器有三个输入端,除了两个加数以外还有一位的进位。对应的,它也有两个输出,一个代表的是这一位的结果,另外一位是进位。多了进位的好处是,如果我们把足够多的全加器串联起来,就能做成一个多位加法器,像是这样:

这是个三位的加法器,A和B表示输入,O表示输出。当然也可以往后面不断接更多的全加器,变成4位5位6位....等等。加法器其实是所有运算电路的基本元件,减法器和加法器基本上是一样的,乘法其实是移位和加法的结合,除法是移位和减法的结合(大家想想运算的时候列竖式是怎么列的?)。

说起来全加器的内部结构也是挺简单的。不过首先我们需要一些分析,这里可能讲得比较晦涩,如果大家不想看的话直接往后跳到下一部分就好了。

全加器一共有两个输出,O和C,分别代表结果和进位。

O在三个输入中有一个为1或者都为1时为1,其余情况为0,相当于在输入中数1的个数,如果是奇数就为1,如果是偶数就为0。很凑巧的是,我们有一个专门的逻辑运算来处理这个问题,叫异或(XOR),它是一个二元运算,如果两个值相同则输出0,两个值不同输出1。写成公式的话就是下面这个样子。

a \oplus b = (\bar{a}\wedge \bar{b})\vee (a\wedge b)

圆圈里一个加号就是XOR,上加横线表示not,\vee 表示或,这个符号上下颠倒表示与。

其实我们也是有专门处理异或运算的门的,用符号表示成这样:

那么输出端O的电路可以这么画:



C在三个输入中有两个以上为1时为1,其余情况为0。

我们可以把它写成这个样子:

C = (A \wedge B) \vee (C_0\wedge (A\vee B))

看上去超级复杂,其实逻辑很好理解,如果A和B都是1,A\wedge B 等于1,,C就等于1,接下来一个部分是来考虑A和B不都等于1的情况的,这个时候只要AB其中之一等于1,C0也等于1,C输出也是1。

我们可以把它也画成电路:

然后把两个部分拼在一起:

(不想画图了,就从课件上截了个图...)

就是全加器啦。可能有人发现了,我们其实重用了一个门的输出,就是O部分电路里面的第一个异或门。这个异或门的输出可以代替C部分电路里面的第一个或门的输出,结果是一样的。

现在,如果大家有心思用开关和小灯泡当输入和输出器件的话,我们已经可以做成一个只能算二进制加法的计算器了。

离计算机还真是遥遥无期啊。

接下来要简单介绍一个很重要的部件,它是计算机实现多种功能选择的基础:

多路选择器(Multiplexer,MUX)

多路选择器,顾名思义,就是能在很多路中间选一个的元件。

最简单的多路选择器是这样的:

什么意思呢,当A为0的时候Z的输出等于I0,当A为1的时候Z的输出等于I1。

当然它也有4:1版本,8:1版本,输入端相应增加就是了,功能不变。下面是一个4路选择器的门级电路图(后面电路说明不想看可以不看),看上去有点乱,其实还蛮简单。拿I0这条线来说,把它和A的非和B的非同时接到一个与门上,这个时候这个与门的输出就只在A和B都为0的时候等于I0,其余时刻永远为0了。其它线路也是一样的,把所有线路或成一个输出,就是多路选择器了。

这个东西有两个重要作用:

首先,比如你想做一个计算器,又能做加法又能做乘法,这个时候就需要MUX出手了。你做一个开关,表示现在正在进行的运算,0的时候表示加法,1的时候表示乘法,然后做一个加法器,做一个乘法器,把输入分别接到加法器和乘法器上,加法器和乘法器的输出接到MUX上,控制开关接MUX的控制端,输出就是你想要的东西了,现代计算机里面最重要的东西是CPU,CPU里面负责算数运算的模块叫 算术逻辑单元(Arithmetic and Logic Unit, ALU) ,可以负责很多种运算,加减乘除,或与非等等,就需要多路选择器的控制。这个东西还可以用在存储器里面,比如我需要提取哪一个地址上的东西,把MUX控制端看成地址输入,输入端看成存储内容输入,输出就是我想要的内容了。

其次,这个元件非常讨懒人工程师们的喜欢。为什么呢?假设我要做一个三元运算,有了MUX以后我再也不用费劲想哪个门应该怎么接了,只要写一下三元运算在所有情况下的输出,然后再MUX的输入上对应接上这些输出,比如000输出0,我就在I0的位置直接接低电平,001输出1,我就在I1上接高电平,直接完事,都不用想的。

到了这里我们已经把组合逻辑部分讲完了,到了这里大家可以做一些比如闰年计算器之类的小玩意,但是离可以实用的家用电器还差得很远很远。

我们上面提到了一个重要的东西叫做存储器,大家仔细想一想,其实如果没有存储能力的话,我们能做的东西非常有限,做个计算器输入还得是用开关一位一位去拨才行,连现在的计算器上面的按键开关都不行,因为它也有最基本的存储功能,在你按下键的时候,按键开关发出了一个很短暂的高电平信号,我们还得把这个很短暂的信号存下来,变成一个稳定的高电平才行。这个时候需要一个很重要的部件出场了: 锁存器(Latch)

从名字上就能看出来锁存器的功能了,把输入锁住,存起来。

锁存器需要干一些什么呢,它作为一个最简单的时序元件,它需要完成下面两个简单的任务:

1.在某一个输入状态之下,可以保存一个信号,或0或1。

2.在某一个输入状态之下,能把其中储存的信号变成自己想要的信号。

想要做一个能把一个电平存住的东西需要大家有点想象力。

先看下面这个电路:

这个电路没有输入,但这个电路用两个非门可以把里面的这个1存到天荒地老,或者停电为止。而且你要是把图上的0和1换一下,也行,这样就变存储0了。这个结构的好处就是,它可以用同一个结构存储0或者1,这是所有存储器件的基本功能。

但是光有它不够,作为一个存储器件,你最起码得有一个能力就是我要你存啥你存啥,这个结构...不行。

那我们改改。

当我们需要一个输入的时候,我们把最左边的开关合上,把Store开关断开,这个时候这个能存储的电路环就不存在了,然后从左边给输入。然后我们把Store一合,Load一断,这个时候就已经存上了。这个模型就可以当做一个存储单元用了。我们只需要把它改成一个门电路的形式就好。为了以后的制造工作省点事,我们在改动过程中需要尽量使用比较少的门电路来完成这个过程。

我们先试试用一个门行不行。

这个电路保持了上面电路的特点,如果你不给他输入,它就能一直把里面的东西保存到天荒地老。如果原来电路中保存的是0,输入为1的时候存储值就会改变成1。但是这个电路虽然能有「把存储的信号变成1的功能」,但是没有一个可以稳定的完成「把存储的信号变成0」的功能。我们需要把这个功能给引入进来。那么我们把电路改成下面这个样子:

这样,如果S保持0,R是1,就可以将保存的内容置成0了。

这个门电路结构叫做 SR锁存器 ,其实在很多书上它还有一个非常炫酷的画法:

Q是输出\bar{Q} 表示和输出的反相,相当于输出加一个非门。

这个锁存器的功能是这样的:当S和R都是0的时候,输出是之前存储的内容。如果S是1R是0,存储的内容变为1,如果S是0R是1,存储内容变为0。如果两个都是1,此时的输出时没有定义的,这个器件要求大家在电路运行的时候不要这样做,否则会被玩坏掉。

这个锁存器是我们接下来许多各式各样的储存元件的基础,比如,门控SR锁存器:

它加入了一个控制端C,相当于之前的控制开关,只有当控制端为1的时候,S和R的改变才会影响到锁存器内部保存的信号,这样可以解决一部分S和R同时为1的情况。

再有D锁存器:

字比较小,我说一下:后面那个大元件是一个门控SR锁存器,三个输入端分别是S,C,R。

它用一个D输入端取代了S和R两个输入端的功能。纯粹靠C来控制写入/储存状态,靠D来输入,在应用上面就更加简单了。

这些锁存器有很多优点:用的门特别少,所以速度飞快,但是相对应的,比如在SR锁存器中就有一个输入组合是不能用的,而且速度再快,每个门对于电信号的处理还是要花时间的,如果输入变化太快,它也是会出现很多不稳定的现象的。怎么解决呢?我们可以通过使用一种叫做 时钟 的信号来控制这些锁存器工作在一个比较稳定的速度下面,还可以同步许多锁存器的共同工作。


施工中。