组合逻辑模块

小孩子 我们都是小青蛙 2018-06-03

本系列主要是《数字设计和计算机体系结构》和一些相关书籍的读书笔记,并没有专门为读者的阅读体验认真做设计,敬请谅解(时间不多)。


本篇是在数字电路的基础上抽象出一些我们常用的模块,这些模块我们之后就不会再详细分析它们的设计细节,直接使用就好了(抽象的好处:不用了解过多细节)。还会介绍一些关于元件的延迟和毛刺的东东。

组合电路和时序电路的区别

前边说一个电路需要有功能规范和时序规范,功能规范是指针对某个输入应该有什么样的输出,时许规范是指明什么时候输出根据输入的改变而改变。组合电路没有时序规范,只要某个输入改变,输出就会跟着改变,我们之前说的各种基本的逻辑门都是组合电路。它有下边几个特征:

  • 组合电路的每一个电路元件本身都是组合电路。

  • 每个电路节点的输出都是另一个电路的输入。

  • 电路不包含回路。

对于组合电路,我们只要描述功能规范就可以了,也就是什么样的输入对应什么样的输出。

常用的组合电路

半加器

考虑一个问题,怎么让电路帮我们做加法呢?我们现在已经知道了可以用高电平代表1,低电平代表0,而且已经知道了一堆基本的逻辑门,怎么利用现有的这些资源来设计一个帮我们做加法的电路?首先分析一下二进制加法(以一位二进制举例):

+01
001
1110

因为结果中可能有进位,所以最后的结果可能包含2个二进制位,我们把上边结果中只有一位前边也补个0:

+01
00001
10110

我们把结果中后边的那个二进制位叫做加法位,前边的那个位叫做进位。很显然,为了得到最后的结果,我们需要设计的电路里必须有两个输入,分别代表两个加数;电路应该包含两个输出,分别代表加法位和进位。所以电路看起来就是这样:

我们现在的任务就是把这个黑盒子用基本的逻辑门描述出来。现在再回过头看我们的加法规则,因为有两个输出,我们分开来分析:

  • 加法位的输出

    单纯的看一下两个二进制位相加后加法位的情况:

    +01
    001
    110

    看这个表是个什么情况?这不就是异或门的输出么,所以我们在这里搞个异或门电路就可以产生加法位的输出了:


  • 进位的输出

    单纯的看一下两个二进制位相加后加法位的情况:

    +01
    000
    101

    这个表不就是与门的输出么,所以我们搞个与门电路就可以产生进位的输出了:

所以这两个电路合起来的样子就是这样的(我们现在把黑框框里的电路补全了):

利用这个电路,我们就可以根据输入A、B的值,来查看它们的进位输出和加法输出了。现在既然我们知道它是怎么组成的了,以后我们会频繁的用到这个东东,所以我们用个简单的方式把它画下来:

因为这个电路只能进行单个二进制位之间的加法,不能处理有进位的加法,所以称之为半加器

全加器

我们平时做的加法一般都不是单个二进制位之间的加法,比方说这样:

    10001
+   11010

这样的加法中每个加数有多个二进制位,只有最后一位相加才能用到半加器,对于非最后一位的二进制位相加,可能需要使用到进位,所以我们的输入也需要加一个进位,就像这样:


现在分析一下这个黑盒该怎么实现,需要先想想我们现实中处理有进位输入的二进制加法是怎么算的:

  1. 先对A、B两个二进制位做加法运算,得到加法位和进位

  2. 再把上一步算出来的加法位和输入的进位相加,得到新的加法位就是最终的加法位,由于这两次加法的进位不可能同时为1(为啥?你想想),只要这两次加法里的进位中有1出现,那么最终的进位就是1。

根据这两个步骤我们可以画出电路图(复用上边的半加器):

这玩意就是所谓的全加器,这玩意儿以后常用,为了不用每次都画这么多东西,我们把图简化一下:

选择器

有时候对于多个输入,我们只想选取某个或者某几个作为输出,这时候就要用到复用器了,比方说这个黑盒子电路:

这个电路有3个输入:D0、D1、S,有一个输出Y,我们想要的结果是:

  • 当S=0 时,Y=D0

  • 当S=1 时,Y=D1

对于输入D0和D1来说,怎么使其中的一个输入有效,另一个无效呢? 我们想到在逻辑或里边,如果某个输入为0,那么输出就取决于另一个输入的值,那么我们可以想办法让某个输入为0,只保留另一个输入的原始值,最后让这两个输入取或关系就好:

