基本数字逻辑电路

tao
发布于2022-03-22

在查阅资料了解了一些历史上的计算机之后,我对现代计算机的运行方式有了兴趣,所以就继续查资料满足我的好奇心,这篇笔记记录一些基本的数字逻辑电路。

开始之前先分享几个非常好用的工具,一个是 draw.io ,除了 Windows 和 MacOS ,它还支持了 Linux ,如果你不想安装桌面端软件,直接网页访问 draw.io 都可以很流畅的使用它。我们可以用它来创建流程图、框架图包括电路图等。

还有一个是 Logisim,支持 Windows 和 MacOS,是一种用于设计和模拟数字逻辑电路的教育工具。凭借其简单的工具栏界面和构建它们时的电路仿真,有助于学习与逻辑电路相关的最基本概念。

最后一个是 logicly ,它是一个可以让你高效的学习数字逻辑电路的工具,支持 Windows 和 MacOS ,通过这个软件可以模拟真实信号,让我们画出的电路图能通过它得到类似于实物的直接反馈。就是如果线连多了整个看上去会变得有点杂乱。

logicly-screen-thumb-1.png

接下来,让我们一起来学习基本数字逻辑电路,说到底,所有的数字逻辑最终都建立在晶体管可以作为一个快速二进制开关这个事实上。下图是一个二级晶体管的简单电路,该晶体管对外有三个管脚:集极基极射极。当输入电压 V in 低于特定的门槛时,晶体管是断开的,其功能就像一个无穷大的电阻。这就使输出电压 V out 的值接近于外接基准电压 V cc 的值,对这类晶体管来说,一般为 +1.5V 。而当 V in 的值超出门槛时,晶体管被接通,就像一根导线,使得 V out 直接接地,电压值为 0。

截屏2022-03-08 下午2.03.38.png

也就是说,当 V in 电压较低时,V out 的电压较高,反之则较低。这样,该电路可以说是一个反转器(非门),将逻辑值 0 转换成 1,将逻辑值 1 转换成 0。状态转换的时间一般为 1 纳秒甚至更短。

下图将两个晶体管串联层叠在一起。在 V1 和 V2 同时为高时,两个晶体管都处于连通状态,V out 将被拉低。如果 V1 和 V2 有一个为低,则 V out 将输出高电压。也就是说 V1 和 V2 同时为高电压时输出低电压,该电路可以说是一个与非门

截屏2022-03-08 下午2.08.40.png

下图中的两个晶体管并联,在这种情况下,V1 和 V2 中任意一个为高电压,则输出为低电压,若 V1 和 V2 同时为低电压时,输出为高电压,该电路可以说是一个或非门

截屏2022-03-08 下午2.14.49.png

上面这三种电路,或他们的等价形态,形成了最简单的三个门,分别是非门(NOT)、与非门(NAND)、或非门(NOR),非门又经常被称为反转器(inverter)。下图给出了这三种门的符号及真值表。

截屏2022-03-08 下午2.30.09.png

图中反转器、与非门、或非门上的小圆圈,我们成为反转泡(inversion bubble)

如果我们将与非门和或非门的输出再次输入到一个非门中,就得到了完全相反的两种电路与门(AND)或门(OR),下图给出了他们的符号及真值表。

截屏2022-03-08 下午2.33.09.png

这五种电路即门,是数字逻辑电路最主要的的组成部分,与非门和或非门需要 2 个晶体管,与门和或门需要 3 个晶体管,因此许多计算机基于的是与非门和或非门,而不是我们更熟悉的与门和或门。

布尔代数与等价电路

为描述通过门的组合组成的电路,我们需要一种新的代数,它的所有变量和函数的值都只能为 0 和 1。我们把它称为布尔代数,是以它的发明者英国数学家 George Boolean 命名的。

n 个变量布尔函数的不同输入值的组合最多只可能有 2n2^n 种,其功能可以通过一个有 2n2^n 行的表格描述清楚,表格中的每一行描述一种输入值组合对应的函数值。这种表格称为真值表。如果我们都将真值表的行按输入值的二进制大小从大到小排列,函数值则可以从上到下读出来构成函数描述,例如与非门的函数为 1110,或非门为 1000。显然,对于两个输入变量,只可能有 16 个布尔函数存在,分别对应 4 位函数值串可能的 16 种组合。

