入坑数字逻辑电路基础心得
SaKongA Lv1

Before This

或许是这个故事的起点?

我理解的数字电路与模拟电路?

对于数字电路,最简单的解释就是用电路中的电压、电流等物理量来表示0和1两种状态,没错,通常就只是这两种状态。非要用不严谨的描述来说的话,数字电路就是用高电压和低电压两种状态来表示0和1。有了0与1这两个数字之后,我们就有了二进制计数法,有了二进制,我们就可以表示任意大的数量了;
那模拟电路呢?我们知道,在电路里面电压、电流等物理量不是只有高低、通断两种状态,还有具体的大小变化,他们都是连续的,模拟电路就是用这种连续的量来表示具体的数据。
举个栗子,0V与5V,如果我们只关注这两个值,我们可以说是一个高电压,一个低电压,从而有了数字电路的概念。但是如果我们关注整体,想一下从0V变化到5V,它是一个连续的过程,比如0.1V,1V,2V ··· 4.8V,5V,在这个过程中,我们所得到的信息是连续不断的,而不是像数字电路一样只关注起始的0V和5V,这就是模拟电路的意思。
image
说这么多有什么用呢?很简单,数字电路是表示数的,所以可以做运算芯片,算数;模拟电路可以表示一个过程中连续不断的量,所以可以做传感器芯片,用电流、电压表示物理量,比如压力传感器芯片中,压力的越用力,电压越高,得出来压力也越大,这个过程是可以画成一条连续的曲线的。

用MOS管表示0和1

既然我们要做数字电路,那就找一个能改变电路两种状态的东西,最简单的,开关!没错,本质就是用开关控制电路通断,实现两种状态,来表示0和1。但是在芯片里面,开关那可太大了,而且也没法用手去开启关闭。于是大佬发明了一个新东西:晶体管。
这东西其没啥高级的,就是一个不用手,而是用电控制的开关。全称是:金属-氧化物-半导体场效应晶体管 (Metal-Oxide-Semiconductor Field-Effect Transistor, MOSFET), 简称MOS管。
如何使用它?很简单,MOS管有三个接口,或者说三个脚,即栅极(Gate),源极(Source),漏极(Drain)。我们可以这样去理解,栅极就是开关的按钮,就好比栅栏,能打开关闭;源极,顾名思义就是源头,可以理解为是电流的源头;漏极,就是漏出去的地方,电流出去的地方。
因此,我们要做的就是控制栅极,然后实现源极的电流能不能进入到漏极。
问题来了,我们如何去操作这个栅极?对于按下式的开关,我们按下,和松手就是连接和断开,那MOS管呢?很好,我们这里就可以把MOS管分为两个大类了:p型MOS管和n型MOS管,即pMOS与nMOS,控制方式如下:

  • 对于 nMOS 来说:
    • 栅极 和 源极 的 电压差 过 “大” (Vg-Vs 较大)的时候,导通,即源极接通到漏极;
    • 栅极 和 源极 的 电压差 过 “小” (Vg-Vs 较小)的时候,断开,即源极与漏极断开;
  • 对于 pMOS 来说:
    • 源极 和 栅极 的 电压差 过 “大” (Vs-Vg 较大)的时候,导通,即源极接通到漏极;
    • 源极 和 栅极 的 电压差 过 “小” (Vs-Vg 较小)的时候,断开,即源极与漏极断开;

问题又来了,我们为什么要研究出这两种MOS管呢,能控制开关不就得了?答案就是,我们不一定非要在栅极高电压的时候就是导通,有的时候也想让栅极高电压时断开源极与漏极。说人话就是,我打开你这个开关的时候,不一定就是让你通电,还有可能是断电哦~
我们来看下面这个具体的例子:

image

  • 当我们在点A施加一个和Vcc差不多的电压
    那么这个时候,上方的pMOS压差小,就会断开;下方nMOS(相较于接地)压差大,就会导通->那么Y就是只和nMOS的源极GND接通,也就是和GND一样的低电压;

  • 当我们在A点施加一个和GND差不多的电压
    那么这个时候,上方的pMOS压差大,就会导通;下方nMOS和接入的电压差不多,就会断开->那么Y就是只和pMOS的源极Vcc接通,也就是和Vcc一样的高电压;

