组合逻辑电路 — 加法器、译码器、复用器与可编程器件
组合逻辑电路 — 加法器、译码器、复用器与可编程器件
这一章讲什么: 组合逻辑(输出只取决于当前输入、没有记忆的电路)的四大件: 加法器(怎么把两个 n 位数加起来、怎么用一个电路兼做减法)、译码器(怎么用一个 编号选中众多目标之一)、复用器(反方向:众多来源里挑一个送出去)、可编程逻辑 器件(把电路的功能做成可烧写的)。所有东西都是第 4 章布尔函数 + 第 5 章门的 直接装配——读完你会相信「计算机的各种操作都是布尔函数」不是口号。
1. 顶层全景:两种能力、四件设备
组合逻辑 = 无记忆:输出 = f(当前输入),和过去无关
│
├─ 会「算」:半加器 → 全加器 → 波动进位加法器 → 加/减一体电路
│
└─ 会「选」:译码器(编号 → 一根线)↔ 复用器(多路 → 一路)
↑ 二者是镜像,中间站着「最小项」这个共同语言
外加一条工业化路线:PLD(PLA / ROM / PAL)= 把电路做成可编程
图说:会算、会选、可烧写——组合逻辑的全部本事就这三样,
CPU 和内存只是它们的大规模重复与组合(第 7~9 章)。这一章是「数学部分 → 硬件部分」的正中点:第 4 章给语言,第 5 章给开关, 本章把开关按语言装配成器件,第 7 章再补上「记忆」,第 8、9 章就能拼出 完整的 CPU 和内存。
分类判据先钉死(6.1 节)1:组合电路的输出仅取决于任意时刻的输入; 时序电路的输出还依赖先前输入形成的状态。 原书用遥控器举例:直接输入频道号 选台是组合关系;按「上/下」键(取决于你正在看的频道)是时序关系。第 7 章 专门讲时序,本章全部电路都是「瞬时的」。
6.1 节还埋了一个硬件黑话,读规格书会用到,当场解释2:
- 高电平有效(active-high):用较高的电压表示 1;
- 低电平有效(active-low):用较低的电压表示 1(信号名常带一根上划线 或后缀 #,如 RESET#);
- 高有效的输出可以接低有效的输入,但中间必须取一次补——规格表里那些小圆圈, 一半是在说这件事。
这一章的方法论也明说在先:「不会完整地描述这些单元,只会讲解几个小部分 及其背后的概念」3——目标是掌握设计套路,不是背电路图。
2. 加法器:从一位到 n 位,再到「加减一体」
2.1 半加器与全加器
- 半加器(half adder):两个 1 位输入 x、y,两个输出:和 Sum = x ⊕ y, 进位 Carry = x ∧ y。缺陷:没考虑低位的进位4;
- 全加器(full adder):三个输入(两个本位 xᵢ、yᵢ 加来自低位的 Carryᵢ), 两个输出。两个函数,第 4 章已经见过一半5:
Sumᵢ = m1 ∨ m2 ∨ m4 ∨ m7 = ∑(1,2,4,7) ← 卡诺图无明显分组,化简不了
Carryᵢ₊₁ = m3 ∨ m5 ∨ m6 ∨ m7 = (x∧y) ∨ (cin∧x) ∨ (cin∧y) ← 第 4 章的最小乘积和把全加器的 8 行真值表(表 6-2)完整走一遍——它是本章所有推导的根基, 也是第 3 章「次末级进位 XOR 最终进位」的现成素材6:
Carryᵢ xi yi | Carryᵢ₊₁ | Sumᵢ | 口算核对(十进制)
------+------+----------+------+-------------------
0 0 0 | 0 | 0 | 0+0 = 0
0 0 1 | 0 | 1 | 0+1 = 1
0 1 0 | 0 | 1 | 1+0 = 1
0 1 1 | 1 | 0 | 1+1 = 2 → 进位 1,本 0
1 0 0 | 0 | 1 | 1+0 = 1
1 0 1 | 1 | 0 | 1+1 = 2 → 进位 1
1 1 0 | 1 | 0 | 同上
1 1 1 | 1 | 1 | 1+1+1 = 3 → 进位 1,本 1
图说:8 行里没有一行出人意料——真值表在这里的作用是「穷举确认设计 = 直觉」,
而不是给出意外;一旦哪一行对不上,错的一定是式设计而不是表。Sum 的卡诺图没有可圈的对——有些函数就是化简不动,这也是诚实的一课: 最小化不是万能药7。直接实现这两个式子得到图 6-3 的全加器:9 个门。
2.2 换个拼法:两个半加器 + 一个或门
能不能更省?把 Sumᵢ 的式子按分配律重排,里面会爬出 XOR8:
Sumᵢ = ¬cin ∧ (x⊕y) ∨ cin ∧ ¬(x⊕y) = cin ⊕ (x ⊕ y)(Carry 侧也照着改写成 Carryᵢ₊₁ = (x∧y) ∨ (cin ∧ (x⊕y))。)两个括号里的
(x⊕y) 和 (x∧y) 正是半加器的两个输出——所以全加器 = 两个半加器 +
一个或门(图 6-5):第一个半加器加 x、y,第二个加 Sum 和 cin,或门合并进位。
原书在这里给了本章第一个工程判断:「简单的电路未必更好。事实上,从逻辑电路的 角度来看,我们没法说图 6-3 和图 6-5 这两种全加器电路哪个更出色」—— 门多的未必输,门少的未必赢,工程设计看实现方式、成本、可用性9。 第 5 章「逻辑等价 ≠ 硬件等价」在这里又应验一次。
2.3 主线例子:4 位波动进位加法走一遍
把 4 个全加器排成一列,进位像接力棒一样从右往左传——波动进位加法 (ripple-carry addition)10。挑具体输入走全程(这个例子是我们为演示编的, 原书给的是通用结构图):
计算 x + y,x = 0111(7),y = 0011(3),c0 = 0(最低位没有进位输入)
位 0: c0=0, x0=1, y0=1 → s0 = 0,c1 = 1 (1+1=10)
位 1: c1=1, x1=1, y1=1 → s1 = 1,c2 = 1 (1+1+1=11)
位 2: c2=1, x2=1, y2=0 → s2 = 0,c3 = 1 (1+0+1=10)
位 3: c3=1, x3=0, y3=0 → s3 = 1,c4 = 0 (0+0+1=01)
结果:s3s2s1s0 = 1010(10),c4 = 0 → 7 + 3 = 10 ✓
图说:每一位的进位输出是左边那一位的第三个输入;
进位从最低位「波动」到最高位,这个延迟就是波动进位加法的代价。这个「代价」值得量化一句:第 i 位必须等第 i−1 位的进位出来才能算完, 所以 n 位加法的延迟 ≈ n × 单个全加器的延迟。32 位加法的等待是 1 位的 32 倍。 原书预告有「预先计算进位」的更快电路(超前进位),但不在本书范围11。 图 6-6 里还标着 CF 和 OF——每次加法,CPU 都在 rflags 寄存器里记账, 第 3 章的标志、第 9 章的寄存器在这里接上了线12。
2.4 减法怎么塞进同一个电路
第 3 章的补码公式在这里兑现为电路:
x − y = x + (y 的补码) = x + (翻转 y 的所有位) + 1电路上只要两件事:每个 yᵢ 先过 XOR 与 func 求补(func=1 时 y 被逐位翻转), 把 c0 从 0 改成 1(补上「+1」)。于是图 6-7 的电路:func = 0 做加法, func = 1 做减法,其他一切照旧13。
func=0: yi ⊕ 0 = yi,c0 = 0 → 普通加法
func=1: yi ⊕ 1 = ¬yi,c0 = 1 → x + ¬y + 1 = x − y(补码世界)
图说:一个开关(func)同时控制了「翻不翻 y」和「要不要 +1」两个动作;
减法没有自己的电路,它只是加法电路的一种用法。用具体数字走一遍减法档(例子是我们为演示编的):4 位补码下算 7 − 3。
x = 0111(7),y = 0011(3),func = 1
第 0 步:逐位求补 + 初始进位
yi ⊕ 1:0 1 1 1 → 1 1 0 0(y 的反码)
c0 = 1(补上 +1)→ 合起来就是 y 的补码 1101(−3 的 4 位补码)
第 1 步:波动进位加法 x + (y 的补码)
位 0: c0=1, x0=1, ¬y0+1 效果=1 → s0 = 1, c1 = 1
位 1: c1=1, x1=1, y1'=0 → s1 = 0, c2 = 1
位 2: c2=1, x2=1, y2'=0 → s2 = 0, c3 = 1
位 3: c3=1, x3=0, y3'=1 → s3 = 0, c4 = 1
结果:s = 0100(4),进位 c4 = 1 被有符号世界丢弃(补码加法的进位「不重要」,
第 3 章磁带计数器的账在这里又记了一次)→ 7 − 3 = 4 ✓
图说:XOR 是可控反相器(func=0 时原样通过,func=1 时逐位翻转),
c0 是「+1」的开关——减法被拆解成加法认识的三种零件。注意两个世界对同一个 c4 的态度:无符号解读里 c4 = 1 是 CF(借位的反面); 有符号解读里它被丢弃。「用哪个标志、丢不丢进位」,依旧是程序的解释—— 第 3 章的 CF/OF 分工表,现在有了电路对应物。
这是全书第一次出现「用控制信号复用同一套硬件」的思想——第 9 章的 ALU、 第 10 章以后的程序流程,全是这一招的放大版。减法是加法的穿着补码外套的亲戚。
3. 译码器:最小项生成器
需求(原书给的场景):x86-64 有 16 个 64 位寄存器,指令里用 4 位选择 用哪个——「必须通过该指令中的 4 位来选择要使用 16 个寄存器中的哪一个」14。
译码器(decoder) 干这件事:n 个二进制输入,最多 2ⁿ 个输出;对每种输入 位模式,恰好一条输出线为 1(线译码器),通常还带一个 Enable 输入 (Enable = 0 时全部输出 0)15。以 3×8 译码器为例(输入 x₂x₁x₀):
Enable=0:不管输入是什么,y7…y0 全 0(器件关断)
Enable=1:x = 000 → y0 = 1;001 → y1 = 1;…;111 → y7 = 1
电路:8 个 4 输入与门,每个与门接 Enable 和三个输入位(各自补或不补),
恰好一「种」组合点亮一「根」线——每个与门就是第 4 章的一个最小项。译码器因此有个更本质的名字:最小项生成器。回顾第 4 章的结论—— 任何逻辑表达式都能表示为最小项的 OR——立刻得到一个通用构造法: 「译码器 + 或门网」能实现任何布尔函数16。原书用它重造了全加器的位片: 3×8 译码器 + 两个 4 输入或门(一个收 m1,m2,m4,m7 出 Sum,一个收 m3,m5,m6,m7 出 Carry),13 个门——比图 6-5 的 5 个门贵得多,但全是「现成货架零件」, 设计成本为零。又一次「门数 vs 工程成本」的权衡。
把表 6-3 的几行走一遍,看清 Enable 与输入的分工17:
Enable x2 x1 x0 | y7 y6 y5 y4 y3 y2 y1 y0
------ --------- -- -- -- -- -- -- -- --
0 任意值 | 0 0 0 0 0 0 0 0 ← 关断:输入无效
1 0 0 0 | 0 0 0 0 0 0 0 1 ← y0 亮:最小项 m0
1 0 0 1 | 0 0 0 0 0 0 1 0 ← y1 亮:m1
1 0 1 0 | 0 0 0 0 0 1 0 0 ← y2 亮:m2
…
1 1 1 1 | 1 0 0 0 0 0 0 0 ← y7 亮:m7
图说:y 的下标 = 输入二进制值 = 最小项编号;Enable 是全军总开关。电路实现(图 6-8)只需要8 个 4 输入与门 + 3 个非门:第 k 个与门接 Enable 和 x₂x₁x₀ 的「k 的二进制展开」所需的各位(补或不补)—— 与门的输入模式本身就是最小项的定义,译码器是「把 ∑ 记号的硬件直译」。 这也让「位片」(bit slice)这个词落了地:全加器电路对每个位 i 都相同, 造 n 位加法器就是把同一片电路复印 n 次,各自接上自己的 xᵢ、yᵢ、cᵢ18。
4. 复用器与三态缓冲器:反向的选择
译码器是「一根编号 → 挑一根线」;复用器(MUX) 是镜像问题: 「n 条选择线,从 2ⁿ 条输入线里挑一条送出去」19。场景:加法器的操作数 可能来自 CPU 内不同位置,得先选好输入。
4 路复用器的输出,就是一个按选择位展开的布尔函数20:
Output = (¬s1 ∧ ¬s0 ∧ w) ∨ (¬s1 ∧ s0 ∧ x) ∨ (s1 ∧ ¬s0 ∧ y) ∨ (s1 ∧ s0 ∧ z)读这个式子有个诀窍:四个乘积项正好是选择位的四个最小项(m0~m3), 每个最小项「守门」一个输入——s1s0 = 01 时,只有第二个乘积项可能为 1, 而它把 x 放进了输出。所以复用器和译码器是同一个最小项家族的两副面孔: 译码器把最小项「摊成」2ⁿ 根线,复用器把 2ⁿ 个输入「收进」最小项选中的一根线。 第 4 章的 ∑ 记号在这里再赢一次:会读最小项,两个器件都是一行式子。
每个输入配一个 3 输入与门,或门收齐——规模一大,n 输入的或门本身就成了 电子技术问题(一个门接几十个输入,电气上很难做好)21。解法是 三态缓冲器(tristate buffer):输出有三种状态——0、1、高 Z (高阻抗,相当于「无连接」)。Enable = 1 时输出 = 输入;Enable = 0 时 它不是输出 0,而是根本断开——对接在它后面的电路没有任何影响22。
真值表:Enable 输入 | 输出
0 0 | 高 Z(断开,不是 0!)
0 1 | 高 Z
1 0 | 0
1 1 | 1
复用器新构造(图 6-13):2×4 译码器 + 4 个三态缓冲器
译码器选中哪一路,哪个缓冲器就把「接通」,其余三路全部「断开」——
输出线上物理上挂着 4 个器件,但任意时刻只有 1 个在驱动它。
图说:「断开」和「输出 0」是两回事:0 也是信号,会压着别的输出;断开是放手。复用器的行为浓缩成一张小表(表 6-6),它就是「选择码 → 被接通输入」的对照23:
s1 s0 | 输出
------+-----
0 0 | w
0 1 | x
1 0 | y
1 1 | z应用场景原书给得很具体:一台有 4 个寄存器 w、x、y、z 和 1 个加法器的计算机, 把每个寄存器的同一位分别接进复用器的 4 个输入(比如第 5 位:w₅、x₅、y₅、z₅), 选择线 s₁s₀ = 10 时,加法器拿到的输入就是 y₅——「哪个寄存器给加法器喂数」 这个决定,被压缩成了两位选择信号24。这正是第 9 章 CPU 内部数据通路 的 preview:寄存器堆 + 复用器群 + ALU,就是图 6-14 放大 64 位的样子。
高 Z 是总线(bus)的物理基础——许多设备共享一组线,轮流「发言」, 靠的就是没轮到的设备全部处于高 Z。第 20 章的 I/O 总线、第 1 章的 「同一物理连接分时传送地址和数据」,背后都是这个器件。
5. 可编程逻辑器件:把「改电路」变成「改程序」
问题(6.5 节开头):固定门电路的设计一变,电路板要重新设计、元件要重新 订购——「有可能价格不菲,而且得花费时间」25。可编程逻辑器件(PLD) 的解法:芯片里预置大量与门和或门(与平面 + 或平面),连线用「熔断器」 (fuse)做成可断的——大电流烧断某根熔丝,就是「编程」掉那条连接; 烧断哪几根,函数就是什么26。
三大类,按「哪个平面可编程」排列,也是按灵活性 ↔ 成本排列:
| 器件 | 与平面 | 或平面 | 灵活性 | 成本 |
|---|---|---|---|---|
| PLA(可编程逻辑阵列) | 可编程 | 可编程 | 最高:任意乘积和 | 最贵 |
| ROM(只读存储器) | 固定(生成全部最小项) | 可编程 | 中:只能「最小项的 OR」,不许化简 | 中 |
| PAL(可编程阵列逻辑) | 可编程 | 固定(每组与门绑死一个或门) | 最低:但允许函数最小化 | 最便宜 |
三条路线的细节27:
- PLA:每个输入变量(补或不补)经熔丝进每个与门 → 可产生任意乘积项; 与门输出再经熔丝进每个或门 → 任意乘积和。「因为与平面可以产生所有可能 的最小项,而或平面能够提供任意最小项之和,所以 PLA 可用于实现任何逻辑函数。」
PLA 的图纸画法值得认识一下(图 6-16),不然第一次看会被「一条线」骗到:
每个与门的输入其实是多条线(x、¬x、y、¬y……各一条),图纸上用一条水平线
打统括;线与线交叉处的点才表示「熔丝没烧断」= 有连接。原书的例子里,
最上面那条水平线有 3 个点,于是那个与门输出 ¬w ∧ y ∧ z;整张图共编程出
三个函数:
F1(w,x,y,z) = (¬w ∧ y ∧ z) ∨ (w ∧ x ∧ ¬z)
F2(w,x,y,z) = ¬w ∧ ¬x ∧ ¬y ∧ ¬z
F3(w,x,y,z) = (¬w ∧ y ∧ z) ∨ (w ∧ x ∧ ¬z) ← F3 与 F1 共享乘积项
图说:F1 和 F3 共用 (¬w∧y∧z) 和 (w∧x∧z) 两个与门——
多输出共享中间项,是 PLA 相对「每函数一电路」白赚的红利。「如果我们想修改函数,只需再编写另一个 PLA,替换掉旧的即可」——改设计 从「重做电路板」降级成「换一颗芯片」,这就是 PLD 全部的商业模式28。
- ROM:与平面固定 = 永远生成全部最小项;把输入当地址,或平面 编程成「每个地址存一个位模式」。原书的例子萌得很:2 位地址的 ROM 存了 4 个 ASCII 字符 A、B、C、D(01000001~01000100)——「计算机指令同样是位模式, 所以我们也可以将整个程序轻松地存入 ROM」29。手表、汽车发动机控制单元、 电器——「我们生活中随处可见的设备都是被 ROM 中的程序所控制的」; 紫外线擦除的 EPROM、出厂烧死的 PROM 是常见的变体。
- PAL:或平面固定——每组与门绑死一个或门,「在与平面中编程的所有乘积项 都将一并执行 OR 运算」。不能挑选最小项,但允许做布尔函数最小化; 「如果所需的功能可以在 PAL 中实现,其成本要比 ROM 或 PLA 低。」
判断(我们的,不是书里的): 这张三器件光谱是「灵活性 ↔ 成本」权衡的 标准教科书案例,但它还有个更深的时间维度:与平面固定的 ROM 是「数据即电路」 ——存字符的 ROM 和存程序的 ROM 没有物理区别,区别只在解释者。 这条「程序 = 位模式 = 可烧进与或阵列」的等价链,正是第 10 章「程序也是数据」 的硬件先声。今天的 FPGA 把这个思想推到极致:不再是烧熔丝,而是 SRAM 单元 控制的可重构连线(补充,不在书里,来自通用知识)。 如果错,会错在: FPGA 与 PLD 的架构差异(查找表 vs 与或阵列)意味着 「等价链」是概念层的而非电路层的;电路层两者已经很不一样。
6. 作者的判断与证据
判断一:「设计往往基于其他因素,例如元件的可用性以及成本等。」 本章三次出现同一态度:全加器的两种设计(9 门 vs 5 门)明说「没法说哪个更出色」; 译码器版全加器 13 门仍然值得给,因为货架现成;PLD 三类的排序标准就是 灵活性与成本。证据是每一处都给了具体数字(9/5/13 个门)。
判断二:诚实标注不做的部分。 超前进位加法「能够显著减少计算时间, 但我们不打算在本书中讨论这些细节」11;PLD「编程技术涉及从指定制造掩模 到廉价的电子编程系统」,点到为止26。这本书的节奏感:给你正确的地图, 不假装地图是全息照片。
判断三:从「造器件」滑向「造工具」。 本章前半造的是功能电路, 后半造的是制造功能的机器(PLD)。这个转折是数字设计史上真实发生过的 产业化路径——先会造加法器,再把「造任意函数」本身做成一种器件。 它还埋着一个对软件读者友好的观察:PLD 的「编程」是物理动作(烧熔丝), 但思维方式已经是软件式的(改连接 = 改配置);从烧熔丝到 SRAM 配置到 HDL 综合,这条线最终把「硬件设计」变成了另一种意义上的「编程」 (补充,不在书里,来自通用知识)。
判断四:选零件的标准反复被点破是「成本与可得性」,而不是「门的数量」。 译码器版全加器(13 门)、半加器拼装版(5 门)、规范式直译版(9 门)三种 设计被并排呈现而没有排出名次——「设计往往基于其他因素,例如元件的可用性 以及成本等」9是本章的隐形结论,也是和第 4、5 章一脉相承的工程观。
判断五:本章是「最小项」这个概念的高光时刻。 译码器(生成最小项)、 复用器(最小项守门)、PLA(最小项 + 任意 OR)、ROM(最小项 = 地址)—— 第 4 章那个抽象的 ∑ 记号,在本章变成了四种能买到的器件。概念一旦有了 货架型号,才算真正学懂了。
7. 边界与局限
- 波动进位的延迟没有量化,只定性说「会有时间延迟」;超前进位只提名不展开11;
- 三态缓冲器没有电路实现,只给了行为真值表和符号(现实里也是专门器件);
- PLD 的编程技术(熔丝/反熔丝/EPROM 紫外擦除)只到名词层,烧写电压、 时序、可靠性一概不涉;
- 没讲比较器电路(动手实践留作练习:两位比较器的等于/大于/小于三输出);
- FPGA/CPLD 这些当代主流可编程器件没有出现(书的时间线停在经典 PLD);
- 动手实践里的七段显示器译码器(BCD → 段模式)是把本章全部工具串起来的 好练习,值得做;
- 「波动进位慢」只给了定性判断。量化它需要门延迟的数字(第 5 章的 RC 充电), 而延迟又随工艺而变;记住结构性的结论即可:n 位加法的延迟 ∝ n, 现代 CPU 用超前进位把延迟压到 ≈ log n(补充,不在书里,来自通用知识)—— 这也解释了为什么第 9 章之后不再为「加法有多快」担心。
- 本章所有电路图都是「逻辑图」不是「晶体管图」。 图里的与门/或门, 落地时会被换成第 5 章的 NAND 实现;图的粒度停在「门」这一层, 是「逻辑设计」和「物理实现」分工的自然边界——左脑画门,右脑数晶体管。
8. 可带走的
全章主线例子,一行走完: 全加器(3 输入位 → 和 + 进位)× 4 个排成一列、 进位接力 → 4 位加法;把 y 先过 XOR(func=1 翻转)再把 c0 置 1(+1), 同一电路 func 切换加减;译码器是「最小项生成器」,加或门实现任意函数; 复用器是它的镜像,三态缓冲器(高 Z)让多路共享一条线成为可能。 四种电路其实是同一套最小项语言的四次翻译:算术翻译(加法器)、 编号翻译(译码器)、通路翻译(复用器)、可烧写翻译(PLD)。
- 组合逻辑 = 输出只看当前输入;有没有「状态」是组合与时序的分界线;
- 半加器不管进位输入,全加器管;全加器可由两个半加器 + 一个或门拼成;
- 有些函数化简不动(Sum = ∑(1,2,4,7) 的卡诺图无分组)——最小化不是万能;
- n 位加法 = n 个全加器 + 波动进位;延迟随位数线性增长;
- 减法 = 加法电路 + 输入逐位求补 + 初始进位置 1(补码的电路兑现);
- 功能信号(func)复用同一套硬件——这是从电路通向 CPU 设计的第一块砖;
- 译码器:n 位输入 → 恰好一根输出线,本质是最小项生成器; 「译码器 + 或门」= 任意布尔函数的通用装配法;
- 复用器:镜像选择;n 输入或门难做时,用译码器 + 三态缓冲器替代;
- 高 Z ≠ 0:断开是「不驱动」,0 是「驱动为低」——总线的物理基础;
- 「位片」思维:设计一次 1 位电路,复印 n 次得 n 位电路——波动进位加法器、 译码器版全加器都这么造;
- PLD 三家:PLA(两平面可编程,最灵活最贵)/ ROM(与平面固定 = 地址译码, 位模式即内容)/ PAL(或平面固定,最便宜);改设计 = 重新编程,不重做电路板; 三家的判据是灵活性 ↔ 成本,不是速度也不是门数;
- 「程序也是位模式」:ROM 存字符和存程序没有物理区别——这是第 10 章 「程序也是数据」的硬件先声;
- 全加器真值表(表 6-2)值得默写:它同时是第 3 章进位链、第 4 章最小项、 本章位片设计三个知识点的公共底座;
- 看到 Enable 输入别跳过它:译码器、三态缓冲器的「全军总开关」, 是所有「选择类」器件的标配脚;
- 「组合逻辑」四个字的意思是法律意义上的:只要电路里出现「输出反馈回输入」 形成记忆,它就不再是本章公民,得去第 7 章报到;
- 译码器和复用器是同一枚硬币的两面——记住一个,另一个按对偶原理免费得到;
- NAND 化时「看着更蠢的中间步骤」(串两个非门)别省——它是把 AND-OR 结构翻译成 NAND-NAND 结构的合法桥梁,删掉这步就只剩经验没有方法。
9. 原文地图
本章地图覆盖第 6 章全文;行号以转码文本(一行 = 一个自然段)为准,
机器可用 book-verify --fix 校正漂移。
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 组合 vs 时序(遥控器例子) | 第6 章 组合逻辑电路 | text/12-ch06.txt:18(搜「遥控器」) |
| 「只讲解几个部分」的定位 | 第6 章 组合逻辑电路 | text/12-ch06.txt:10(搜「不会完整」) |
| 半加器:Sum = XOR、Carry = AND | 第6 章 组合逻辑电路 | text/12-ch06.txt:54(搜「XOR」) |
| 全加器与 Sum 化简不动 | 第6 章 组合逻辑电路 | text/12-ch06.txt:82(搜「Sumi」) · text/12-ch06.txt:87(搜「没有明显的分组」) |
| 9 门全加器 | 第6 章 组合逻辑电路 | text/12-ch06.txt:95(搜「9 个逻辑门」) |
| 两个半加器拼全加器 | 第6 章 组合逻辑电路 | text/12-ch06.txt:127(搜「已经由半加器生成」) |
| 「简单的电路未必更好」 | 第6 章 组合逻辑电路 | text/12-ch06.txt:135(搜「未必更好」) |
| 波动进位加法 | 第6 章 组合逻辑电路 | text/12-ch06.txt:156(搜「波动效应」) |
| CF/OF 接回 rflags | 第6 章 组合逻辑电路 | text/12-ch06.txt:160(搜「rflags」) |
| 减法 = 加补码(func 开关) | 第6 章 组合逻辑电路 | text/12-ch06.txt:162(搜「补码」) · text/12-ch06.txt:168(搜「func」) |
| 超前进位不展开 | 第6 章 组合逻辑电路 | text/12-ch06.txt:172(搜「预先计算」) |
| 寄存器选择场景(x86-64 16 个) | 第6 章 组合逻辑电路 | text/12-ch06.txt:184(搜「16 个 64 位寄存器」) |
| 译码器定义与 Enable | 第6 章 组合逻辑电路 | text/12-ch06.txt:188(搜「线译码器」) · text/12-ch06.txt:192(搜「Enable」) |
| 最小项生成器与「译码器+或门」 | 第6 章 组合逻辑电路 | text/12-ch06.txt:232(搜「最小项生成器」) |
| 译码器版全加器 13 门 vs 5 门 | 第6 章 组合逻辑电路 | text/12-ch06.txt:244(搜「13 个逻辑门」) |
| 复用器定义与布尔式 | 第6 章 组合逻辑电路 | text/12-ch06.txt:284(搜「复用器」) · text/12-ch06.txt:290(搜「Output」) |
| n 输入或门的问题 | 第6 章 组合逻辑电路 | text/12-ch06.txt:321(搜「电子技术方面」) |
| 三态缓冲器与高 Z | 第6 章 组合逻辑电路 | text/12-ch06.txt:299(搜「三态缓冲器」) · text/12-ch06.txt:295(搜「断开」) |
| 译码器+三态的复用器 | 第6 章 组合逻辑电路 | text/12-ch06.txt:323(搜「2 × 4」) |
| 寄存器供数例子(s1s0=10 → y5) | 第6 章 组合逻辑电路 | text/12-ch06.txt:342(搜「y5」) |
| PLD 动机(重做电路板之痛) | 第6 章 组合逻辑电路 | text/12-ch06.txt:101(搜「回到 Sumi 的等式。」) |
| 与平面/或平面、熔断器 | 第6 章 组合逻辑电路 | text/12-ch06.txt:350(搜「与平面」) · text/12-ch06.txt:369(搜「熔断器」) |
| PLA 万能性 | 第6 章 组合逻辑电路 | text/12-ch06.txt:403(搜「任何逻辑函数」) |
| ROM 存 ASCII 字符 | 第6 章 组合逻辑电路 | text/12-ch06.txt:423(搜「ASCII」) · text/12-ch06.txt:431(搜「01000001」) |
| ROM/PROM/EPROM | 第6 章 组合逻辑电路 | text/12-ch06.txt:437(搜「PROM」) |
| PAL 与三器件权衡 | 第6 章 组合逻辑电路 | text/12-ch06.txt:442(搜「永久连接」) · text/12-ch06.txt:448(搜「最灵活」) · text/12-ch06.txt:456(搜「成本」) |
| 表 6-2 全加器 8 行真值表 | 第6 章 组合逻辑电路 | text/12-ch06.txt:67(搜「全加器」) |
| 七段显示器动手实践 | 第6 章 组合逻辑电路 | text/12-ch06.txt:252(搜「七段显示器」) |
| 比较器动手实践 | 第6 章 组合逻辑电路 | text/12-ch06.txt:460(搜「比较器」) |
| 全加器 9 门与 5 门之争 | 第6 章 组合逻辑电路 | text/12-ch06.txt:244(搜「13 个逻辑门」) · text/12-ch06.txt:135(搜「未必更好」) |
| 复用器布尔式与晶体管数 | 第6 章 组合逻辑电路 | text/12-ch06.txt:290(搜「Output」) |
| 高/低电平有效定义 | 第6 章 组合逻辑电路 | text/12-ch06.txt:26(搜「高电平有效」) |
Footnotes
-
出处:「第6 章 组合逻辑电路」第 18 段(
text/12-ch06.txt:18,搜「遥控器」)。原文:「组合型:组合逻辑电路的输出仅取决于在任何时刻给定的输入,而非先前的输入。」「你可以通过在遥控器上输入数字来选择特定频道……因此,输入和输出之间是组合关系。」 ↩ -
出处:「第6 章 组合逻辑电路」第 26 段(
text/12-ch06.txt:26,搜「高电平有效」)。原文:「如果用一个较高的电压来表示 1,那么该信号就叫作高电平有效(active-high)。如果用一个较低的电压来表示 1,那么该信号就叫作低电平有效(active-low)。」 ↩ -
出处:「第6 章 组合逻辑电路」第 10 段(
text/12-ch06.txt:10,搜「不会完整」)。原文:「我们不会完整地描述这些单元,只会讲解几个小部分,并讨论其背后的概念。目标是简要地阐述这些逻辑电路背后的概念。」 ↩ -
出处:「第6 章 组合逻辑电路」第 54 段(
text/12-ch06.txt:54,搜「XOR」)。原文:「和(Sum)是两个输入的 XOR,进位(Carry)是两个输入的 AND。」「但是这里有一个缺陷:半加器只处理两个输入位……没有考虑到次低位可能产生的进位。」 ↩ -
出处:「第6 章 组合逻辑电路」第 82 段(
text/12-ch06.txt:82,搜「Sumi」)。原文给出Sumi(Carryi, xi, yi)的最小项之和与Carryi+1 = (xi ∧ yi) ∨ (Carryi ∧ xi) ∨ (Carryi ∧ yi)(第 89 段,text/12-ch06.txt:89,搜「Carryi+1」)。 ↩ -
出处:「第6 章 组合逻辑电路」第 67 段(
text/12-ch06.txt:67,搜「全加器」)。原书表 6-2 给出 Carryi、xi、yi 的 8 种组合对应的 Carryi+1 与 Sumi。 ↩ -
出处:「第6 章 组合逻辑电路」第 87 段(
text/12-ch06.txt:87,搜「没有明显的分组」)。原文:「图 6-2 中没有明显的分组,所以我们只能用 4 个乘积项来计算前一个等式中的 Sumi。」 ↩ -
出处:「第6 章 组合逻辑电路」第 104 段(
text/12-ch06.txt:104,搜「XOR」)至第 118 段(text/12-ch06.txt:118,搜「Carryi」)。原文演示分配律重排后( ¬xi ∧ yi ) ∨ ( xi ∧ ¬yi ) = xi ∨ yi(异或,即下划线 ∨)及Sumi = ¬Carryi ∧ (xi ∨_ yi) ∨ Carryi ∧ ¬(xi ∨_ yi)。 ↩ -
出处:「第6 章 组合逻辑电路」第 135 段(
text/12-ch06.txt:135,搜「未必更好」)。原文:「简单的电路未必更好。事实上,从逻辑电路的角度来看,我们没法说图 6-3 和图 6-5 这两种全加器电路哪个更出色。良好的工程设计取决于诸多因素,例如每种逻辑门的实现方式、成本及其可用性等。」 ↩ ↩2 -
出处:「第6 章 组合逻辑电路」第 156 段(
text/12-ch06.txt:156,搜「波动效应」)。原文:「整个相加的过程以一种波动效应从最低位流向最高位,这种加法称为“波动进位加法”(ripple-carry addition)。」 ↩ -
出处:「第6 章 组合逻辑电路」第 172 段(
text/12-ch06.txt:172,搜「预先计算」)。原文:「通过更复杂的电路设计,预先计算 CF 的进位和 OF 的值,能够显著减少计算时间,但我们不打算在本书中讨论这些细节。」 ↩ ↩2 ↩3 -
出处:「第6 章 组合逻辑电路」第 160 段(
text/12-ch06.txt:160,搜「rflags」)。原文:「每当 CPU 执行算术运算时(本例中为加法运算),都会在 rflags 寄存器中记录是否发生进位和溢出。」 ↩ -
出处:「第6 章 组合逻辑电路」第 162 段(
text/12-ch06.txt:162,搜「补码」)至第 169 段(text/12-ch06.txt:169,搜「func」)。原文:「如果我们对每个 yi 求补并将初始进位设置为 1 而不是 0,就能使用图 6-5 中的加法器执行减法……当 func = 0 时将两个 4 位数相加,当 func = 1 时将其相减。」 ↩ -
出处:「第6 章 组合逻辑电路」第 184 段(
text/12-ch06.txt:184,搜「16 个 64 位寄存器」)。原文:「x86-64 架构有 16 个 64 位寄存器。如果一条指令使用了某个寄存器,则必须通过该指令中的 4 位来选择要使用 16 个寄存器中的哪一个。」 ↩ -
出处:「第6 章 组合逻辑电路」第 188 段(
text/12-ch06.txt:188,搜「线译码器」)。原文:「译码器有 n 个二进制输入,最多可产生 2n 个二进制输出。最常见的类型是线译码器(line decoder),对于每个输入的位模式,只选择一条输出线设置为 1。」 ↩ -
出处:「第6 章 组合逻辑电路」第 232 段(
text/12-ch06.txt:232,搜「最小项生成器」)。原文:「因此,译码器可以被视为“最小项生成器”。我们从本书先前部分可知,任何逻辑表达式都能够表示为最小项的 OR 运算,因此我们可以通过对译码器的输出进行 OR 运算来实现任何逻辑表达式。」 ↩ -
出处:「第6 章 组合逻辑电路」第 192 段(
text/12-ch06.txt:192,搜「Enable」)。原书表 6-3:「当 Enable = 0 时,所有的输出线均为 0;当 Enable =1 时,输入的 3 位数(x = x2x1x0)用于选择哪个输出线被设置为 1。」 ↩ -
出处:「第6 章 组合逻辑电路」第 240 段(
text/12-ch06.txt:240,搜「位片」)。原文:「其中,x、y、Carry 的下标 i 表示位片(bit slice)」;每个全加器处理被加值的其中一位(第 153 段,text/12-ch06.txt:153,搜「位片」)。 ↩ -
出处:「第6 章 组合逻辑电路」第 284 段(
text/12-ch06.txt:284,搜「复用器」)。原文:「能够做出这种选择的设备称为复用器(MUX)。它可以通过使用 n 条选择线在 2n 条输入线之间切换。」 ↩ -
出处:「第6 章 组合逻辑电路」第 290 段(
text/12-ch06.txt:290,搜「Output」)。原文:Output = ( ¬s0 ∧ ¬s1 ∧ w ) ∨ ( ¬s0 ∧ s1 ∧ x ) ∨ ( s0 ∧ ¬s1 ∧ y ) ∨ ( s0 ∧ s1 ∧ z )。 ↩ -
出处:「第6 章 组合逻辑电路」第 321 段(
text/12-ch06.txt:321,搜「电子技术方面」)。原文:「如果我们尝试扩大规模,对于更大的 n 而言,n 输入的或门会带来一些电子技术方面的问题。」 ↩ -
出处:「第6 章 组合逻辑电路」第 299 段(
text/12-ch06.txt:299,搜「三态缓冲器」)与第 295 段(text/12-ch06.txt:295,搜「断开」)。原文:「“无连接”输出实际上是高阻抗连接,也称为高 Z 或开路」「当 Enable = 0 时,输出基本上是断开的。这与 0 不同;断开意味着它对它所连接的电路元件没有影响。」 ↩ -
出处:「第6 章 组合逻辑电路」第 329 段(
text/12-ch06.txt:329,搜「表 6-6」)。原书表 6-6 给出 4 路复用器行为:s1s0 = 00 → w,01 → x,10 → y,11 → z。 ↩ -
出处:「第6 章 组合逻辑电路」第 337 段(
text/12-ch06.txt:337,搜「寄存器」)与第 342 段(text/12-ch06.txt:342,搜「y5」)。原文:「如果我们将每个寄存器的各位与复用器相连,就可以使用双位选择器(two-bit selector)s1s0 来选择由哪个寄存器为加法器提供输入……如果 s1s0 = 10,那么加法器的输入为 y5。」 ↩ -
出处:「第6 章 组合逻辑电路」第 101 段(
text/12-ch06.txt:101,搜「回到 Sumi 的等式。」)。原文:「这几乎总是意味着布设逻辑门的电路板以及逻辑门之间的连接电路需要重新设计。变更也往往意味着订购各种类型的逻辑门,有可能价格不菲,而且得花费时间。」 ↩ -
出处:「第6 章 组合逻辑电路」第 369 段(
text/12-ch06.txt:369,搜「熔断器」)。原文:「熔断器是一片用来保护电路的薄导体。如果流过其的电流足够大,导体就会熔化,从而断开电路,阻止电流流动。可编程逻辑设备可以通过断开(或烧断)相应的熔断器进行编程,从而省去了逻辑门的输入。」 ↩ ↩2 -
出处:「第6 章 组合逻辑电路」第 448 段(
text/12-ch06.txt:448,搜「最灵活」)至第 456 段(text/12-ch06.txt:456,搜「成本」)。原文:「在这 3 种 PLD 中,PLA 是最灵活的,因为我们可以对或平面和与平面进行编程,但它的价格也是最贵的」「ROM 不允许我们最小化函数,因为所有的乘积项都必须是最小项」「PAL 允许我们做一些布尔函数最小化。如果所需的功能可以在 PAL 中实现,其成本要比 ROM 或 PLA 低。」 ↩ -
出处:「第6 章 组合逻辑电路」第 403 段(
text/12-ch06.txt:403,搜「另一个 PLA」)。原文:「如果我们想修改函数,只需再编写另一个 PLA,替换掉旧的即可。」;F1/F2/F3 的编程结果见第 399 段(text/12-ch06.txt:399,搜「F1」)。 ↩ -
出处:「第6 章 组合逻辑电路」第 423 段(
text/12-ch06.txt:423,搜「ASCII」)与第 425 段(text/12-ch06.txt:425,搜「整个程序」)。原文:「或门平面经过编程的 ROM,其中存储了 4 个字符 A、B、C、D(以 ASCII 码表示)」;「计算机指令同样是位模式,所以我们也可以将整个程序轻松地存入 ROM。」 ↩