尽管任何一个布尔函数都可以用真值表来描述,但是随着输入变量越来越多,这种描述方法也就越来越笨拙,因此我们需要升级描述布尔函数的方法。

接下来我们实现一个三变量的表决函数,也就是说,输入变量多数为 0 时,函数输出结果为 0,如果输出变量多数为 1 时,函数的输出结果为 1。

我们设这个函数为 M=f(A,B,C)。在输入变量上加上一小横线来表示其值被求反,没有小横线表示其值为原值,用隐含的乘号或小圆点来表示布尔与函数,用“+”表示布尔或函数。按照此描述规定,ABCA\overline{B}C 则表示 A=1 且 B=0 且 C=1,AB+BCA\overline{B}+B\overline{C} 则表示(A=1 且 B=0)或(B=1 且 C=0),所以三变量表决函数我们可以写成如下形式:

M=ABC+ABC+ABC+ABCM=\overline{A}BC+A\overline{B}C+AB\overline{C}+ABC

这种公式表示法可以很方便地导出标准门电路对函数的实现。同时可以发现一个 n 个变量的函数可以描述为不超过 2n2^n 个变量“积”项的“和”。

截屏2022-03-09 下午5.29.21.png

图中亮绿色表示 1,深绿色表示 0,根据上面推导出的公式,我们可以很容易的画出对应的电路图。

逻辑电路的设计者经常要减少产品中门的数量,以减少实现时芯片的面积、最小化能耗并提高产品的速度。为降低电路的复杂性,设计者需要找到另外一个能完成和原电路相同的功能,但使用门更少的电路,例如 A+B+C+D 可以等价替换为 (A+B)+(C+D),用双输入的门替换四输入的门。为寻找等价电路,布尔代数是一个有用的工具。

普通代数中的许多规律对布尔代数也是适用的,对 AB+AC,就可以用分配律对其提取公因子,变成 A(B+C)。当且仅当两个函数所有可能的输入对应的输出都完全相同时,我们才把它们视为等价电路。由下图真值表可得这两种电路是等价电路。并且 A(B+C) 的电路使用了更少的门。

截屏2022-03-09 下午6.54.38.png

一般来说,电路的设计者先将电路用各种布尔函数的定律进行简化,得到它的更简单的一些等价函数,最后,再用电路实现其最简形式的函数。

下表列出了一些布尔代数的主要恒等式

截屏2022-03-09 下午7.08.00.png

德摩根律可以扩展到多于两个变量的形式,例如:ABC=A+B+C\overline{ABC} = \overline{A} + \overline{B} + \overline{C},利用德摩根律我们可以得到与非门和或非门的等价形式:

截屏2022-03-15 下午12.01.48.png

这在需要将电路全部转为与非门或者或非门进行等价变换时是很用的。比如异或函数的等价电路变换:

截屏2022-03-15 下午12.06.50.png

组合逻辑电路

许多数字逻辑的应用需要的电路,都有多个输入信号和多个输出信号,且输出信号是由输入信号的当前状态唯一确定。我们把他们叫做组合逻辑电路。

1.多路选择器

多路选择器电路有 2n2^n 个数据输入信号、1 个数据输出信号及用来选择将哪个数据输入信号输出的 n 个控制信号。

截屏2022-03-15 下午4.21.29.png

使用这个多路选择器,可以实现上面我们提到的三变量表决功能电路,任何三变量的真值表都可以用它实现。

截屏2022-03-15 下午5.59.24.png

它还可以用于对数据进行并行到串行的转换,将 8 位数据放在输入信号上,然后按顺序将控制信号从 000 到 111,每步变换一次,8 位数据就可以串行输出到输出信号了。并行到串行转换的典型应用是键盘,每次击键都隐含着将一个 7 位或者 8 位数通过串行链路输出。

与多路选择器相反的是多路输出选择器,根据 n 个控制信号的值,将单个输入信号输出到 2n2^n 个输出信号之一上。若控制信号的二进制值是 k,即在第 k 个输出信号上输出。