简单的说无论是nMOS还是pMOS,栅极和源极差不多的时候截止,差得多的时候导通。
像上面如图所示的MOSFET电路,既有nMOS也有pMOS,由于nMOS和pMOS具有互补的特性,我们就称它为CMOS(Complementary Metal-Oxide-Semiconductor)技术。

通过MOSFET实现门电路

从前面的信息我们了解到,可以使用MOSFET实现导通和断开两种状态,因此我们还可以用它的漏极输出有无,来表示0和1这两个信号。
那现在我们想要对这两个实现各种转换,比如判断输入的两个信号是否一样,一样输出1,不一样输出2;再比如说,判断两个信号是不是都是0,都是0则输出1,不是输出0。我们把这种有特殊运行规则的电路叫做门电路,门电路实际上就是对数字信号进行运算。

写在前面

在分析MOSFET电路的时候,我自己的总结了几个新人容易踩坑的地方,并且说几点我自己的分析思路,可能有助于后人来入坑(?)
第一,我们所谓的输出1和0,高信号和低信号,其实就是输出的两种状态,所谓的输出是什么,只是我们人为定义的含义,我们甚至可以认为有输出是男生,无输出是女生。如何表示没有特定的规则,关键在于理解有没有输出这两种状态;
第二,在分析MOSFET电路的时候,我们不要想太多,仔细揣摩一下pMOS和nMOS的导通和截止的性质,在正确的MOSFET电路中,其实无论是pMOS还是nMOS,只要栅极和源极之间有大一点的压差,就会导通,无论谁大于谁;
第三,不要把GND认为是整个MOSFET电路电流的输出位置!GND只是零电位参考点,表示的是相对我们VCC来说的一个零电位,更低的一个点位,远低于VCC的一个电位。因此,其实我更推荐把VCC换为高压,GND换为低压来理解,我们的输入高信号也是高压,MOSFET是比较的栅极和源极之间有没有太大的压差;
第四,在分析MOSFET电路的时候,我一般会先关注控制高压的部分,看看哪几个MOS管控制高压,因为只有高压进入,才会有可能输出高信号。
第五,不管是什么门电路,MOS管始终控制的是电流的流入,而不是流出。这里又要强调,不要把GND认为是整个MOSFET电路电流输出位置!我们只是控制的是接通的低压,还是接通的高压,然后输出的是高压,低压,以此来表示高信号和低信号。拿最简单的非门来说,如下一节中所示的非门MOSFET电路图片中,上方的pMOS连接的是顶部的高压电源,下方的nMOS连接的是底部的低压电源(这里虽然是连接到的是GND零电位点,但是我们理解为是低压),所以pMOS控制高压流入,nMOS控制低压流入。

非门

非门也叫反相器,是最简单的门电路。顾名思义,就是将我们的输入信号反过来,变成输出信号。其电路结构正是我们前面所看到的那个例子,将一个pMOS和一个nMOS并联起来。非门的MOSFET门电路和表示符号如下图所示:
image
那我们想要彻底了解这个非门电路的运行情况,就需要引入一个叫做真值表的东西,其实就是表示这个电路能输入什么,对应的能输出什么。非门的真值表如下表所示:

输入A 输出Y
1 0
0 1

一句话总结非门,就是信号取反,这个还是比较简单的。

与非门

接下来就是与非门。通过非门,相信你已经了解门电路是什么意思了,那我们这里先说与非门的结论:所有输入均为高时,才会有输出为低。我们来看一下与非门的MOSFET电路:
image
仔细观察的话,会发现电路是有两个pMOS并联,和两个nMOS串联实现的。pMOS控制Vcc,而nMOS用来控制是否接通GND,为整个电路接地。当有一个pMOS接通,Y就可以输出高信号。为了得到真值表,让我们来分析这个电路的每个元件的运行状况:

输入A 输入B pMOS-1 pMOS-2 nMOS-1 nMOS-2 Y
0 0 导通 导通 截止 截止 1
0 1 导通 截止 导通 截止 1
1 0 截止 导通 截止 截止 1
1 1 截止 截止 导通 导通 0

