目录
你是否想过,为什么内存芯片使用固定的"地址硬编码"来访问数据,而不是像外部总线那样采用灵活的"三态门"机制?这个看似微小的选择背后,实则蕴含着数字电路设计的终极权衡。本文将带你穿透表面功能,深入数据选择器、加法器、数值比较器等核心模块的设计本质,揭示"高性能"、"低成本"与"高灵活性"之间的艰难抉择。我们还将直面电路设计中的幽灵------"竞争-冒险"现象,并探讨如何从结构上将其根除。理解这些,你才能从电路的使用者,转变为真正的设计者。
一、数据选择器
(1)为什么用地址+数据的硬编码对应,而不用三态输出门?
有时候我们会有很多个输入,但是我们想在同一时刻只能取出一个端口输入的数据。就好像一个单刀多掷开关,每次只能选中一条通路。
诶,这个描述是不是有点像前面学习三态输出门时候的定义啊,多种外设(键盘、鼠标等)的输出连接到一根总线上交给CPU计算处理,通过严格的控制可以保证同一时刻只能有一个外设被导通,其余的都呈现高阻态而没有信号进入总线。
然而实际中却并不会这样做,下图是三态输出门的原理图,可以发现他的实现需要3个非门(CMOS反相器)、1个与非门、一个或非门、一个CMOS反相器。也就是总共8+4+4=16个MOS管,成本还是比较高的。且这仅仅是一个三态输出门的成本,每一个输出端都需要一个三态门。最后还需要复杂的逻辑电路来严格控制三态输出门的状态,防止同一时刻有多个导通,造成数据的混乱。这一系列问题导致了实际中不可能这么做。

而如果我们换一种思路,不要三态输出门的灵活性,直接把每个数据按照地址+数据的方式组合,就能成一种硬编码,每个地址对应一位二进制数据。
举个例子,现在我们有2个不同轨道的数据想要选择输出。

可以发现,一个2端口的数据选择器,用地址+数据的方式硬编码,仅仅需要2个与门+1个非门,总的也不过是12个MOS管,相比三态输出门的成本大大降低。
当然我们上面是用常规做法对真值表进行一步步化简得到的最简逻辑表达式。但更简单的做法是直接从功能特点出发:一共有两个数据端口,则需要两个地址,于是地址可以用0、1来表示。即图中的A,而BC分别代表一个数据通路。所以当A=0时,0地址被选中,输出B的数据;当A=1时,1地址被选中,输出C的数据。直接就能写出Y=AB'+AC,更加简便。
(2)三态门的灵活性与地址硬编码的高性能对比
我们说内存这种地址对应一个输入端的数据,是一种硬编码行为。即只要该芯片设计好了,每一个地址都一定会有对应的数据线,不可能说选中001地址却输出了002地址的数据。他虽然比较死板固定,但是他使用到的MOS管数量极少,既降低了生产成本,还大大提高了运算速率(因为每一个MOS管都有导通时间,尽管很微小,但是叠在一起就特别影响性能)
内存并不需要灵活性,他只需要死板地把数据从CPU给到的地址取出即可。所以这种硬编码行为是最为合适的。
而三态输出门使用场景与之不同,他常常用在CPU和各种外设的连接上,因为每个人的需求不同,可能挂载到总线上的设备都完全不同,如果仍然使用硬编码则不够灵活。使用总线的方式只需要提前留出总线的接口,就能让人们方便地把各种外设扩展上去。
虽然理论上来说同样可以硬编码的,只需要让各种设备的地址固定死,每种设备自觉的连接到对应地址上(当然仍然是映射到内存中)即可,而且这样性能更好。但随着计算机的发展,各种多样的外设层出不穷,计算机厂商不可能把任意外设都兼容到地址上,即使能兼容他也需要庞大的地址线。
现代计算机采取的就是三态门这种灵活编码。当你插入一个外设到总线上时,操作系统会遍历该总线,询问每一个设备需要多大的地址空间,并动态分配地址给其使用**(现代计算机采用内存映射IO,即把各种外设需要的地址空间映射到内存中,这样CPU在访问外设时就如同访问内存)** 。我们称为PCI协议。
(3)74HC153数据选择器的级联
学习每一种外设我们都需要考虑一下是否能级联成为功能更复杂的模块。经过上面的分析,我们知道了数据选择器、三态输出门的使用场景不同。而工程师们已经将4端口情况封装好了。

