3.7 选择
计算机中对信息进行选择是一个非常重要的功能,不仅用于系统部件之间的通信,而且也用于系统部件的内部运作。执行选择的电路通常由一组供选择的输入、一个单独的输出以及一组决定选择的控制输入线组成。首先,我们讨论用多路复用器来进行选择,然后我们简略地看一下用三态驱动器构成的选择电路。
3.7.1 多路复用器
多路复用器是一个组合电路,它可以从多条输入中选择一个输入,并将信息直接传输到输出。选择哪一条输入线由一组输入变量控制,它们被称为选择输入(selection input)。
通常,有2n条输入线和n个选择输入,选择输入的位组合决定选择哪条输入线。我们从n=1的2-1多路复用器开始。这个函数有两个信息输入I0和I1,一个单独的选择输入S,电路的真值表如表3-7所示。分析真值表可知,如果选择输入S=0,多路复用器输出为I0的值;如果选择输入S=1,多路复用器输出I1的值。这样,S不是选择输入I0就是输入I1到输出Y。通过这些讨论,我们可以看出,2-1多路复用器输出Y的方程式:
通过使用三变量的卡诺图可以得到同样的等式。如图3-24a所示,实现这个等式的电路可以展开为一个1-2译码器、两个使能电路和一个二输入或门。表示2-1多路复用器的常用符号如图3-24b所示,这个符号中有一个梯形,梯形中较长的平行边上有2n个信息输入,较短的平行边表示输出,输出是2n输入中的某一个。
假设我们希望设计一个4-1多路复用器。在这种情况下,函数Y由4个输入I0、I1、I2、I3和两个选择输入S1与S0决定。将I0至I3的值填入表中的Y列,我们可以得到这个多路复用器的紧凑真值表,如表3-8所示。在这个表格中,信息变量不出现在表的输入列,而是出现在表的输出列,每一行表示原真值表的多行。在表3-8中,行00I0表示所有(S1,S0)=00的行,对于I0=1有Y=1,对于I0=0有Y=0。因为有6个变量,而且只有S1和S0是固定的,因此这个单独的行代表完整真值表对应的16行。根据这个表,我们可以写出Y的等式为
Y=S1S0I0+S1S0I1+S1S0I2+S1S0I3
如果要直接实现这个方程,则需要两个反相器、四个三输入的与门、一个四输入或门,门输入成本为18。也可以通过使用与项因子的方法实现这个函数
如图3-25所示,这种实现方法需要把一个2-4译码器、四个用作使能电路的与门和一个四输入或门组合在一起。我们将与门和或门的组合看作是一个m×2与或门,其中m表示与门的数量,2表示与门输入的数量。这个电路的门输入成本为22,开销变大了。然而,它却提供了通过扩展来构造大型n-2n多路复用器的基本结构。
多路复用器也称为数据选择器(data selector),因为它从许多信息输入中选出一个并将这个二进制信息送到输出线。“多路复用器”也被简写为“MUX”。
将输入向量的位数增加到n位,多路复用器就得以扩展。这种扩展基于图3-24a所示的电路结构,由一个译码器、一个使能电路和一个或门组成。例3-10和例3-11讲解了多路复用器的设计过程。
例3-10 64-1多路复用器
设计一个n=6的多路复用器,这需要一个如图3-15所示的6-64译码器和1个64×2的与或门,最终的结构如图3-26所示,它的门输入成本为182+128+64=374。
与此不同,如果译码器和使能电路用反相器和七输入与门来代替,那么门输入成本将为4+448+64=518。对于这样一个一位的多路复用器,将产生Di的与门和被Di驱动的与门合并成一个单独的三输入与门,i从0到63,这样可将门输入成本减少到310。对于多位的多路复用器,则不能进行这样的合并。因此,几乎在所有的情况下,原始结构的门输出成本较少。例3-11是多位多路复用器的扩展。
■
例3-11 四重4-1多路复用器
设计一个四重4-1多路复用器,它有两个选择输入,并且每个输入信息不是原来的一位,而是一个四位的向量。因为输入信息是一个向量,所以输出Y也变成一个四元向量。实现这个多路复用器需要一个如图3-13所示的2-4译码器和4个4×2与或门。最终的结构如图3-27所示,它的门输入成本为10+32+16=58。与此不同,如果4个四输入多路复用器由4个三输入门并排放置来实现,则门输入成本为76。所以,通过共用译码器,我们减少了门输入成本。
接下来的几个例子说明了使用VHDL和Verilog语言描述多路复用器的行为,以此作为在第2章每一种语言首次介绍的结构和数据流建模方式的补充。
例3-12 4-1多路复用器的VHDL模型
在图3-28中,显示了根据图3-25编写的4-1多路复用器的结构化描述。解释了两个在第2章介绍的VHDL的概念:std_logic_vector和另一种端口映射方法。
■
在图3-29的结构体中,我们使用when-else语句而不是根据电路结构得到的表达式来描述多路复用器。这个语句是表3-8给出的功能表的一种表示方法。当S取一个特定的二进制值时,将所选的输入I(i)赋给输出Y。当S的值为00时,将I(0)的值赋给Y,否则执行else后面的语句;当S为01时,将I(1)的值赋给Y,如此反复。对于标准逻辑类型,每位有9种不同的取值。因而S有81种可能的取值,但是在这里我们仅指定其中4种取值所对应的情况。为了明确其余77种取值所对应的Y,在最后的else后面对Y赋X(未知),即如果S取值为这77种中的任何一个,Y的值为X。不过这种输出值仅在仿真中出现,因为在实际电路中Y的值总是为0或1。
图3-30提供了利用with-select实现4-1多路复用器的另一种方法。在这个表达式中,关键词with与select之间的信号值用于决策。由该信号的值来选择赋值表达式,信号的每个值跟在关键词when后面,用逗号分开。在这个实例中,S是一个信号,它的取值决定了分配给Y的值。当S="00"时,I(0)赋给Y;当S="01"时,I(1)分配给Y;等等。当S的取值为others时,Y的值为'X'(未知),这里的others表示没被指定的其他77种逻辑组合。
上述的这两个模型说明了在第2章阐释的when-else与with-select之间的不同:when-else允许用多个不同的信号来决定赋值,而with-select仅允许单一的信号。例如,如图3-16中的多路分配器,第一个when将输入EN作为条件,而后面的when用S作为条件。相反,with-select仅允许一个单一的布尔条件(例如,要么EN要么S,但不允许两者都作为条件)。另外,对于典型的综合工具,when-else语句将综合出一个较复杂的逻辑结构,因为每个判定不仅取决于当前正在评估的条件,还取决于先前所有的判定。由于综合出来的结构考虑到了这一优先顺序,所以电路包含了4个2-1多路复用器而不是4×2的与或门结构。而with-select与之相反,判定之间不存在直接的依赖关系。故由with-select语句综合出的是一个译码器和4×2的与或门结构。
例3-13 4-1多路复用器的Verilog模型
在图3-31中,根据图3-25编写的4-1多路复用器的结构化描述,解释了一个在第2章介绍的Verilog的概念—向量(vector)。一组线被指定为多位向量,而不是指定每一个线网为一个单独的位。每根单独的线可以使用向量的名称和这根线在向量范围内的标号来访问。
■
图3-32显示了一个通过使用Y的布尔表达式来描述多路复用器的Verilog数据流模型。这个等式是积之和的形式,用&表示与运算,|表示或运算。向量S和I的位用作它的变量。
图3-33中的Verilog模型采用二进制组合条件运算符实现类似表3-8的功能。如果括号内的逻辑值为真,则冒号“:”之前的值赋给独立变量Y。如果这个逻辑值为假,则将冒号“:”之后的值赋给Y。假设我们考虑条件s==2'b00,==为逻辑等于的运算符。如第2章介绍的,2'b00是Verilog中常量的表示形式,代表着一个值为00的二进制常量。因此当向量S等于00时,这个表达式为真,否则为假。如果表达式为真,则将I[0]分配给Y。如果表达式为假,则继续判断接下来的表达式,如此反复。在此,一个条件被判断,必须是其前面所有的条件都为假才行。如果没有一个条件为真,那么就将默认值1'bx(未知数)赋给Y。
Verilog数据流描述的最后一种形式如图3-34所示。它基于条件操作来形成决策树,这样的决策树对应于因数分解形式的布尔表达式。在这里,如果S[1]为1,那么由S[0]决定是将I[3]还是I[2]赋值给Y。如果S[1]为0,那么S[0]的值将决定是将I[1]还是I[0]赋值给Y。对于一个有规律的结构,例如多路复用器,这种基于两路(或两个二进制数)判定的方法给出了一个简单的数据流描述。
■
例3-14 采用多路复用器选择安全系统中的传感器信号
问题:一个带有15个传感器的家庭安全系统,用来检测打开的门和窗户。当窗户或门关闭时,每个传感器输出一个数字信号0,而当窗户或门打开时,传感器输出一个数字信号1。控制这个安全系统的是一个微控制器,它有8个输入/输出位,每一位都可以由程序控制而作为输入或输出。设计一个逻辑电路,通过将传感器的输出与微处理器编程为输入的输入/输出端相连接,来反复检测这15个传感器的值。可供使用的器件包括下面几种多路复用器:1)单8-1多路复用器,2)双4-1多路复用器,3)四重2-1多路复用器。每种器件的使用数量没有限制,但设计原则则是使用最少的多路复用器,最少的微控制器输入/输出端口。微控制器的输入/输出端口为输出时,可以用来控制多路复用器的选择输入。
解决办法:某些传感器可以与多路复用器的输入相连接,而某些传感器可直接与微控制器的输入端相连接。一种可能耗用多路复用器最少的解决方法是,将两个8-1多路复用器分别与微控制器的输入端相连接。这两个多路复用器处理16个传感器信号,同时需要微控制器的三个输出作为选择输入。因为只有15个传感器输出,多路复用器未使用的第16个输入可以连接0。微控制器输入/输出端口的使用个数为3+2=5。使用其他任何类型的多路复用器将会增加微控制器输入端的使用个数,同时会减少微控制器输出端的使用个数,但输入端增加的个数通常大于输出端减少的个数。所以,就微控制器输入/输出端口的使用数目来说,上述解决办法是最佳的。 ■
3.7.2 基于多路复用器的组合电路
在本节的前面,我们学习了将一个译码器和一个m×2与或门组合在一起,实现一个多路复用器。多路复用器的译码器产生选择输入的最小项,与或门提供使能电路,以判断最小项是否和或门“连接”,使能用信号输入(Ii)作为使能信息。如果Ii输入为1,则最小项mi和或门相连接;如果Ii输入为0,则最小项mi由0来代替。将I输入的值固定,就可以用一个有n个选择输入、2n个数据输入的多路复用器来实现一个有n个变量的布尔函数,其中对于每一个最小项有一个数据输入。进一步来说,一个m位输出函数可以通过将一个m位多路复用器的m位信息向量的值固定来实现,如例3-15所述。
例3-15 用多路复用器实现一个1位二进制加法器
表3-4所示的是1位二进制加法器的真值表,其中S和C的值可以通过固定一个多路复用器的信息输入的值得到。因为有3个选择输入和总共8个最小项,所以我们需要一个双8-1多路复用器来实现两个输出S和C。按照真值表来实现的情况如图3-35所示,其中每一对值,如(I1,1,I1,0)上的值(0,1),都可以直接从真值表最后两列的相关行中得到。 ■
实现一个n变量布尔函数的一种更为有效的方法是,使用一个只有n―1个选择输入的多路复用器。函数前n―1个变量连接到多路复用器的选择输入,余下的变量用作信息输入。如果最后一个变量为Z,则这个多路复用器的每一个数据输入可以是Z、Z、1或者0,该函数可以通过将表3-1所示的4个基本函数附加到多路复用器的信息输入端来实现。下面的例3-16演示了这一过程。
例3-16 另一种用多路复用器实现1位二进制加法器的方法
如图3-36所示,该函数可以用一个双4-1多路复用器来实现,我们通过和S来阐述其设计过程。两个变量X和Y按这样的顺序加载到选择线上:X连接到S1输入,Y连接到S0输入。数据输入线的值由函数的真值表决定。当(X,Y)=00时,输出S等于Z,因为当Z=0时S=0,而当Z=1时S=1,这要求变量Z接到信息输入I00。多路复用器的操作过程是这样的:当(X,Y)=00时,输入信息I00通过一条路径到输出,使S等于Z。用类似的方法,当(X,Y)的值分别为01、10和11时,我们可以通过S的值来确定输入到I10、I20和I30的值。使用相似的方法同样可以确定输入I01、I11、I21和I31的值。 ■
用一个有n-1个选择输入和2n-1个数据输入的多路复用器,来实现任何n变量布尔函数的一般方法与上例方法一致。首先列出布尔函数的真值表,表中前n-1个变量加载到多路复用器的选择输入。对于选择变量的每一个组合,我们将输出看作最后那个变量的函数,其值为0、1、变量或变量的非,因此可以将这些值加载到相应的数据输入。这个过程如例3-17所示。
例3-17 用多路复用器实现四变量的函数
作为第二个例子,我们考虑实现下面的布尔函数:
F(A, B, C, D)=m(1, 3, 4, 11, 12, 13, 14, 15)
这个函数使用一个8×1多路复用器来实现的情况如图3-37所示。为了得到正确的结果,真值表中的变量必须与选择输入端S2、S1和S0相连接(按照它们在表中所列的顺序)(即A与S2相连,B与S1相连,C与S0相连)。数据输入的值由真值表决定,信息输入线上的数由A、B和C的二进制组合决定。例如,当(A,B,C)=101时,通过真值表得知F=D,所以输入变量D加载到信息输入I5。二进制常数0和1对应于两个固定的信号值。我们在3.6节曾提到,这些固定的值在逻辑图中就像图3-7那样可以用地线和电源符号来代替。
下面的例子比较了利用逻辑门、译码器或多路复用器来实现一个组合电路的情况。
例3-18 设计一个将BCD码转换成7段码的译码器
功能描述:数字显示装置普遍存在于消费类电子产品中,例如闹钟经常使用数码管(LED)来显示时间。显示装置中每一个数字由一个7段数码管来显示,每一段可以用一个数字信号来点亮。一个BCD码到7段码的译码器,是一个输入为十进制数字的BCD码,输出可以驱动数码管显示此十进制数字的组合电路。显示中,译码器的7个输出(a、b、c、d、e、f、g)选择对应的段,如图3-38a所示。一组十进制数字的表现形式如图3-38b所示。BCD码到7段码的译码器,对BCD码数字有4个输入A、B、C和D,并有a~g 7个输出来控制各个段。
■
形式化:该组合电路的真值表如表3-9所示。根据图3-38b,每个BCD码数字点亮数码管中对应的段。例如,BCD码0011对应十进制的3,数码管的a、b、c、d和g段被点亮。真值表中约定逻辑1信号点亮段,逻辑0信号熄灭段。但有些7段数码管显示方式则恰好相反,它们由逻辑0信号点亮。对于这种显示方式,7个输出必须求反。从1010到1111的6个二进制组合在BCD码中没有意义。在前面的例子中,我们定义这些组合为无关项。如果这里我们也这样定义,那么这种设计对于那些组合很可能会产生一些任意的、无意义的显示。既然这些组合不会出现,我们就可以用这种方法来减少转换器的复杂度。一种安全的做法是,当任意一个未用的输入组合出现时,灭掉所有的段,以防止数码管胡乱显示,但这会增加转换器的复杂性。要做到这一点,需要将最小项10到15的方格标记为0。
优化:为了使用逻辑门实现函数,真值表中的信息可以转换成7个卡诺图,从图中我们可以得到初步优化了的输出函数。作为练习,大家可以尝试自己来画这7个函数的卡诺图。一种7个函数简化后的布尔函数形式可能如下所示:
单独实现这7个函数需要27个与门和7个或门。然而,通过共用不同输出表达式中的6个乘积项,可以将与门的数量减少到14,这样就大大节省了门输入成本。例如,乘积项BCD在a、c、d和e中都存在,所以产生这个乘积项的与门可以直接和这4个函数的或门的输入连接。对于这样的函数,我们不用两级电路优化,也不共用与门,使用多级优化也许能使门输入成本更低。
一般而言,通过共用输出函数中的公共项,可以减少多输出组合电路所使用的门的数量。输出函数的卡诺图可以帮助我们找出这些公共项,方法是从两个或多个卡诺图中找出相同的蕴涵项。有些公共项并不一定是某个函数的主蕴涵项,设计者必须发挥一定的创造力,合并卡诺图中的方格从而获得公共项。采用一个程序来进行多输出函数的简化可以使这项工作变得更有条理。主蕴涵项的定义不仅只对单个函数而言,同时也适用于输出函数所有可能的组合情况。获取这些主蕴涵项的有效方法,是通过对输出函数所有的非空子集做与运算,并找出结果中的主蕴涵项。利用这个完整的主蕴涵项集合,我们可以通过一个形式化的选择过程来获得最佳的两级多输出电路。这个过程在逻辑优化软件中有多种实现形式,我们用它来获得表达式。
这个电路也可以通过使用一个译码器或多路复用器,而不仅仅是用逻辑门来实现。7个或门(每一个用于显示装置的一个功能段)再加上一个4-16译码器就足够了。但实践中使用超过4个输入的或门是不实际的,所以需要更多的门。加载到这7个或门的输入,其最小项之和形式是:
如果用多路复用器来实现,则需要7个8-1多路复用器,每一个对应着显示一段所需的功能。另外一种办法是使用一个7位宽的8-1多路复用器,将选择输入S2连接到A,S1连接到B,S0连接到C,那么7个多路复用器的数据输入将如表3-10所示。 ■