综上,我们只取输入与输出,可以得到下表的真值表:

输入A 输入B Y
0 0 1
0 1 1
1 0 1
1 1 0

可以得到和前面一样的结论:所有输入均为高时,才会有输出为低。

与门

与门就是将与非门后面接一个非门,即把与门的输出取反。真值表如下表所示:

输入A 输入B Y
0 0 0
0 1 0
1 0 0
1 1 1

因此可以出结论:所有输入均为高时,才会有输出为高。可以看到,只有输出反过来了。
同理,我们也可以在与非门的MOSFET电路后面,加一个非门的MOSFET电路,就可以实现与门的MOSFET电路,电路结构和与门的符号表示如图所示:
image

我们看图中与门的表示符号的输出端相比于与非门的符号,少了一小圆圈,这个小圆圈就是取反的意思。为什么多了取反电路,反而要去掉取反的小圆圈呢?我们可以这样理解,虽然与门的结果是与非门取反得到的,但是不看MOSFET电路,与非门的结果也是与门取反的结果。而“非”这个字就是取反的意思,因此与非门多了一个圈。“与”、“非”只是一种运算,和具体的MOSFET电路没啥关系,不是说有“非”就一定要有取反的电路。

或非门

先说结论:所有输入均为低时,才会有输出为高。因此,我们可以得出或非门的真值表:

输入A 输入B Y
0 0 1
0 1 0
1 0 0
1 1 0

或非门的MOSFET电路结构与与非门相似,如下图所示。可以看到,两个串联的pMOS控制高电压的进入,两个nMOS并联控制低电压的流入。我们可以理解为,pMOS只要有一个截止,高电压就会被截止,无法输出高信号,即A、B只要有一个为高信号,就会有pMOS截止,导致高电压无法流入,进而无法输出高信号。因此,所有输入均为低时,才会有输出为高。

image

或门

按照与非门和与门的规律,或门就是或非门后面加上一个非门,就可以实现结果取反了。因此结论就是:所有输入均为低时,才会有输出为低。真值表如下:

输入A 输入B Y
0 0 0
0 1 1
1 0 1
1 1 1

根据上面我们说的或门是在或非门后面加上一个非门,我们可以画出相应的MOSFET电路结构:
image

异或门

异或门用于进行异或(eXclusive OR, XOR)运算, 异或是一个特殊的运算, 通常在处理逻辑数据时使用, 其真值表如下:

输入A 输入B Y
0 0 0
0 1 1
1 0 1
1 1 0

我是这样理解异或门的:“异”或门,即在或门的基础上,只对“异”信号输出高信号,即只有信号不一样的时候,才输出高信号,原本两个高信号也要输出低信号。
异或门电路可以通过一个或门和一个与门,两个非门来实现,如下图所示。对比前面的全定制MOSFET电路,少许复杂。

image

全定制电路: 通过晶体管设计电路
在晶体管层次设计的电路称为全定制电路. 通过三输入与非门的例子, 我们可以看到, 全定制电路所需要的晶体管数量更少, 因此电路面积也更小. 在实际生产中, 除了面积更小之外, 全定制电路的主频也更高, 功耗更低。
但是, 全定制电路的设计难度大, 开发周期也很长. 现代处理器芯片包含动辄上亿个晶体管, 全部使用全定制电路来开发是不现实的. 对于超大规模集成电路的设计, 更常见的是采用的是半定制电路设计方法。
半定制电路的设计又分为基于标准单元的设计方法和基于门阵列的设计方法. 前者是预先用全定制方式设计出一些常用的逻辑单元, 例如与门、或门、触发器等, 这些逻辑单元称为标准单元; 然后再通过这些标准单元构建出大规模电路. 回到上面三输入与非门的例子, 如果把两输入的与门和两输入的与非门看成是标准单元, 那么通过它们搭建三输入与非门就可以看成是半定制电路的设计方法. 至于基于门阵列的设计方法, 一个常见的例子是FPGA. 但我们接下来不打算使用FPGA, 感兴趣的同学可以搜索相关资料。
在现代的处理器芯片设计中, 大部分情况下都使用基于标准单元的半定制电路设计方法; 只有在追求极致表现时(例如企业产品通过追求高性能占领市场), 才会对电路中的部分核心模块进行全定制设计。
引自:https://ysyx.oscc.cc/docs/2407/f/3.html