2.译码器

译码器(decoder)输入是一个 n 位二进制数,根据二进制的值将 2n2^n 个输出信号中的一个选中。

截屏2022-03-15 下午6.45.02.png

译码器可以用于存储器芯片的选择上,将每个输出信号分别作为一块存储器芯片的使能信号,这样就有一块芯片被选中工作。

3.比较器

比较器(comparator)用来对输入的两个字进行比较,它以异或门为基础实现。

截屏2022-03-15 下午7.12.12.png

算术电路

组合逻辑电路的特征是输出信号是其输入信号的函数,但用于算术运算的电路并不完全具有这个特征。

1.移位器

我们首先来实现一个 8 输入,8 输出的移位器,D0 ~ D7 代表 8 位输入信号,将他们移动一位后的输出结果是 S0 ~ S7。控制信号 C 决定移位的方向,C 为 0 时左移,为 1 时右移。左移时,第 7 位补 0,同样,右移时第 0 位补 0 。

截屏2022-03-16 上午11.41.51.png
2.加法器

完成加法运算的硬件电路是每台计算机的必备部分,1 位整数加法器的真值表如下图所示:

截屏2022-03-16 上午11.46.21.png

能够计算出结果位和进位位的电路如下图所示,它常被称为半加器(half adder)

截屏2022-03-16 下午3.56.08.png

为了能处理进位,我们需要全加器(full adder)。只有在输入信号 A、B 和低位进位三个中有奇数个为 1 时,其输出信号“和”才为1。而只有在 A、B 全为 1 或者它们中只有一个为 1 但同时进位(输入)为 1 时,它产生的进位(输出)才为 1。两个半加器一起产生“和”及“进位”信号。

截屏2022-03-16 下午4.26.59.png

下面给出对 8 位字求和的电路图,同理如果需要能对 16 位字进行求和的加法器,则只需要再增加 8 个全加器即可。这种加法器叫做行波进位加法器(ripper carry adder),因为在最糟糕的情况下,即往 111...111 上加上 1 时,只有在进位从最右边一直进行到最左边时,加法才能完成。没有这种延迟因此也更快一些的加法器也存在。

截屏2022-03-17 下午1.40.24.png

举个例子,将一个 32 位的加法器分成两半,一半用来对低 16 位求和,另一半对高 16 位求和。开始进行加法时,用两个加法器 U0 和 U1 对高 16 位加法器求和,给 U0 的进位设为 0,给 U1 的进位设为 1,让这两个加法器可以并行工作。同时低 16 位加法器也开始工作,得到结果后,得到高 16 位的进位,就可以从两个加法器 U0 和 U1 中选一个正确答案了。这种方案使完成 32 位加法的时间减少了一半。我们把它称为进位选择加法器(carry select adder)。同理,我们也可以把 16 位加法器分解成 8 位加法器,再减少一半的时间。

3.算术逻辑部件

大多数计算机中都会有一个简单的电路,来完成两个机器字的与、或和求和运算。一般来说,这种 n 位字的电路是由 n 个同样的对一位进行运算的电路组成。下图是这种电路的简单实例,它就是我们通常所说的算术逻辑部件(Arithmetic Logic Unit,ALU)。它可以根据功能选择信号 F0 和 F1 的值为 00、01、10、11 的不同,分别用来实现 4 个功能,即 A 与 B、A 或 B、非 B 和 A 加 B。

截屏2022-03-17 下午3.18.22.png

左上角是输入信号 A 和 B,分别使 ENA 和 ENB 信号为 0,可以强制使 A 和 B 为 0,置 INVA 信号为 1,还可以将 A 求反得到 A\overline{A}。通常情况下,ENA 和 ENB 信号都为 1,INVA 信号为 0,这样可以将 A 和 B 不做任何修改输入到逻辑部件中。

右上角是用于计算 A 与 B、A 或 B、非 B 的逻辑部件,右下角则是我们刚刚学习过的加法器。它们根据左下角的译码器决定具体输出哪个运算结果。

我们把现实中这种电路叫做位片(bit slice)电路,它可以供计算机的设计者用来实现任何位的 ALU。

