首页 > > > 11358 超级玛丽教你看懂 D 触发器
我曾经说过,电子系的本科课程,可以串成一条宏伟的线索,它们从单个电子的运动规律出发,教你一层又一层地搭建出五彩缤纷的硬件、软件与网络世界。当我在大四悟到这一点的时候,是心潮澎湃的。但是,在这条线索上,却有一个关键的环节我一直没搞懂,这是我本科时代的一个遗憾。
这关键的一环,就是「数字电路」课程中的「D 触发器」。「D 触发器」是计算机系统中存储器的基本组成单元。它有「时钟」和「数据」两个输入,功能是这样的:
1. 当时钟的上升沿到来时[1],根据外界输入的数据,改变自身的内部状态;
2. 在其它时候,保持自身的内部状态不变。
「D 触发器」有多种实现方式。有一种实现方式使用了 8 个与非门,下面这篇文章言简意赅地介绍了它的设计思路,十分值得一读:
三郎:计算机数学小书2-D触发器的进化之路但还有一种更加「节省」的实现方式,只用了 6 个与非门,这就是我长久以来没有搞懂的东西。它的电路图长这样:
是不是一看就有一种要晕的感觉呢?我的数字电路课本上,在这个电路图的旁边,用了大约 20 行文字,追踪了信号在电路中传递的过程。如果你静下心来读的话,不一定读不懂,但往往会淹没在细节之中,无法宏观地掌握上述电路的工作原理与设计思路。
上周在刷知乎的时候,我又见到了「D 触发器」这个东西。这让我又想起了本科时代的遗憾,并让我下决心真正弄懂图 1 中的电路。很幸运的是,这次我成功了!这篇文章,就来带你直观地弄懂下面三个问题:
1. 图 1 中的电路,是怎么实现「D 触发器」的功能的?
2. 图 1 中的电路,是怎么设计出来的?
3. 能不能用更少的与非门实现「D 触发器」?
咦?超级玛丽在哪里?别着急,马上就来!
图 1 中的电路之所以看起来乱,是因为「与非门」画起来很笨重:它的所有输入端都必须画在一边,而输出端画在另一边。于是,各个与非门之间的连线,就只好各种拐弯、交叉了。而下面的图 2,用超级玛丽代替与非门,就解开了这一团乱麻:

图中每个红色的超级玛丽(Mario)代表一个与非门,绿色(Luigi)和黄色(Wario)的代表输入数据和时钟。如果从一个玛丽到另一个玛丽之间有箭头,则代表前者是后者的一个输入。读者不妨检验一下,图 1 和图 2 的连接关系是一模一样的。由此也比较容易看出各个玛丽的功能:1、4 号玛丽负责接收输入数据,2、3 号玛丽直接受时钟控制,5、6 号玛丽负责记忆及输出。
玛丽的姿势代表高低电平,但是注意:蹲着的玛丽代表 1,站着的玛丽代表 0。这种设定有点儿绕,不过它可以让与非门的逻辑很符合直觉:如果箭头起点处的玛丽站起来了(输入为 0),则箭头终点处的玛丽必须蹲下(输出为 1),可以看成是前者「压制」住了后者;如果一个玛丽不被任何其他玛丽「压制」,那他就会自动站起来。不难看出,1、2 号,3、4 号,5、6 号玛丽形成了三对「冤家」,每一对中的两个玛丽不可能同时站着。其中,5、6 号这一对「冤家」比较好理解,它们不是你压制我,就是我压制你,可以形成两种稳态,代表两种记忆。至于 1、2 号,3、4 号两对「冤家」有什么用,下文中会见分晓。
现在可以讲解 D 触发器的工作原理了。我们从时钟为 0 的状态开始。此时黄色的玛丽站着,把 2、3 号玛丽都压了下去,使得它们无法对 1、4、5、6 号玛丽施加影响。于是,输入侧的 1、4 号玛丽就与输出侧的 5、6 号玛丽隔绝了,不管输入数据如何变化,5、6 号玛丽都不受影响,保持着之前的状态。而在输入侧,1 号玛丽会与绿色玛丽保持相同的状态,4 号玛丽则相反(如图 3)。
当时钟上升沿来临时,黄色的玛丽就蹲下去了,2、3 号玛丽终于有机会伸伸懒腰了。但它们还受 1、4 号玛丽控制。如果绿色的玛丽站着(输入为 0),则 4 号玛丽会受压制,而 1 号玛丽站起来。此时 2 号玛丽会被 1 号玛丽压制,而 3 号玛丽会因无人压制而站起来。3 号玛丽进一步压制住 6 号玛丽,从而让 5 号玛丽站起来(如图 4)。反之,如果绿色的玛丽蹲着(输入为 1),那么 4 号玛丽就会站着,并把 1、3 号玛丽压制住,2 号玛丽则会没有人压制而站起来。站起来的 2 号玛丽会把 5 号玛丽压制住,于是 6 号玛丽会站起来(如图 5)。总而言之,奇数号玛丽会与绿色的玛丽采取同样的姿势,偶数号的玛丽则相反。这就达到了把输入数据保存到 5 号玛丽的目的。


数据存到 5 号玛丽以后,时钟仍会保持为 1 一段时间。这段时间内输入数据仍可能发生变化,但输出侧不应受其影响。但是黄色的玛丽在这段时间内是蹲着的,失去了黄色玛丽压制的 2、3 号玛丽,如何把输入侧与输出侧隔绝呢?这就要靠 1、2 号以及 3、4 号两对「冤家」了!原来,2 号或 3 号玛丽在时钟上升沿的瞬间站起来后,会立即反过来对 1 号或 4 号玛丽形成压制。如果 3 号玛丽站着,它就会以一己之力压制住 4 号玛丽,让它不再听从绿色玛丽的命令(如图 6)。如果 2 号玛丽站着,它就会把 1、3 号玛丽都压制住。此时,虽然 4 号玛丽还能听从绿色玛丽的命令,但它只能自己玩,无法对其它玛丽造成影响(如图 7)。于是,在时钟保持为 1 的期间,5、6 号玛丽也可以维持记忆。