门电路小结

到目前为止,我们已经学习了常用的6大门电路,也就是Logisim工具栏中的6种门电路,有了这6种逻辑门电路,就可以进行后面各种逻辑运算单元的搭建了,以下为汇总表。

名称 特性
非门 信号取反
与非门 所有输入均为 高 时,才会有输出为 低
与门 所有输入均为 高 时,才会有输出为 高
或非门 所有输入均为 低 时,才会有输出为 高
或门 所有输入均为 低 时,才会有输出为 低
异或门 输入不一样时,输出高

进位计数法

经过前面门电路的学习,我们知道CMOS电路可以,也只可以处理高信号、低信号,即0和1两种状态的信号。如果我们想要通过CMOS电路完成我们实际生活中的逻辑运算,就需要某种特殊的表示方法,只用这两种状态的信号,来表示其他事物。
比如我们现在想做一个计算器,就需要用门电路计算加减法,但是我们平时学习的加减法,都是十进制计数法,用0-9这10个数字来表示,而门电路只能处理0与1两种状态的信号,所以我们就要用一种特殊的计数法,只用0与1来表示十进制所有的数字。
这种表示方式称为”编码”(encoding)。物理世界中的信息有很多, 我们先考虑如何表示自然数。

二进制计数法

在了解二进制之前,我们先学习十进制的组成。
假设我们现在有一个十进制数字“734”,如果我们只用10、10²、10³…等表示,可以像下面的式子一样拆解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
734 = 7x100 + 3x10 + 4x1
= 7x10² + 3x10¹ + 4x10º
```

“734”是一个三位十进制数字,那如果我们有一个随机的三位十进制数字呢?如:“a₂a₁a₀”(如果和734进行对应,a₂对应7,a₁对应3,a₀对应4),那么可以按照如下拆解:

```TEXT
a₂a₁a₀ = a₂x100 + a₁x10 + a₀x1
= a₂x10² + a₁x10¹ + a₀x10º
```

很好,那如果我们扩展到n位的随机十进制数字呢?即:“aₙ₋₁aₙ₋₂···a₂a₁a₀”,那么可以按照如下拆解:

```TEXT
aₙ₋₁aₙ₋₂···a₂a₁a₀ = aₙ₋₁x10ⁿ⁻¹ + aₙ₋₂x10ⁿ⁻² + ··· + a₂x10² + a₁x10¹ + a₀x10º
```

我们如果想把这个规律扩展到其他进制的数字呢?我们可以发现,十进制和其他的进制拆开后,最大的区别就是乘的数字不同,故可以得到以下规律:
通常,对于n位b进制数“aₙ₋₁aₙ₋₂···a₂a₁a₀”,其真值可以通过以下加权求和展开式得到:

![Image](https://github.com/SaKongA/picx-images-hosting/raw/master/加权求和.2yyr8c2mv2.webp)

其中,“b”称为基(base),“bⁱ”称为每一位的权重。
现在,如果我们想要用这个方式来表示二进制数,只需要让 b = 2,并让 aᵢ 在“0”和“1”中取值即可,这样,我们就得到了二进制(binary)计数法。
但是有一个问题,由于十进制也会使用数字“0”与“1”,如数字“11”。我们需要一种办法区别某个数字是用十进制表示的,还是二进制。有的编程语言,通过在二进制数字最前面添加前缀`0b`来表示这个数字是一个二进制数字,如`0b010111`;有的则是在二进制数字末尾添加右下角的角标`B`,如:`01010111B`。我们主要采用第一种办法,使用前缀`0b`来表示我们的数字是一个二进制数。例如, 二进制数`0b00101110`的真值是:

```TEXT
0b00101110 = 1x2⁵ + 1x2³ + 1x2² + 1x2¹
= 32 + 8 + 4 + 2
= 46
```

那如果我们想要把一个十进制的数字转为二进制数字呢?一种办法是通过上面的展开式,把每一项进行进一步的展开,如下图所示:

![Image](https://github.com/SaKongA/picx-images-hosting/raw/master/十进制数公式展开求二进制数.7eh6dlf132.webp)

不难发现,其实这个过程的本质就是让待转换的十进制数字不断的除二,然后取余数,因此,有了第二种转换的办法--"短除法"。
短除法,顾名思义,即不断的把待转换数字除2,取余数的竖式,在式子中,先得到的余数,作为转换出的二进制数的最低位,如下图所示:

```TEXT
2 | 46 -> 0 ^ 低位
+---- |
2 | 23 -> 1 |
+---- |
2 | 11 -> 1 |
+---- |
2 | 5 -> 1 |
+---- |
2 | 2 -> 0 |
+---- |
2 | 1 -> 1 | 高位
+----
0 (商为0, 结束)
```

同样可以得出“46”的二进制计数结果为:0b11101,和上面第一种办法得出的结果,省略高位的无意义0后一致。

### 十六进制计数法
除了我们最熟悉的十进制计数法、二进制计数法,计算机还有一个常见的计数法--十六进制计数法(hexadecimal),在十进制的0-9共10个数字的基础上,增加了a、b、c、d、e、f六个字母来表示十进制中的10、11、12、13、14、15,所以一位16进制数字可以表示0-15共16个十进制数字。
同样的,它也需要特定的前缀或后缀来表明一串数字是十六进制。在一些教材在整串数字的右下角添加字母`H`来表示这个数字是一个十六进制数;另一种表示的方法就是在整串数字前面添加前缀`0x`,如`0xbeef`。
根据我们的公式,如果想把这个十六进制数字转化为10进制真值,其加权求和展开公式如下:

```TEXT
0xbeef = 11x16³ + 14x16² + 14x16¹ + 15x16⁰
= 45056 + 3584 + 224 + 15
= 48879
```

虽然数字电路无法直接处理十六进制数,但是由于 16=2⁴,我们可以把一个二进制数字,每四位作为一组,然后转化为对应的16进制(即先把4位的二进制数字转为十进制,然后找到十进制数字对应到其十六进制数字):

```TEXT
1011 1110 1110 1111
| | | |
11 14 14 15
| | | |
b e e f

