Los multiplexores son circuitos combinacionales de mediana escala (MSI) con múltiples entradas y una única salida de datos. A su vez poseen de entradas de control capaces de seleccionar una, y sólo una, de las entradas de datos para permitir su transmisión desde la entrada seleccionada hacia dicha salida.

Este artículo demuestra cómo utilizar multiplexores (MUX) y memorias ROM para implementar funciones lógicas como reemplazo a las compuertas tradicionales (AND, OR, NAND, NOR, etcétera).



En el campo de la electrónica el multiplexor se utiliza como dispositivo que puede recibir varias entradas y transmitirlas por un medio de transmisión compartido. En computación se utilizan frecuentemente para implementar el direccionado (por ejemplo dentro de memorias RAM, ROM) y para implementar todo tipo de circuitos combinacionales.

Un multiplexor posee 2n líneas de entrada de datos, una única línea de salida y n entradas de selección. Las entradas de selección indican cuál de las líneas de entrada de datos es la que proporciona el valor a la línea de salida. Cada combinación de las entradas de selección corresponde a una entrada de datos, y la salida final del multiplexor corresponderá al valor de dicha entrada seleccionada.

La siguiente figura demuestra el diagrama junto con la tabla de verdad de un multiplexor:

Cuando se utilizan multiplexores para implementar funciones lógicas, las líneas de selección tienen la capacidad de "eliminar variables" de la ecuación. Para entender este comportamiento, veamos directamente un ejemplo.

Se desea diseñar un circuito para implementar la siguiente función lógica:

f(A,B,C,D) = BC + AC + CD

La cual corresponde con el siguiente mapa de Karnaugh:

Si se quisiera implementar utilizando compuertas NAND empleando lógica mixta, el circuito resultante sería el siguiente:

La idea detrás de una implementación con un MUX consiste en emplear las variables de la función en las líneas de selección, y pasar a la salida el valor correspondiente para cada combinación de variables. Teniendo 4 variables, para esta implementación se necesitaría un MUX 16 a 1 con 4 líneas de selección:

Esta es la solución trivial haciendo "fuerza bruta". Las 16 combinaciones posibles de las variables A, B, C y D en las líneas de selección, habilitan el valor que debe tomar la función para cada una (0 ó 1).

La expresión "fuerza bruta" da a entender que se desperdicia hardware para implementar la solución (un MUX 16 a 1 emplea una gran cantidad de transistores). Es posible lograr implementaciones más eficientes en cantidad de transistores utilizando MUX de menor cantidad de entradas, por ejemplo 4 a 1 (como el de la primera figura).

Con un MUX 4 a 1 sólo se dispone de 2 líneas de selección. Por ende no es posible generar todas las combinaciones de variables posibles para esta función. Sino que se descompone la función original en 4 nuevas funciones llamadas "residuo". La característica de las funciones residuo es que tendrán n variables menos en cada una de sus ecuaciones, por ende tendrán menor complejidad. Siendo n el número de líneas de selección del multiplexor utilizado en el diseño (2n entradas).

Básicamente el multiplexor permite eliminar variables en la ecuación.

Si, por ejemplo, empleamos un MUX 4 a 1 y utilizamos A y B en las líneas de selección, pasamos de implementar f(A,B,C,D) a implementar f{0..3}(C,D). Es decir, en lugar de tener que implementar (con compuertas) una función de 4 variables, ahora tenemos que implementar 4 funciones de sólo 2 variables. La siguiente figura demuestra cómo se divide el mapa de Karnaugh original de 16 combinaciones en 4 mapas de 4 combinaciones cada uno:

Las líneas rojas marcan los límites de los 4 mapas de 4 combinaciones donde las líneas de selección (AB) tienen el mismo valor. Se aplica entonces la minimización utilizando el método gráfico sin atravesar estos límites. El resultado son las siguientes 4 funciones residuo:

f0(C,D) = C
f1(C,D) = 1
f2(C,D) = CD
f3(C,D) = C + D

Tal como se observa, las funciones residuo f2 y f3 no son triviales y se requiere de compuertas para implementarlas. Sin embargo, si se eligen cuidadosamente las variables para las líneas de selección, a veces es posible lograr obtener funciones residuo de implementación trivial. Veamos qué ocurre si se eligen A y C como líneas de selección:

Al utilizar A y C como líneas de selección, el mapa queda dividido de forma diferente, lo que permite obtener 4 funciones residuo de 2 variables (B y D) de implementación trivial:

f0(C,D) = B
f1(C,D) = 1
f2(C,D) = B
f3(C,D) = D

De esta forma no se requiere compuertas (más que un simple inversor para generar D en f3) al implementar el circuito utilizando un MUX 4 a 1:

En comparación con el diseño inicial empleando compuertas NAND y lógica mixta, resulta mucho más simple.

Memorias ROM

Las memorias ROM en su forma básica son dispositivos que simplemente almacenan valores binarios (unos y ceros).

Es posible implementar todo tipo de funciones lógicas empleando memorias ROM. Las variables de la función se utilizan como líneas de dirección, y el valor que toma la función para cada combinación se guarda como dato. Para el ejemplo presentado, se puede hacer una analogía con la implementación del MUX 16 a 1. Es otro tipo de solución de "fuerza bruta", pues se almacenan en memoria todos los valores que puede tomar la función, incluso los don't care.

El tamaño de la memoria ROM dependerá de la cantidad de variables de la función (cantidad de bits de dirección) y la cantidad de funciones a implementar (si se desea implementar sólo una función, el dato es de 1 bit). De esta forma, para implementar m funciones de n variables, se necesitará una ROM de 2n filas de datos de m bits de ancho. En total la memoria ROM tendrá una tamaño de 2n * m.

Si se deseara implementar con una memoria ROM la función f(A,B,C,D) = BC + AC + CD, se requiere una memoria ROM de 16 líneas de 1 bit de ancho. El tamaño total será de 16 bits.

La programación de la ROM consiste en indicar el valor que toma cada una de las funciones para cada combinación de valores en las entradas:

Básicamente coincide con la tabla de verdad de la función, a excepción de que se deben especificar datos para absolutamente todas las combinaciones de entradas. Esto significa que todos los don't care de la función (*, si es que tiene) deben adoptar un valor 0 o 1. Lógicamente la ROM no almaneca un valor "indefinido", sólo es capaz de almacenar unos y ceros.


Tal vez pueda interesarte


Compartí este artículo