剖析全加器的一次尝试

全加器是计算机进行计算的基本单元,是构成电子计算机核心微处理器中算术逻辑单元的基础。

全加器的结构如下。

全加器示意图

其中,AB是计算所需要的两个数,C_{in}表示输入进位,C_{out}表示输出进位,S表示求和结果。

全加器的硬件剖析

全加器本质上是一个数学概念。在实际生产时,可以使用不同的方式制造。在现代工艺中,主要使用晶体管进行制造。

后文将会详述,全加器实际上只是逻辑门的组合,所以实际上任何可以构成逻辑门的原件(哪怕是非电子元件)也可以通过组装构建成一个全加器。

二进制,布尔代数和电路

虽然这几个概念都是独立发明的,但是最后他们组合在一起,形成了我们所认识的逻辑门。

二进制

0代表十进制中的0,1代表十进制中的1,10代表十进制中的2,11代表十进制中的3,以此类推。

实际上,我们需要注意到的是,在任意的进制中,例如在8进制中,10代表8,十进制中,10表示10,在16进制中,10代表16。

这一点很有趣,10永远表示的是代表该进制的数。
这不是偶然,因为当我们用于表示该改进所有可用的数都用完了之后,我们想表示下一个数的时候,只能通过进位的方式表示,而进位的结果就是下一位置为1,而原来的位置位0。

布尔代数

布尔的贡献在于将原本属于哲学范畴,或者说是语言表达范畴的逻辑推论数学化,使得我们可以简单的使用数学语言来描述逻辑推论的命题。

运算 符号
交集(与) A \cap B
并集(或) A \cup B
\neg A
运算律 符号
结合律 A \cup (B \cup C) = (A \cup B) \cup C
A \cap(B \cap C) = (A \cap B) \cap C
交换律 A \cup B = B \cup A
A \cap B = B \cap A
分配律 A \cup (B \cap C) = (A \cup B) \cap (A \cup C)
A \cap (B \cup C) = (A \cap B) \cup (A \cap C)
互补律 A \cup \neg A = 1
A \cap \neg A = 0

有了这样的数学表达,逻辑运算就变成了可以通过数学进行推导的运算。
同时,更重要的,让计算机实现逻辑运算成为可能。

电路

香农在他著名的硕士论文《继电器与开关电路的符号分析》中详述了如何通过电路实现逻辑运算,这给计算机的实现提供了有力的理论基础。

事实上,全加器就是一系列逻辑运算的总和。

继电器

继电器示意图

继电器与电报机。

电报机在按下一个开关后,实际上是接通了电路,
我们可以想象,
电报机A和继电器相连,
电报机按下按键后,继电器的开关闭合,
电磁线圈通电后带动弹簧片位移,
与继电器相连的另一个电路被接通,
这个另一个电路实际上连接着电报机B(接收方),
这样电报机B就接收到了电报机A发送的消息。

继电器与逻辑电路

上文描述的继电器其实不属于一种逻辑电路,
但是如果,
继电器开关闭合,与继电器相连的电路断开,那么我们就实现了一个简单的非门电路。

如果让两个继电器串联,那么就实现了一个与门电路。
反之,如果两个继电器并联,就实现了一个或门电路。

继电器与现代计算机

继电器属于物理设备,受物理学的限制,机械运动相对效率较低因此由继电器构成的计算机运行缓慢。
其中比较有名的是马克一号计算机,1944年诞生,由3000多个继电器组成。

值得一提的是,马克一号虽然是继电器计算机,运行速度缓慢,但其使用了二进制,同时可编程,所以实际上算是真正意义上的计算机。

继电器之后出现了真空管,只有又出现了晶体管,集成电路,于是计算器的运算速度一步步加快。

晶体管的发明者,诺贝尔奖获得者肖克利在发明了晶体管后,召集了一群精英一同研制并销售晶体管。后来他手下的八个人,史称八叛徒组建了赫赫有名的仙童公司。后来仙童公司日落西山,曾经仙童公司的当家,诺伊斯和摩尔(提出摩尔定律的那个男人)成立了另一家公司,就是英特尔。

全加器的“软件”部分

全加器这个名字,看起来好像是要做数学加法。可实际上内部做的都是逻辑运算。
这也就是为什么只要我们有继电器,我们就可以自己动手做一个全加器的原因,
乃至我们可以做一台计算机的原因。
因为计算机实际上就是逻辑计算的总和。

半加器

全加器实际上是半加器的组合,所以要了解全加器,首先我们需要知道什么是半加器。

首先来看A和B两个1bit数字,相加时的效果。

A B sum
0 0 0
1 0 1
0 1 1
1 1 10

当A和B同时为1时,计算结果溢出了。
因为我们的全加器只支持1bit的计算,所以无法保存10这个2bit的数据。