对于高位不足的情况,我们直接补0,凑到4个数一组即可,如0b1111011101111

1
2
3
4
5
0001 1110 1110 1111
| | | |
1 14 14 15
| | | |
1 e e f

因此, 该二进制数对应的十六进制数即为0x1eef. 可以看到, 和二进制表示的0b1111011101111相比, 十六进制表示的0x1eef更加简洁紧凑。

通过门电路搭建基本组合逻辑电路

从这一节开始,我们就开始进入数电的核心部分了,前面我们说的门电路和进位计数法均为组合逻辑电路的基础,现在我们需要把门电路和二进制数结合到一起,通过门电路处理二进制数据,进行特定的逻辑运算,如加法、减法等,最终作为成品的模块。

译码器

译码器是一种将k位输入转为为2ᵏ种不同输出的电路。听完这句话之后你是不是很懵,这是什么意思,他有什么用?别急,我们从最简单的“n选1译码器”开始了解译码器。

n选1译码器

对于“n选1译码器”,我们可以通过现象来理解它,前面说了,“n选1译码器”是最简单的一类译码器,那我们来看一个“n选1译码器”中简单的4选1译码器:2-4译码器。根据名字来看,2表示这个译码器有两个输入,4个输出,我们假定两个输入为“A₁”、“A₀”,四个输出依次为:“Y₃”、“Y₂”、“Y₁”、“Y₀”,那么2-4译码器的真值表如下:

A₁ A₀ Y₃ Y₂ Y₁ Y₀
0 0 0 0 0 1
0 1 0 0 1 0
1 0 0 1 0 0
1 1 1 0 0 0