截屏2022-03-17 下午4.00.37.png

内存

任何一台计算机都不能没有内存,离开了内存,也就不存在我们现在所说的计算机。它用来存放计算机执行的指令和执行指令用到的数据。

锁存器

要得到 1 位的内存,我们需要一个能以某种方式“记住”上一个输入值的电路。这样的电路可以由两个或非门构成。

截屏2022-03-17 下午5.07.06.png

我们把上图所示的电路称为 SR 锁存器(SR latch)。它有 S 和 R 两个输入信号,S 用来设置锁存器,R 用来重新设置(也就是清除)锁存器。它的输出信号也是两个,一个是 Q,另一个是 Q\overline{Q},这两个输出值互补。和组合逻辑电路不同,锁存器的输出不仅与当前输入的值有关,还和它上一个状态有关。

当 S=R=0 时,该电路有两个稳定状态,即 Q = 1,Q=0\overline{Q}=0 或者 Q = 0,Q=1\overline{Q}=1,Q 和 Q\overline{Q} 同时为 0 或 1 的情况是不存在的。将 S 置为 1 锁存器状态输出 1,将 R 置为 1 锁存器状态输出 0。该电路可以“记忆”上次是置 S 还是 R,我们正好可以利用这个特性来制造计算机的内存。

1.时钟 SR 锁存器

如果能使锁存器只在某些特定时间改变状态,将带给我们很大的方便。为了达到这个目的,我们对上面的电路进行了一些变动,成为时钟 SR 锁存器(clocked SR latch)

截屏2022-03-17 下午5.58.33.png

尽管名字是时钟锁存器,但是时钟信号不一定要由计算机上真正的时钟信号来驱动,我们也常用术语使能(enable)和选通(strobe)来说明它为 1,所以当使能信号为 1 时锁存器才能对 S 和 R 的变化起作用。

当 S = R = 1 时,锁存器有唯一的稳定状态 Q=Q=0Q = \overline{Q} = 0,当输入变回 0 时,锁存器将立即跳转到它的两个稳定态中的一个。如果有一个输入变化得比另一个早,则另一个保持为 1 的输入将起作用,由它来决定锁存器的稳定态。如果两个输入同时变为 0 (这很难发生),锁存器将会随机跳转到一个稳定状态。

2.时钟 D 锁存器

解决 SR 锁存器存在的不确定状态(由 S = R = 1 而引起的)的一个好办法是防止这种情况出现。如下图所示,电路中只有一个输入 D ,由于下面的的与门的输入总是与上面的与门输入相反,所以两个输入同时为 1 的情况将永远不可能发生。

截屏2022-03-17 下午6.12.13.png

我们把这个电路称为时钟 D 锁存器 (clocked D latch),它是真正意义上的 1 位内存。存放在里面的值总可以从 Q 读取到,要将 D 的当前值写到内存中,只需要将使能信号置为 1。

触发器

许多电路中,必须在特定的时刻对某个信号采样并加以存储。我们把这种存储触发方式的内存叫做触发器(flip-flop),它的状态转变不是发生在时钟信号为 1 时,而是发生在时钟信号从 0 变为 1(上升沿)或从 1 变为 0(下降沿)的时候。这样,时钟信号的脉冲长度就不重要了,重要的是脉冲变化要足够快。

触发器用的是边沿触发,而锁存器用的是电平触发

设计触发器可以有许多方案。例如,如果有某种办法在时钟信号的上升沿产生一个很短的脉冲,再把这个脉冲输入到 D 锁存器中就可以了。

截屏2022-03-17 下午7.12.32.png

乍一看,图中与门的输出将永远是 0,因为任何信号和它的反相与的结果都将是 0,但实际情况有所不同。反转器有一个微小的、但不为 0 的传输延迟,正是该延迟使得电路的功能得以实现。

截屏2022-03-21 上午10.49.35.png

在 logisim 使用一个反转器会使电路出现震荡(oscillation),也就是无限循环,但是我把反转器的数量增加到三个,再把触发信号输入到 D 锁存器中电路功能就正常了,如上图所示。这种触发器的设计易于理解,但现实中常用的触发器要比这个复杂。