那么显然,我们需要两个输出来保证我们不会丢失信息。

A B sum carry
0 0 0 0
1 0 1 0
0 1 1 0
1 1 0 1

我们把A和B相加的结果,分别存放在sum输出和carry输出中,
其中,sum表示A和B相加之后原始位的结果,carry表示是否产生进位。

Carry

通过观察Carry,我们可以发现,Carry实际上是A和B进行与操作之后的结果。

A \cap B = Carry

Sum

对于sum来说,我们现有的非,与,或操作都无法满足,所以我们需要对逻辑门进行组合。

第一次尝试:
与非门
通过将与门和非门串联,我们可以实现如下的表格。

A B A NAND B
0 0 1
1 0 1
0 1 1
1 1 0

\neg (A \cap B) = \text{NAND}

我们希望实现,当A或者B其中有一个为1时,结果为1,否则结果为0。

通过观察或门与非门的结果我们发现,
他们在A和B为1时输出的结果相同(都为1),而当A和B为其他值时输出的结果相异。
那么,什么门可以保证我们在两个输入当且仅当其都为1时,输出1呢,那就是与门

A B A NAND B A \cup B (A NAND B) \cap (A \cup B)
0 0 1 0 0
1 0 1 1 1
0 1 1 1 1
1 1 0 1 0

对于最右侧一列,我们就通过逻辑计算求出了sum。
同时,这样的逻辑门的组合我们也给它一个名字,异或XOR

到此为止,我们通过将A和B输入与门得到了进位,通过将A和B输入异或门,得到了当前位的sum值。

异或门的内部逻辑
半加器图示

全加器

在半加器中,我们输出了进位,很明显,在实际计算中,当我们计算A和B的加法时,进位也可能成为输入。
所以在二进制的1bit计算中,我们应该有三个输入:A,B,进位。

让我们画一个完整的表格。

A B cin sum cout
0 0 0 0 0
1 0 0 1 0
0 1 0 1 0
1 1 0 0 1
0 0 1 1 0
1 0 1 0 1
0 1 1 0 1
1 1 1 1 1

Sum

先将A和B放入半加器试试。

sum(A,B)表示A和B放入半加器后的sum输出。
c(A,B)表示A和B放入半加器后的carry输出。

A B sum(A,B) c(A, B) cin sum cout
0 0 0 0 0 0 0
1 0 1 0 0 1 0
0 1 1 0 0 1 0
1 1 0 1 0 0 1
0 0 0 0 1 1 0
1 0 1 0 1 0 1
0 1 1 0 1 0 1
1 1 0 1 1 1 1

把多余的部分去除。

sum(A,B) cin sum
0 0 0
1 0 1
0 1 1
1 1 0

神奇的事情发生了,
原来全加器的sum输出,就是sum(A,B)和cin作为输入,再进行一次半加器的输出。

sum(sum(A, B), cin) = sum

用符号表示。XOR(\oplus

(\text{A} \oplus \text{B}) \oplus \text{cin} = \text{sum}

Carry

那同理,cin和A,B半加器的进位输出,我们用c(sum(A,B), cin)表示。

A B cin c(A,B) c(sum(A,B), cin) cout
0 0 0 0 0 0
0 1 0 0 0 0
1 0 0 0 0 0
1 1 0 1 0 1
0 0 1 0 0 0
1 0 1 0 1 1
0 1 1 0 1 1
1 1 1 1 0 1

如果我们只关注后三列的话,

c(A,B) c(sum(A,B), cin) cout
0 0 0
0 0 0
0 0 0
1 0 1
0 0 0
0 1 1
0 1 1
1 0 1
c(A,B) c(sum(A,B), cin) cout
0 0 0
1 0 1
0 1 1

我们发现,其实

\text{c(A,B)} \cup \text{c(sum(A,B), cin)} =\text{cout}

用逻辑运算表示的话,
(\text{A} \cap \text{B}) \cup ((\text{A} \oplus \text{B}) \cap \text{cin}) = \text{cout}

全加器的结构

实现多bit运算

当我们实现了一个全加器后,我们就实现了1bit运算。

自然而然的,我们将多个全加器级联后,就构成了多比特加法器。

多个全加器级联

例如上图,我们构建了一个6bit的加法器。
例如我们输入A(001010)和B(100101),X表示进位。

这里如果我们在首次计算时,X置为0表示加法计算,置为1表示减法计算。

从A和B的低位开始依次计算。
A_0B_0的sum结果作为S_0输出,进位输出作为下一个全加器的输入,以此类推。

最后我们得到加法结果为S_5S_4S_3S_2S_1S_0,如果C不为0,则表示计算结果溢出。

Appendix

资料

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容