我们仔细观察真值表,并把输出作为一串数字(不要纠结是什么进制的数字,就是一串没有意义的数字),可以得到以下规律并理解什么是译码器:

  • 这个译码器有2个输入,4个输出;
    -> 即章节开头所说的,译码器是一种将k位输入转为为2ᵏ种不同输出的电路,输入的位数和输出的位数是相对应的。而“n选1译码器”就是有n位输入,2ⁿ位输出的一种特殊译码器。
  • 无论输入是什么,输出最多有一位是1,而且1在不同输入的情况下,所在的位数还不一样;
    -> 这就是“n选1”的意义,即从n位输出中,选出特定的1位,输出1,有且仅有1位。
  • 如果我们把输入信号作为一个二进制数值,比如A₁为1,A₀为0的时候,二进制数字10表示的是十进制数字3,而你惊奇的发现,输出中唯一的1,正是在第3位;
    -> 这就是“n选1译码器”的核心功能–“选择”。你可以理解成,“n选1译码器”把你输入的信号,看作一个二进制数,然后通过门电路,将这个选择体现在真实的电路中,而不再是一个抽象的数字。举个简单的例子,比如现在有很多人在排队,你想快速找到第97个人是谁,我们通常的办法就是从头开始数,直到数到第97个人,但是现在有了“n选1译码器”,我们想要找到第97个人,在“n选1译码器”上面输入97,“n选1译码器”就会给第97个人发消息,让他直接出列,大大减少了我们的寻找时间。

对于“n选1译码器”,我们已经知道了她的输出不管有多少位,最多只会有一个1,如果我们把2-4译码器的输出看作一串数字,所有可以输出的数字为:0001,0010,0100,1000。类似的,像输出仅有1位为1的一串数字, 称为”独热码”(One-hot),它是一种特殊的编码,就是一种表示某些特殊含义的编码,和二进制、十进制等等都没有关系,只是一串有着特殊含义的数字而已。
通过上面的规律分析,我们基本了解了“n选1译码器”的特性,让我们来看一下“n选1译码器”的具体门电路结构,如下图所示:

image

在计算机中, n选1译码器常用于实现寻址的部分功能, 此时译码器的输入即为地址, 输出则是选择信号, 其中与地址对应的选择信号为1。

转码器

既然n选1译码器可以输出独热码,将二进制数字转化为具体的选择结果,那我们是不是也可以将二进制数字转化为某种我们想要的结果呢?有的兄弟,让我们来认识一下:转码器(code translator)。
转码器其实是对“将二进制数字转化为某种我们想要的结果”的译码器的统称,一个常见应用是七段数码管译码器(7-segment decoder)。七段数码管是一个由7段发光二极管按”8”字型排列组成的输出元件,其每一段发光二极管都可以单独的控制,通常是按照下面图片所示来定义每个数码管的字母标识:

image

如果我们想要通过让七段数码管显示我们想要的数字,就需要点亮特定的发光二极管,也就是向特定编号的发光二极管输出高电平。问题来了,我们总不能手动给每一个发光二极管通吧,太麻烦了,于是七段数码管译码器就出现了。我们可以向七段数码管译码器输入一个二进制整数,让七段数码管译码器帮我自动点亮表示这个整数所需要的发光二极管,即告诉所有的发光二极管,你应该亮还是不亮。我们按照a、b、c、d、e、f、g、h的顺序,让七段数码管译码器输出这样顺序的编码,如下所示:

1
2
3
input    output
abcdefgh
0100 01100110

假设我们的七段数码管是高电平点亮,那么,我输入0100(4的二进制数字),译码器就会输出01100110,然后点亮b、c、f、g共4个发光二极管,效果就是显示了个数字“4”。

编码器

编码器(encoder)就是反过来的译码器,它可以把输入当做独热码,然后转为对应的二进制数值。例如, 一个4-2编码器有四位输入A₃、A₂、A₁、A₀,两位输出Y₁、Y₀,可以得到其真值表如下:

A₃ A₂ A₁ A₀ Y₁ Y₀
0 0 0 1 0 0
0 0 1 0 0 1
0 1 0 1 1 0
1 0 0 0 1 1
X X