74HC153是一款双四选一数据选择器。也就是说他的地址线可以复用,当S2使能时,选择的是D23~D20四个数;而当S1使能时,选择的是D13~D10四个数据。分别从Y2何Y1输出。
当我们想要简单的用作4数据选择器时,只需要让S2使能,然后在A1、A0输入地址,即可从Y2上获取4输入的任何一个了。
而想要级联成8数据选择器时,由于地址线只有两个,所以需要考虑把使能端也作为地址的某一位进行输入。而输出端需要让Y2和Y1分别输出,即可以使用或门。这个还是比较简单的,如下:地址>=4时,A2为1,第一片选择器被选中输出;当地址<4时,A2=0,第二片选择器被使能输出。

(4)使用74HC153芯片来构造逻辑函数
任何一款芯片都可以通过一定控制,来构造最小项/最大项的逻辑函数,从而达到复用的作用。
例如现在有一个3变量的逻辑表达式如下,我们要控制该芯片的端口电平情况写出该逻辑表达式。

值得注意的是:
上篇文章用3-8译码器来构造逻辑函数时,我们还对输出进行了一定控制。但是这里经过分析(地址线同一时刻只会有一个被选中),所以Y2直接输出即可。相当于他内部已经帮我们实现了或门的逻辑。
二、数据分配器
任何元件都存在他的反面逻辑,前面的数据选择器是有多个输入端,但仅仅需要一条支路连接到总线上,而数据分配器则是总线的数据想根据地址输出到不同的分路上。74HC18译码器刚好能实现这一点。
只不过这里我们是采用A2A1A0作为地址选择,把使能端当做数据输入端(使能工作时,译码器会输出0作为真,而没有使能时,译码器会输出1作为假)。当地址选取后,对应的输出端上的电平就呈现和S2使能端一样的特点(这是是把S2当做数据输入端,S1、S3都正常使能)

可以联想到内存中数据的存取过程,就是CPU读取了地址和数据后这样存进去的。而读取则是用数据选择器的反向过程。比较简单,了解一下即可
三、加法器
(1)半加器
加法器分为半加器和全加器。所谓的半加器就是不带进位输入,仅包含进位输出的加法器。而全加器则是都有,可以直接级联使用作为一个完整的计算器。

半加器由于其不完整的进位功能,所以只能用于1位加法,在数字电路中是不合适的,于是有了后面的全加器。
(2)全加器

通过这两个逻辑表达式其实就可以通过门电路的设计实现了。假设我们将其做成了一颗芯片,以后直接对其级联就可以实现多位加法器了。
(3)串行多位全加器
既然全加器可以实现一位的进位加法,那么是不是和人们手算的过程一样,级联到一起就能构造出任意多位的全加器呢?

这种设计方式很简单,但是存在速度慢的问题:因为每一位都是独立计算的,且需要低位的结果输出给高位,这意味着如果位数很多则每颗1位加法器的延迟都会叠加,显著影响效率。
人们将每一位的计算并行化,得到了超前进位全加器。也就是说每一位的加法是同时运算的,但是需要能"预判"进位,所以电路结构十分复杂。以后直接使用74HC283这颗并行全加器即可。他是两个4位数的加法器。

四、数值比较器
(1)1位数值比较器
从小规模组合逻辑电路的思路来说,设计1位数值比较器应该是从其逻辑关系、真值表出发。
我的思路是有A、B两个输入端,然后由于输出要有3种情况则需要2位。如下:

但是这样有个问题,输出端无法直接看到结果,需要设计者定义,而且观察者看的时候也比较麻烦。为了解决它,需要在输出位置级联一块译码器将2位二进制数转成三输出的直观结果。
那为什么不直接将输出定义成三种情况呢?即输出为3位数据,每一位代表着>、<、==
我们可以直接从逻辑关系写出逻辑表达式,不再利用真值表一步步推导(当然推导仍然是基础,只不过比较麻烦)