下面是锁存器和触发器的的标准符号:

截屏2022-03-21 上午11.05.47.png

其中 a 是一个锁存器,当时钟信号为 1 时,可以改变其状态,与之相反,b 的时钟信号通常为 1,只在它的电平降为 0 时,才可以保存 D 上的信号。c 和 d 是触发器,c 在时钟信号的上升沿(从 0 改变为 1)改变,d 在时钟信号的下降沿(从 1 改变为 0)改变。很多,但也不是所有的锁存器和触发器也可输出 Q\overline{Q} ,有些还有另外两个输入管脚:SET 或 PRESET,用来强制 Q=1,RESET 或 CLEAR 用来强制 Q=0。

寄存器及内存组成

多个触发器可组合在一起,构成寄存器,来保存超过 1 位的数据,如下图所示。8 位寄存器设计完成后,我们就可以用它作为模块来构造容量更大的寄存器了。

截屏2022-03-21 上午11.58.21.png

如果只有很少的位数,把触发器并排放置也勉强够用了,当需要实现更大的位数时则常用其他的内存组成方式。

截屏2022-03-21 下午6.31.41.png

这个电路总共有 8 根输入信号线和 3 根输出信号线,输入信号线中有三个数据信号线分别是 I0、I1、I2,中间的两个是地址信号线,还有三个控制信号线:CS(chip select) 为片选信号,RD 用来区分是读还是写操作,OE是输出使能信号。O0、O1、O2是输出信号线。加上电源和地信号,这个 12 位的存储器仅需要 13 个信号,而上面我们用到的 8 位寄存器需要 20 个信号,原因是这个 12 位存储器共享了输出管脚。减少了管脚数量的同时,更重要的是这种方案可以很方便地扩展成大容量的内存系统。

我们设计的这个电路中,三个或门的输出仅和三个数据输出线相连,但这样做有时也会出问题。特别是,我们设计的输入数据和输出数据用的信号线是不一样的,但在实际的内存芯片中,输入数据和输出数据使用的是同样的管脚。如果我们简单地将或门连接到输出数据线上,芯片将输出数据,也就是说,在对内存进行写操作时,使输出线上的数据成为选定字中存放的值,这样会干扰输入数据。因此,就急需一种办法,在读操作时将或门和输出数据相连,但在写操作时将他们完全断开。

办法在上述的电路图中已经给出了,就是用非反向缓冲器(noinverting buffer)与输出信号线连接。它有一个数据输入、一个数据输出和一个控制信号。当控制信号为高时,该缓冲器就像一根导线,否则就像一根断开的导线。

截屏2022-03-21 下午7.00.00.png

此外还有反向缓冲器(inverting buffer)。这两种缓冲器都是三态器件(tri-state device),因为它可以输出 0、1 和非0非1三种状态。缓冲器也可以对信号进行放大。

另外内存芯片还有其他的寻址方式。更大容量的内存通常采用 n*n 矩阵的方式,通过行地址和列地址进行寻址。

截屏2022-03-22 下午12.25.45.png

其中 R0、R1 是行地址,C0 是列地址,整个电路由 1 位存储单元组成 2*4 的矩阵,组成总共 8 位的存储。可以看到管脚数变的更少了,我们可以拿这个电路再组成一个 4 位宽度内存字的内存。

截屏2022-03-22 下午2.53.01.png

但随着内存字的宽度从 8 位增长到 32 位甚至更宽,宽度为 1 位的芯片使用起来就很不方便,为了使用 8*1 位的芯片构造一个宽 32 位的内存系统就需要并行用 32 块芯片,最小内存容量为 32 K,而经上述 4*3 位拓展的 4*4 位内存芯片只需要并行 8 块芯片,最小内存容量为 16 K。为避免在一个内存系统中就要采用 32 块芯片,很多内存厂商现在都推出了 4、8、16 位字宽的系列芯片。

好了,基本数字电路就先了解到这里,我把文中出现的用 logisim 仿真的电路图上传到了百度云,大家可以下载下来进行参考阅读。~链接在这里(提取码: 2vib)~


参考链接:
1.计算机组成:结构化方法
2.10分钟速成课:计算机科学