此电路就符合我们上述要求,它也叫做2-1选择器,意思从2个输入中选择一个作为输出。我们把这个2-1选择器画个简图就是这样:

当然,我们还可以定义更多个输入的选择器,比方说从4个输入里挑一个输出,那就是4-1选择器,可以这么表示:

这个图的意思是:

  • 当S0=0,S1=0时,输出Y=D0

  • 当S0=0,S1=1时,输出Y=D1

  • 当S0=1,S1=0时,输出Y=D2

  • 当S0=1,S1=1时,输出Y=D3

译码器

1个二进制位可以表示0和1两个数,2个二进制位可以表示00、01、10、11这4个数,依此类推,3位二进制数可以表示8个数,4位二进制数可以表示16个数。我们把输入当作二进制的位数,输出当作这几个二进制位可以表示的数,以2位二进制数为例,输入输出的黑盒如下:

我们期望的效果是:

  • 当A0=0,A1=0时,让Y0为1,其余的输出都为0。

  • 当A0=0,A1=1时,让Y1为1,其余的输出都为0。

  • 当A0=1,A1=0时,让Y2为1,其余的输出都为0。

  • 当A0=1,A1=1时,让Y3为1,其余的输出都为0。

实现一下这个电路:

这个电路十分有用,后边的存储器寻址就是用它做的。

电路延迟

我们前边说了很多电路,那电平信号是以什么速度在电路中传播的呢?我也不知道,书上也没写,但是再快也快不过光速吧,理想中的情况是一旦我们改变了输入,那输出应该立即改变,但是很不幸,这个假设不成立,尤其是当电平信号经过某个元件的时候,输入信号和输出信号之间有一个明显的延迟,这个延迟主要是因为元件中的电容充放电的原因造成的,不同元件可能有不同的延迟,具体延迟多少是一个物理层面的事情,不过元件的生产厂商会给我们把延迟的时间标出来。以缓冲器为例:

当我们改变输入A的电平时,输出Y改变的延迟的示意图如下:


还有一个需要注意的点是,在元件的输出改变后,它可能有一段时间处于不稳定状态,过了这段时间才会真正的稳定下来,这是元器件的物理属性,我们也没办法呀,所以一个元器件从输入的改变到真正的输出改变后稳定下来要经过两个阶段,不过这个延迟是非常非常小的,使用的单位已经是皮秒了。示意图如下:

其中tcd称为最小延迟(contamination delay),tpd称为传播延迟(propagation delay)。tcd表明从输入发生变化后输出开始发生变化的最短时间,tpd表明从输入发生变化后到输出称为最终值的最长时间。至于为什么会产生这两个延迟是元器件的物理属性,元器件生产商会在元器件说明书上标明它们的最小延迟和传播延迟,我们知道某个元件的最小延迟和传播延迟就行了,它们的产生机制需要我们称为物理学家后再继续研究(抽象的好处,我们不必要关心过多的细节)。

毛刺

看下边这个电路图:


假设现在的状态是:A=0,B=1,C=1,所以输出Y=1。

当B从1变成0时,B的改变会影响两条线路(飘红的线路1和飘绿的线路2),如图:

但是线路1上的元器件比线路2上的多一些,所以它的传播延迟更大一些,所以B的变化先通过线路2传播到输出Y,所以Y的值先从1变为0,随后很快的时间,B的变换通过线路1传播到Y,所以Y的值又从0变为1,这个过程虽然很短暂,但是还是会出现Y的短暂波动,但是随着时间推移,Y的值便会稳定在1不变,这个短暂的波动我们称之为毛刺。在组合电路中毛刺经常出现,但是只要时间足够,最终的输出还是稳定的。



    觉得不错,分享给更多人看到
    我们都是小青蛙 热门文章:

    java并发编程之原子性操作    阅读/点赞 : 0/0

    我们都是小青蛙,呱呱呱呱呱    阅读/点赞 : 0/0

    活跃性(死锁、饥饿、活锁)    阅读/点赞 : 0/0

    指令重排序    阅读/点赞 : 0/0

    InnoDB的Buffer Pool简介    阅读/点赞 : 0/0

    一些比较重要的数字电路模块    阅读/点赞 : 0/0

    抽象的艺术    阅读/点赞 : 0/0

    内存可见性    阅读/点赞 : 0/0

    存储程序(二)之存储函数简介    阅读/点赞 : 0/0

    线程间通信(下)    阅读/点赞 : 0/0

    我们都是小青蛙 微信二维码

    我们都是小青蛙 微信二维码