(2)4位数值比较器
数值比较应当从高位开始,如果高位相等才需要往下判断。我们根据这种特点,直接写出其逻辑表达式,以A>B为例:

其中最后一行是用来做级联的,当目前4位都相等时候,需要比较更低位,于是可以直接把低位的比较结果输入到这里的I端口。
类似的,分别写出A<B;A==B的逻辑表达式。然后人们将其封装成了一颗芯片---74HC85。以后可以通过该芯片作为基础,创造出无限的可能。

(3)数值比较器的级联
数值比较器的级联十分简单。唯一需要注意的就是要把低位的输出接到高位的附加端,使得满足附加端为低位比较结果。
五、竞争-冒险现象
(1)竞争、冒险的定义
**竞争指的是:**单变量的两个相反信号经过不同路径输入到某个门电路时,由于前级的输入多多少收都有一点延时,所以A和A'并不是同时到达该门电路的,对于该门电路的输出就产生了毛刺。
**而冒险则是:**输出端由于各种原因(比如竞争、外界电磁场干扰等)产生了一个毛刺。
**竞争-冒险是:**特指由竞争引起的冒险。

(2)竞争-冒险的检查方法
我们说竞争是单变量的正反输出。
于是只要逻辑函数中包含A+A';A*A'这种式子,就一定存在竞争现象。当然可能一个式子没有这么直白,比如AB+A'C看似没有竞争,但当B=C=1时,就恢复成了原本简单的竞争问题。所以想要用公式法判断必须考虑各种其他变量的配合情况。
为了简化这种方式,同样可以使用卡诺图判定法。当你在卡诺图画的圈有相切时,则必定有竞争现象。首先我们从公式法考虑,出现竞争的条件是A+A',那么在卡诺图中必定有挨在一起的节点,即只有A和A'这个位置不同。

(3)竞争-冒险的消除办法
1.从输出端考虑
利用电容的滤波特性过滤掉毛刺。这种方式比较简单,但是集成电路不适合制作大电容、且会造成一定性能下降,往往不会采取这种方式。
2.从输入端考虑
既然是某个端口的两个输入不匹配导致的过渡性问题,那么只要严格保证输入端的同步即可,于是可以考虑给电路加选通脉冲(使能信号是一种脉冲),只有当脉冲到达时,后续电路才能汲取输入端的电平信号,大大降低了毛刺的可能。(这种方式也会在后面的时序逻辑中讲解,通过时序的使能来控制采样时间)
但这种情况只适用于频率较低的情况,一旦频率高了,脉冲信号本身可能都不是很稳定,又何谈精准控制使能呢?
3.从电路结构(逻辑函数表达式)
给电路增加冗余项的角度考虑,以AB+A'C为例。他出现单变量竞争的情况是B=C=1时会导致A+A'进入后面的或门时候产生过渡性问题,而A+A'理论上恒为1,那么我们只需要加上一个在B=C=1时候的1项即可。那么就是B*C本身连接到后面的或门,相当于或门从二输入端变成了一个三输入端的结构。
这样的好处是直接避免了单变量竞争问题,不过会增加一定设计复杂度。但是他解决了滤波电容无法在集成电路中制作、选通脉冲无法应用在高频率信号的问题。所以是芯片设计中最为常见的方式。
(4)思考
其实在刚刚看到竞争-冒险的定义时候,我就特别好奇:为什么他特指单变量情况呢?明明A、B两个不同的变量输入同一个门也会造成过渡性竞争问题。难道这种情况不用处理吗?
经过查阅资料后明确说明:必须得处理!不过他们是通过上述(2)方法解决的,即引入时序选通电路。这种方式只能通过严格的约束压缩延时差,即缩小毛刺的持续时间,无法根本上杜绝毛刺的产生。
但是对于单变量本身可以引入冗余项直接杜绝该问题,同时引入简单的冗余项的成本在集成电路大规模制作中几乎可以忽略,而引入时序选通电路则更为复杂昂贵。
那有人就会问了:A、B这两种信号为什么不和单变量一样引入无关项呢?因为门电路本身就是依靠不同的输入响应不同的输出的,如果你为了处理A、B两个变量的过渡性问题,那么无关项是不是还得用AB本身来实现啊,这就变成了鸡生蛋、蛋生鸡的问题。