于是,我们可以得到这样的结论:和译码器相反,编码器有2ⁿ位输入,n位输出,对于4-2编码器来说,如果输入是独热码,定义输入中为1的是第x位,那么就会输出x的二进制数值;如果输入的不是独热码,如“0101”,那么输出是未定义的。
对应到前面排队的那个例子,就好比某一个同学主动出列,4-2编码器可以立马告诉他:“同学你是第97位”,而不用同学自己一个人一个人的去数了。
在计算机中, 编码器常用于根据用独热码表示的选择信号生成相应地址。另一种理解是用于找出独热码中1的位置。

多路选择器

前面我们通过“n选1译码器”实现了输入二进制数字,输出对应特定位的高信号的功能,由此,我们可以基于“n选1译码器”,实现从几路输入选择某一路输出,这就是多路选择器,从多路输入中选一路输出。
最简单的选择器是“1位2选1选择器”,即1位选择信号输入,从2路待选择的信号中选出一路进行输出,顾名思义,是基于1-2译码器来实现的,其电路结构如图所示:

image

其简化后的真值表如下:

S Y
0 D₀
1 D₁

在计算机中, 选择器是使用频率很高的元件, 因为计算机的本质是用于处理数据, 而数据的来源和处理方式都很多, 因此需要大量的选择器来对数据来源和处理结果进行选择。

比较器

假设你现在想要对比两个二进制数:0b1010111101110b101001110111是否一致,直接看的话,可能有点费劲,于是有了比较器这个东西。比较器本质上是通过异或门+非门(也就是同或门)来比较二进制数字的每一位,只有两个数字完全一致的时候,才会输出1,说起来可能有点抽象,看图你立马就明白了。
现在我们有两个二进制数需要比较:0bA₀A₁A₂A₃0bB₀B₁B₂B₃,可以按照下面的4位比较器电路结构进行输入和比较:

image

我相信你看完图就瞬间明白了,比较器是如何工作的,即通过比较输入的二进制数的每一位,只要有一位不一致,对于使用异或门+非门搭建的比较器,异或门就会输出1给非门,非门反转后,将0传递给与门,与门只有所有输入全为1的时候,才会输出1,所以就会输出0。而使用同或门搭建的比较器,省了非门反转这一步。

加法器

从加法器开始,你将会慢慢的切身感受到数电的强大之处,因为这是真正意义上的离我们最近的逻辑运算。
加法是算术运算的基础, 因此需要考虑如何通过门电路实现加法。首先考虑1位加法器,也就是两个一位的二进制数的相加,思考一下,两个一位的二进制数的相加,因此有两个输入;相加的话,1+1=2,会成为一个两位二进制数,因为在二进制计算中进位了,因此至少要有两个输出,一个表示最低位,一个表示是否进位了。据此,我们可以得到1位加法器的真值表,其中S代表Sum,即输出和;C代表Carry,即输出进位:

A B S C
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

半加器的逻辑门电路如下图所示:

image

现在,我们已经明白了当两个一位二进制数相加,可以用一个Sum和Carry来表示最后的结果,但是如果是两个两位或两位以上的二进制数相加呢?第二位相加的时候,怎么处理上一位的进位呢?这个时候就需要引入“全加器”这个东西了。
全加器需要输入三个信号,分别是A(加数)、B(被加数)、C-in(Carry-In,即来自低位的进位);有两个输出信号,分别是S(Sum,即输出和)、c-out(Carry-Out,即当前位计算的输出进位),容易得出,其真值表如下表所示:

A B C-in S C-out
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1

全加器的逻辑门电路如下图所示:

image

回到加法器的起点,最简单的多位加法器(就是计算多位二进制数相加的器件),其实就是把两个多位二进制数的第一位通过半加器相加,后面的位通过全加器分别相加。其中,第一位通过半加器相加后,如果有输出进位,就传递给后一位的全加器,然后后一位的全加器如果有进位,进一步传给后面的全加器,以此类推,就可以实现多位加法器。4位加法器的计算流程如下图所示:

image

细心的你肯定发现了,为什么第一位计算,半加器会有进位C0输入呢?答案就是,第一位计算也用的是全加器,但是并不影响使用,C0固定输入0即可。

整数的机器级表示

由 Hexo 驱动 & 主题 Keep
访客数 访问量