CPU 如何决定把哪个数值送去参与计算?数字电路又如何从多个数据来源中选出一个?
实现这些选择的基础电路之一,就是多路选择器(Multiplexer,简称 MUX)。
多路选择器是一种从多个数据输入中选择一个,并将所选输入值传递到输出端的电路。它通过另一组称为**选择信号(Select Signals)**的输入,决定当前选择哪一路数据。
它的基本任务很简单:多个输入,一路被选中的输出。
本教程将从最基本的二选一多路选择器讲起,逐步介绍选择信号、逻辑门实现,以及多路选择器在处理器中的用途。
1. 数字电路使用二进制值
**数字逻辑(Digital Logic)**描述电路如何处理离散的数值,通常用 0 和 1 表示。硬件利用这些数值表示信息,并完成逻辑判断。
**位(Bit)**是一个二进制数位,只能取 0 或 1。**二进制(Binary)**是一种只使用这两个数字的计数系统。
在电子电路中,0 和 1 通常由不同的电压范围表示。**电压(Voltage)**是两点之间的电势差,数字电路会把规定范围内的电压识别为相应的逻辑值。
**信号(Signal)**是承载信息的物理量。在这里讨论的电路中,信号通过电压表示二进制值。
**输入(Input)**将信号送入电路,**输出(Output)**则将电路的结果传递出去。
多路选择器可以接收多个数据信号,但只有被选中的输入决定输出值。
2. 最简单的多路选择器:两个输入,一个输出
**二选一多路选择器(2-to-1 Multiplexer)**有两个数据输入端和一个数据输出端。此外,它还有一个选择输入端,用来决定选择哪一路数据。
我们把两个数据输入标记为 D0 和 D1,把选择输入标记为 S,把输出标记为 Y。
这些字母只是名称。D0 表示第 0 路数据输入,D1 表示第 1 路数据输入。
选择规则如下:
| 选择输入 S | 输出 Y |
|---|---|
| 0 | D0 的值 |
| 1 | D1 的值 |
当 S 为 0 时,Y 跟随 D0;当 S 为 1 时,Y 跟随 D1。
可以把它想象成一个铁路道岔:两条进入的轨道通向一条离开的轨道,道岔的位置决定接通哪条路线。
多路选择器完成的是类似的电子选择过程,不需要移动的机械开关。
3. 选择信号决定数据来源,而不是数据值
理解数据与选择之间的区别非常重要。
**数据信号(Data Signal)**承载我们要使用的信息。**控制信号(Control Signal)**决定电路如何处理这些信息。
多路选择器的选择输入就是一种控制信号。
假设 D0 的值是 1,D1 的值是 0。
当 S 为 0 时,多路选择器选择 D0,所以 Y 为 1;当 S 为 1 时,它选择 D1,所以 Y 为 0。
注意,将 S 设置为 1,并不意味着“让输出变成 1”,而是意味着“选择 D1”。
如果 D1 的值是 0,那么输出就是 0。
同样,如果两个数据输入都是 1,那么无论选择哪一路,输出都是 1。
选择信号决定使用哪个来源,被选中的来源决定输出什么数值。
4. 多路选择器选择数据,但不存储数据
多路选择器是一种组合逻辑电路(Combinational Circuit)。这类电路的输出由当前输入决定,但电路需要一定的响应时间。
基本的多路选择器不会记住之前选中的值。
如果 S 一直为 0,而 D0 发生变化,那么 Y 也会跟随变化。在理想逻辑模型中,未被选中的 D1 即使发生变化,也不会影响输出。
**存储元件(Storage Element)**是能够保留数值的电路。如果需要保存多路选择器选中的数据,就必须使用另外的存储元件。
基本的多路选择器也不需要**时钟信号(Clock Signal)**来完成选择。时钟信号是一种周期性变化的定时信号,用于协调许多数字系统中的状态更新。
与多路选择器连接的寄存器可能使用时钟,但多路选择器本身会直接响应数据输入和选择输入的变化。
5. 用逻辑门构建多路选择器
**逻辑门(Logic Gate)**是对二进制输入执行基本逻辑运算的小型电路。
我们可以使用三种逻辑门构建二选一多路选择器:非门、与门和或门。
**非门(NOT Gate)**也称反相器,它将输入值反转。输入为 0 时输出为 1,输入为 1 时输出为 0。
**与门(AND Gate)**只有在所有输入都为 1 时才输出 1。只要有一个输入为 0,输出就是 0。
**或门(OR Gate)**只要有一个输入为 1,就输出 1。只有所有输入都为 0 时,输出才为 0。
构建多路选择器时,首先使用非门产生 S 的相反值,也就是 NOT S。
第一个与门接收 D0 和 NOT S,第二个与门接收 D1 和 S。
最后,使用一个或门合并两个与门的输出。
这种结构让被选中分支的数据值传递到 Y,同时使未被选中的分支输出 0。
这只是实现多路选择器的一种方式。实际芯片也可以使用其他电路结构,完成相同的选择功能。
6. 理解逻辑表达式
**布尔表达式(Boolean Expression)**用于描述取值为 0 或 1 的逻辑运算。它来自布尔代数,也就是分析逻辑关系的一套数学方法。
二选一多路选择器的逻辑表达式为:
Y = (D0 AND NOT S) OR (D1 AND S)
其中,NOT 表示“非”,AND 表示“与”,OR 表示“或”,括号用于将相关运算组合在一起。
我们分别看看 S 的两种取值。
当 S 为 0 时,NOT S 为 1。
第一个分支变成 D0 AND 1,结果等于 D0。第二个分支变成 D1 AND 0,结果为 0。
最后,对 D0 和 0 进行或运算,输出就是 D0。
当 S 为 1 时,NOT S 为 0。
第一个分支变成 D0 AND 0,结果为 0。第二个分支变成 D1 AND 1,结果等于 D1。
最后,对 0 和 D1 进行或运算,输出就是 D1。
这个表达式完整地描述了选择规则:一个分支传递数据值,另一个分支输出 0。
7. 从四个输入中进行选择
**四选一多路选择器(4-to-1 Multiplexer)**可以从四个数据输入中选择一个。
我们把这些输入标记为 D0、D1、D2 和 D3。
一个选择位只有两种取值,无法区分四个输入,因此需要两个选择位。我们把它们称为 S1 和 S0。
两个选择位一共可以形成四种组合:
| 选择位 S1 S0 | 输出 Y |
|---|---|
| 00 | D0 的值 |
| 01 | D1 的值 |
| 10 | D2 的值 |
| 11 | D3 的值 |
这里,S1 是左边的位,S0 是右边的位。
一般来说,n 个选择位最多可以标识 2ⁿ 个输入。2ⁿ 表示 2 的 n 次方,也就是 n 个 2 相乘。
三个选择位可以形成八种组合,因此能够控制八选一多路选择器。四个选择位可以形成十六种组合,能够控制十六选一多路选择器。
电路的输入数量也可以不是 2 的整数次幂,例如只有三个输入。这时会有一些选择组合未被使用,设计者需要规定遇到这些组合时电路如何响应。
8. 用小型多路选择器构建大型多路选择器
我们可以用三个二选一多路选择器,构建一个四选一多路选择器。
这种结构称为多路选择器树(Multiplexer Tree):前面的小型多路选择器将输出送入后面的多路选择器,共同完成更大范围的选择。
在第一级,一个多路选择器负责在 D0 和 D1 之间选择,另一个负责在 D2 和 D3 之间选择。
这两个多路选择器都使用 S0 作为选择信号。
在第二级,第三个多路选择器从第一级的两个结果中选择一个,它使用 S1 作为选择信号。
**级(Stage)**指电路中的一个处理层次。在这个例子中,数据需要经过两级选择才能到达最终输出。
假设 S1 S0 为 10。
由于 S0 为 0,第一级分别从第一组中选出 D0,从第二组中选出 D2。
由于 S1 为 1,第二级选择第二组的结果。
因此,最终输出为 D2。
这种方法可以构建更大的多路选择器,但增加级数也会增加信号通过电路所需的时间。
9. 一次选择一整组二进制位
到目前为止,每个数据输入都只携带一个位。
处理器通常需要同时选择由多个位组成的数值。
**总线(Bus)**是一组共同传输相关信息的信号线。在这个例子中,一条八位数据总线通过八条独立信号线,同时传输八个位。
这种同时传输的方式称为并行(Parallel)。总线的**宽度(Width)**就是它能够并行传输的位数。
如果要在两个八位数值之间进行选择,可以把八个单比特二选一多路选择器并排放置。
每个多路选择器负责一个对应的位位置,八个多路选择器共用同一个选择信号。
当 S 为 0 时,所有输出位都来自第一条输入总线;当 S 为 1 时,所有输出位都来自第二条输入总线。
它们共同构成一个八位宽的二选一多路选择器。
这里的两个数字描述不同的属性:“二选一”说明有多少个数据来源可供选择,“八位宽”说明每个来源携带多少位数据。
10. CPU 如何使用多路选择器
**CPU(Central Processing Unit,中央处理器)**负责执行程序指令。**指令(Instruction)**是经过编码的命令,用来告诉处理器执行什么操作。
在 CPU 内部,数据经常有多个可能的来源或去向。
**寄存器(Register)**是处理器内部容量小、速度快的存储位置,用来保存当前正在处理的数值。
**ALU(Arithmetic Logic Unit,算术逻辑单元)**负责加法、减法和按位逻辑运算等操作。**按位运算(Bitwise Operation)**是分别对相应的二进制位应用逻辑规则。
ALU 在执行运算之前,CPU 必须先为它提供输入。参与运算的数值称为操作数(Operand)。
例如,一条指令可能将两个寄存器中的值相加,另一条指令则可能将寄存器中的值与指令里包含的常数相加。
**立即数(Immediate Value)**就是直接包含在指令中的常数。
多路选择器可以决定 ALU 的某个输入来自寄存器,还是来自经过必要处理的立即数。
CPU 的**控制逻辑(Control Logic)**负责产生信号,协调内部各部分的操作。它根据当前执行的指令,设置多路选择器的选择信号。
另一个多路选择器可能负责决定写入寄存器的数据来源:是 ALU 的运算结果,还是从内存读取的数据。
这些选择电路构成了 CPU **数据通路(Datapath)**的一部分。数据通路是处理器中负责传输和处理数据的电路及连接的集合。
有了多路选择器,不同指令就能在提供不同输入数据的同时,共用同一套运算硬件。
11. 真实的多路选择器需要响应时间
逻辑规则描述的是输出最终应该变成什么,并不意味着输出会瞬间改变。
**传播延迟(Propagation Delay)**是从输入发生变化,到输出作出相应变化之间的时间。
当被选中的数据输入发生变化时,输出需要经过一小段时间才会反映这个变化。改变选择信号,同样需要一定时间才能影响输出。
如果多个信号在相近的时间发生变化,输出在稳定下来之前,可能短暂出现一个非预期的值。这种短暂的异常变化称为毛刺(Glitch)。
当多路选择器连接到寄存器时,这一点尤其重要。
电路必须留出足够的时间,让选中的数据稳定下来,然后再由寄存器捕获。硬件设计者会在安排系统时序时,考虑多路选择器和其他电路的延迟。
层次更深的多路选择器树通常会增加延迟,因为信号需要经过更多级电路。实际延迟还取决于具体的电路实现,以及输出端所连接电路带来的电气负载。
这里的**电气负载(Electrical Load)**是指后续电路对信号驱动端形成的电气影响,例如需要充放电的电容。负载大小会影响信号变化的速度。
因此,电路不仅要在逻辑上选择正确,还必须在时间上满足要求。
12. 多路选择器与解复用器的区别
**解复用器(Demultiplexer,简称 DEMUX)**也称分路器,它将一个数据输入送往多个输出中的某一个。选择信号决定哪一个输出接收输入值。
多路选择器决定读取哪个来源,解复用器决定把数据送往哪个目标。
例如,四选一多路选择器从四个输入中选择一个,送到单个输出端。一分四解复用器则把单个输入送到四个输出中的某一个。
在基本的数字解复用器中,未被选中的输出保持为 0。
两者的名称相似,因为它们都根据控制信号分配数据路