时钟下降沿来临时,黄色玛丽站起来,把 2、3 号玛丽都压下去,开始一个新的周期。
看懂了 D 触发器精妙的工作原理,下一个问题自然就是:这个电路是怎么设计出来的呢?具体来说,为什么各个玛丽要像图 2 那样布局,它们之间的线要那么连呢?在这一节,我们就从右往左设计 D 触发器的电路。
先看最右边 5、6 号两个玛丽。它们其实组成了一个「SR 锁存器」:
● 当两个输入一个为 0 一个为 1 时写入数据,写入后两个玛丽的状态与输入相反;
● 当两个输入均为 1(即 2、3 号玛丽都蹲下)时,保持状态;
● 当两个输入均为 0(即 2、3 号玛丽都站起)时,两个输出均为 1(即 5、6 号玛丽都蹲下)。
其中第三种情况是没有用的,在 D 触发器里也不会出现。

锁存器存储的内容可以随时由外界输入修改。我们下面要做的事情,就是用时钟把 SR 锁存器的输入端「保护」起来,由时钟来控制什么时候写入,什么时候保持。于是就有了 2、3 号玛丽。

当时钟为 0(黄色玛丽站着)时,2、3 号玛丽均被压制,所以 5、6 号玛丽可以保持状态。当时钟上升沿来临(黄色玛丽蹲下)时,2、3 号玛丽就变成了非门的作用,把输入取反后送给 5、6 号玛丽。于是就知道,2 号玛丽的输入应当就是要存入的数据,而 3 号玛丽的输入应当与之相反。于是就有了 4 号玛丽:

到了现在,还缺的功能就是在时钟为 1(黄色玛丽蹲着,不起作用)时,保护好刚刚存入的数据,不让它受输入影响了。上图中的电路做不到这一点:当黄色玛丽蹲着时,绿色玛丽可以长驱直入地控制所有红色玛丽。为了保护 5、6 号玛丽的状态,就需要 2、3 号玛丽结成一对「冤家」(即组成 SR 锁存器),并向输入侧提供反馈,让输入不至于翻转 2、3 号玛丽的状态。这时我们发现,表示输入数据的绿色玛丽是不可以直接连到 2 号玛丽上的,因为绿色玛丽不受控制,它只要一站起来,就可以轻而易举地让本该站着的 2 号玛丽蹲下。于是就只好再增设一个 1 号玛丽,作为绿色玛丽的傀儡。只要让 4 号玛丽控制 1 号玛丽,1 号玛丽就可以与绿色玛丽亦步亦趋了。

下一步就是要设计 2、3 号玛丽对 1、4 号玛丽的反馈。不妨把四个箭头全部连上,这样 不管是 2 号玛丽还是 3 号玛丽站着,就都可以把 1、4 号玛丽压制得服服帖帖,不再受绿色玛丽影响:

但其实没必要费这么大力气。不难看出,2 号玛丽怕的就是自己站着时,1 号玛丽站起来把自己压下去;同样,3 号玛丽怕的就是自己站着时,4 号玛丽站起来把自己压下去。于是只要 2、3 号玛丽分别控制 1、4 号玛丽就行了(又形成两对「冤家」),中间两个交叉的箭头可以去掉:

最后检查一下电路,发现从 3 号玛丽到 2 号玛丽的连线可以去掉。这是因为,3 号玛丽站着时,1 号玛丽必然也站着,它可以代替 3 号玛丽压制 2 号玛丽。但反过来,2 号玛丽到 3 号玛丽的连线不能去掉,因为 4 号玛丽不能代替 2 号玛丽压制 3 号玛丽 —— 4 号玛丽本身还受绿色玛丽控制呢。

还剩最后一个问题:能不能使用少于 6 个与非门搭出 D 触发器呢?
在上面的设计过程中我们发现,5、6 号玛丽作为记忆的载体,是必不可少的;2、3 号玛丽要保护 5、6 号玛丽的输入,也是必不可少的。那么 1、4 号玛丽能不能去掉呢?首先,它们不能都去掉,因为输入数据不可以直接连到 2、3 号玛丽上。那么去掉一个行不行呢?注意到 1 号玛丽是角色是输入数据的傀儡,而在时钟为 1(黄色玛丽蹲下)时,3 号玛丽的状态也是始终跟 1 号玛丽一致的。既然这样,何不让 3 号玛丽直接作为输入数据的傀儡,去掉 1 号玛丽呢!(当然,要恢复 3 号玛丽对 2 号玛丽的控制)
很不幸,这个电路是有问题的。问题出在时钟上升沿的瞬间:如果输入数据为 0(绿色玛丽站着),那么 4 号玛丽蹲着,当黄色玛丽蹲下时,2、3 号玛丽都不受压制,会争相站起来,不能保证站起来的一定是 3 号玛丽。此时就显示出 1 号玛丽的必要性了:3 号玛丽只能在时钟上升沿之后担任绿色玛丽的傀儡,但在时钟上升沿的瞬间,还是需要 1 号玛丽把输入数据传递给 2 号玛丽的。
由此,我们就说明了六个红色玛丽(与非门)都是必要的。当然,这并不算严格的证明。不过,由五个以内与非门组成的电路种类是很有限的,可以用计算机来枚举。有兴趣的读者不妨自行编程验证,只使用五个以内与非门无法搭建出 D 触发器。
原文作者:;如有侵权,请联系管理员删除。