Está en la página 1de 55

Introducción a los ordenadores

4. Bloques funcionales combinacionales

Muchas aplicaciones de sistemas digitales hacen uso de unos mismos sistemas


combinacionales, pues a lo largo de los años se ha visto que algunos de estos sistemas
eran la manera más ágil de implementar ciertos requerimientos. Esta particularidad,
unida al hecho que en las aplicaciones reales es habitual usar elementos que
directamente solucionen parte del diseño, ha hecho que algunos circuitos
combinacionales se puedan encontrar directamente implementados en un circuito
integrado o chip. Esto facilita el diseño de sistemas complejos y también simplifica el
cableado entre los distintos elementos del circuito.

Los bloques funcionales combinacionales son pues circuitos combinacionales que


realizan una cierta función lógica y que se hallan habitualmente implementados en un
circuito integrado.

Ejemplo 4.1

A modo de ejemplo supongamos que nos interesa disponer de un circuito integrado que
compare dos números binarios de 2 bits y nos responda si éstos son iguales.

2
A 1
2 A=B C
B

Figura 4.1. Bloque funcional comparador.

Primero tendríamos que diseñar la función booleana que soluciona las especificaciones,
por lo que partiríamos de la tabla de verdad del sistema.

𝐴𝐴1 𝐴𝐴0 𝐵𝐵1 𝐵𝐵0 𝐶𝐶


0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
0 0 1 1 0
0 1 0 0 0
0 1 0 1 1
0 1 1 0 0
0 1 1 1 0
1 0 0 0 0
1 0 0 1 0
1 0 1 0 1
1 0 1 1 0
1 1 0 0 0
1 1 0 1 0
1 1 1 0 0
1 1 1 1 1

Tabla 4.1. Tabla de verdad del comparador.

1
Introducción a los ordenadores

Es interesante trabajar con la función booleana más simplificada posible para facilitar la
implementación, por lo que haríamos su simplificación por Karnaugh.

𝐵𝐵1 𝐵𝐵0
00 01 11 10
00 1 0 0 0
01 0 1 0 0

𝐴𝐴1 𝐴𝐴0
11 0 0 1 0
10 0 0 0 1

Tabla 4.2. Simplificación por el método de ceros de Karnaugh de la función comparador.

Una vez hemos hallado la función booleana 𝐶𝐶 = (𝐴𝐴1 + 𝐵𝐵 ���1 ) × (𝐴𝐴0 +


���1 ) × (𝐵𝐵1 + 𝐴𝐴
���0 ) procederemos a implementarla mediante puertas lógicas. En este punto
���0 ) × (𝐵𝐵0 + 𝐴𝐴
𝐵𝐵
podríamos considerar diversas opciones para su implementación, pero la más óptima
seguramente pasa por observar la relación de esta función con puertas de tipo XOR, es
�����������������������������
���1 ) × �����������������������������
���1 ) × (𝐵𝐵1 + 𝐴𝐴 ���0 ) = ������������������������
���
decir 𝐶𝐶 = (𝐴𝐴1 + 𝐵𝐵 (𝐴𝐴0 + ���
𝐵𝐵0 ) × (𝐵𝐵0 + 𝐴𝐴 𝐴𝐴1 × 𝐵𝐵1 + 𝐵𝐵���1 × 𝐴𝐴1 ×
������������������������
��� 𝐵𝐵0 × 𝐴𝐴0 = ���������
𝐴𝐴0 × 𝐵𝐵0 + ��� 𝐴𝐴1 ⨁𝐵𝐵1 × ���������
𝐴𝐴0 ⨁𝐵𝐵0.

A1
B1
C
A0
B0

Bloque comparador

Figura 4.2. Implementación interna del bloque funcional comparador.

Lo que acabamos de ver es pues un posible bloque funcional combinacional que una
vez integrado en un chip podría ser utilizado en múltiples aplicaciones. De esta manera
en cada una de estas aplicaciones ya no nos tendríamos que preocupar por diseñar e
implementar el bloque comparador. Directamente haríamos uso del chip que
implementa esta función y cablearíamos sus entradas y salida con el resto de elementos
de nuestra aplicación.

Ejemplo 4.2

Los circuitos que hacen conversiones entre distintos sistemas de codificación numérica
también son bloques funcionales combinacionales. Imaginemos por ejemplo el caso que
nos pidan implementar un bloque funcional que convierta un número codificado en
binario natural a BCD Aiken.

4 4
XBN BN to Aiken YAiken

Figura 4.3. Bloque conversor de binario natural a BCD Aiken.

2
Introducción a los ordenadores

Partimos nuevamente de la tabla de verdad del sistema a diseñar. Podemos ver cómo
algunas combinaciones dan lugar a indeterminaciones pues no tiene sentido codificar
en BCD un número superior al 9.

𝑋𝑋3 𝑋𝑋2 𝑋𝑋1 𝑋𝑋0 𝑌𝑌3 𝑌𝑌2 𝑌𝑌1 𝑌𝑌0


0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1
0 0 1 0 0 0 1 0
0 0 1 1 0 0 1 1
0 1 0 0 0 1 0 0
0 1 0 1 1 0 1 1
0 1 1 0 1 1 0 0
0 1 1 1 1 1 0 1
1 0 0 0 1 1 1 0
1 0 0 1 1 1 1 1
1 0 1 0 X X X X
1 0 1 1 X X X X
1 1 0 0 X X X X
1 1 0 1 X X X X
1 1 1 0 X X X X
1 1 1 1 X X X X

Tabla 4.3. Tabla de verdad del comparador.

De hecho, en este caso se trata de implementar no una sino cuatro funciones distintas,
una para cada salida. Para cada una de estas funciones tendríamos que hacer su
simplificación por Karnaugh y posteriormente su implementación con puertas lógicas.
Consideremos el caso de la salida de mayor peso 𝑌𝑌3 .

𝑋𝑋1 𝑋𝑋0
00 01 11 10
00 0 0 0 0
01 0 1 1 1
𝑋𝑋3 𝑋𝑋2

11 X X X X
10 1 1 X X

Tabla 4.4. Simplificación por el método de unos de Karnaugh de la función 𝒀𝒀𝟑𝟑 .

De este modo la salida de 𝑌𝑌3 sería 𝑌𝑌3 = 𝑋𝑋3 × ���


𝑋𝑋1 + 𝑋𝑋2 × 𝑋𝑋0 + 𝑋𝑋2 × 𝑋𝑋1 = 𝑋𝑋3 × ���
𝑋𝑋1 +
𝑋𝑋2 × (𝑋𝑋0 + 𝑋𝑋1 ).

Os proponemos que halléis las tres funciones restantes 𝑌𝑌2 , 𝑌𝑌1 e 𝑌𝑌0 . Una vez halladas las
distintas funciones tan sólo restaría implementarlas mediante puertas lógicas e
integrarlas todas ellas como un bloque.

3
Introducción a los ordenadores

X3
Y3
X2
X1 Y2
X0 Y1
Y0

BN to Aiken

Figura 4.4. Implementación interna del bloque conversor de binario natural a Aiken. Observad que
sólo se muestra la implementación de la salida 𝒀𝒀𝟑𝟑 , dejando para vosotros que halléis una posible
implementación de las tres restantes salidas.

Como hemos visto los bloques funcionales combinacionales no son más que sistemas
combinacionales como los que habíamos visto anteriormente y su proceso de diseño e
implementación sigue las mismas pautas que hemos usado en temas anteriores.

Recordemos no obstante que su particularidad está en el hecho que suelen ser bloques
muy repetidos en muchos sistemas reales por lo que en la práctica se comercializan
integrados en chips para facilitar la implementación de sistemas complejos.

4.1. Características de las señales de entrada y


salida de los bloques funcionales

Pasemos a comentar distintos aspectos que suelen utilizarse en la descripción de un


bloque funcional, más allá de propiamente la función que implementa.

4.1.1. Señales por lógica positiva y señales por lógica


negativa

Hemos visto que los bloques funcionales tendrán una o diversas señales de entrada y
salida. Hasta el momento siempre hemos considerado que cuando queremos “activar”
una entrada aplicamos un 1 a dicha variable mientras que cuando la queremos
“desactivar” le aplicamos un 0. Del mismo modo hemos ido considerando que cuando
una salida responde con un 1 entonces quiere decir que la función es “cierta” o bien que
estamos “activando” algo, mientras que cuando responde con un 0 quiere decir todo lo
contrario, es decir que la función es “falsa” o bien que “desactivamos” alguna cosa. No
obstante, no siempre es así, por lo que en las señales de entrada o salida se suele
indicar si éstas son activas por lógica positiva o bien por lógica negativa.

• Una señal de entrada es activa por lógica positiva o también denominada


activa por uno, cuando sea necesario aplicar un 1 a dicha entrada para que sea
considerada activa o cierta sobre la función que implementa.
• Una señal de salida es activa por lógica positiva o también denominada activa
por uno, cuando ésta responda con un 1 para indicar que la función que
implementa es cierta.
4
Introducción a los ordenadores

• Una señal de entrada es activa por lógica negativa o también denominada


activa por cero, cuando sea necesario aplicar un 0 a dicha entrada para que sea
considerada activa o cierta sobre la función que implementa.
• Una señal de salida es activa por lógica negativa o también denominada activa
por cero, cuando ésta responda con un 0 para indicar que la función que
implementa es cierta.

Veamos un ejemplo simple, aunque no sea propiamente un bloque funcional.


Supongamos que tenemos una puerta AND de dos entradas de la que nos dicen que
dichas entradas son activas por cero mientras que su salida es activa por lógica positiva.
Sabemos que una puerta AND solo es “cierta” cuando sus dos entradas son “ciertas” y
como las entradas nos dicen que son activas por lógica negativa entonces tan solo la
combinación formada por 0 y 0 dará lugar a un valor cierto a la salida, en este caso un
1 pues la salida sí funciona por lógica positiva. Es decir, la puerta dará un 0 de salida
para todas las combinaciones de entrada excepto para la combinación formada por 0 y
0.
𝑎𝑎 𝑏𝑏 𝑎𝑎 × 𝑏𝑏
0 0 1
0 1 0
1 0 0
1 1 0

Tabla 4.5. Función AND con entradas por lógica negativa y salida por lógica positiva.

En general estamos habituados a razonar el funcionamiento de los sistemas digitales


por lógica positiva, por lo que a menudo se continúa haciendo de esta manera y
posteriormente si conviene se complementa el valor de las entradas o salidas si éstas
son activas por lógica negativa.

Para terminar de entenderlo veamos las posibles tablas de verdad de una puerta OR
con distintas combinaciones de señales activas por uno o bien por cero.

Activas por 1 Activa por 1 Activas por 1 Activa por 0


𝑎𝑎 𝑏𝑏 𝑎𝑎 + 𝑏𝑏 𝑎𝑎 𝑏𝑏 𝑎𝑎 + 𝑏𝑏
0 0 0 0 0 1
0 1 1 0 1 0
1 0 1 1 0 0
1 1 1 1 1 0

Activas por 0 Activa por 1 Activas por 0 Activa por 0


𝑎𝑎 𝑏𝑏 𝑎𝑎 + 𝑏𝑏 𝑎𝑎 𝑏𝑏 𝑎𝑎 + 𝑏𝑏
0 0 1 0 0 0
0 1 1 0 1 0
1 0 1 1 0 0
1 1 0 1 1 1

Tabla 4.6. Puertas OR que difieren entre ellas según si sus entradas y salida operan por lógica
positiva o bien por lógica negativa.

5
Introducción a los ordenadores

Cabe mencionar que si bien en los distintos ejemplos anteriores todas las entradas eran
activas por lógica positiva o bien por lógica negativa, en la realidad encontraremos
bloques funcionales con algunas de sus entradas activas por lógica positiva y otras
entradas activas por lógica negativa. Pero esto ya lo veremos con algún ejemplo más
complejo más adelante.

La manera de indicar si una señal es activa por lógica negativa en un diagrama de


puertas o de bloques es mediante un círculo en la correspondiente entrada o salida. De
hecho, esto ya lo habíamos visto en el caso de puertas lógicas, es decir, observad la
diferencia por ejemplo entre el diagrama de una puerta AND y una puerta NAND.

Figura 4.5. Diferencia gráfica entre una puerta con salida activa por lógica positiva y otra con
salida por lógica negativa.

De este modo los distintos bloques funcionales tendrán habitualmente como símbolo un
rectángulo en el que se indicará la función correspondiente y en el que las entradas y
salidas mostrarán un círculo cuando éstas funcionen por lógica negativa.

X3 Y3
X2 Y2
X1 BN to Aiken Y1
X0 Y0

Figura 4.6. Ejemplo de bloque funcional conversor de binario natural a Aiken en el que las entradas
funcionan por lógica negativa mientras que las salidas funcionan por lógica positiva. De esta
manera si por ejemplo las entradas valen 1001 entonces querrá decir que estamos entrando el
valor decimal 6 (0110) y el sistema responderá con el valor 1100. Si la salida hubiese funcionado
por lógica negativa el boque habría respondido para esta combinación con un 0011.

Si bien no es objetivo de la asignatura entrar a ver cómo se implementan todos estos


circuitos a nivel electrónico, comentar que el hecho que algunas entradas y salidas
funcionen por lógica negativa responde a que su implementación real a nivel de
transistores es mucho más simple, es decir, precisa de menos transistores.

4.1.2. Señales operativas y señales de control

Aparte de si las entradas funcionan por lógica positiva o bien por lógica negativa,
también se suele diferenciar si éstas son entradas operativas o bien entradas de control.

• Una señal de entrada es operativa cuando el circuito usa su valor para


determinar o calcular el resultado de la función que implementa.
• Una señal de entrada es de control cuando el circuito usa su valor para
influenciar sobre el funcionamiento general del bloque o bien sobre el
funcionamiento de sus entradas operativas.

6
Introducción a los ordenadores

Ejemplo 4.3

Supongamos que queremos implementar un bloque funcional con dos entradas


operativas (𝑎𝑎,𝑏𝑏) y una entrada de control (𝐴𝐴/𝑂𝑂�), de tal modo que cuando tengamos
𝐴𝐴/𝑂𝑂� = 0 entonces el bloque implemente la función OR y si 𝐴𝐴/𝑂𝑂� = 1 entonces el bloque
implemente la función AND. Supongamos que las entradas son activas por lógica
positiva y la salida es activa por lógica negativa.

a
b AND/OR R
A/O

Figura 4.7. Bloque funcional que implementa una función AND o bien una función OR según el
� . Las entradas funcionan por lógica positiva y la salida por lógica
valor de la entrada de control 𝑨𝑨/𝑶𝑶
negativa.

El hecho que unas entradas sean operativas o bien de control no excluye que todas
ellas sean señales propias de un sistema combinacional, por lo que podemos elaborar
la tabla de verdad para todas las combinaciones posibles de entradas y razonar el valor
con el que debe responder el bloque.

𝐴𝐴/𝑂𝑂� 𝑎𝑎 𝑏𝑏 𝑅𝑅
0 0 0 1
0 0 1 0
0 1 0 0
0 1 1 0
1 0 0 1
1 0 1 1
1 1 0 1
1 1 1 0

Tabla 4.7. Tabla de verdad del bloque combinacional que implementa una AND o una OR según el
� . La salida es activa por cero.
valor que toma su entrada de control 𝑨𝑨/𝑶𝑶

Finalmente sólo resta extraer la función, en la medida de lo posible simplificarla por


Karnaugh e implementarla.

𝑎𝑎 𝑏𝑏
00 01 11 10
0 1 0 0 0
𝐴𝐴/𝑂𝑂�
1 1 1 0 1

Tabla 4.8. Simplificación por el método de ceros de Karnaugh del bloque que implementa una AND
�.
o bien una OR según una entrada de control 𝑨𝑨/𝑶𝑶

En este caso hemos optado por simplificar por ceros obteniendo como resultado 𝑅𝑅 =
�𝐴𝐴/𝑂𝑂� + 𝑏𝑏�� × (𝐴𝐴/𝑂𝑂� + 𝑎𝑎�) × �𝑎𝑎� + 𝑏𝑏�� = �𝐴𝐴/𝑂𝑂� + �𝑏𝑏� × 𝑎𝑎��� × �𝑎𝑎� + 𝑏𝑏��.

7
Introducción a los ordenadores

a
b R
A/O

Figura 4.8. Implementación del bloque funcional que implementa una función AND o bien una
�.
función OR según el valor de la entrada de control 𝑨𝑨/𝑶𝑶

Os proponemos que miréis la implementación de este mismo bloque si hubiésemos


simplificado la función por el método de unos de Karnaugh.

4.1.3. Señal de control ENABLE

Existen múltiples tipos de señales de control en los sistemas digitales. No obstante, en


este punto del temario nos vamos a centrar en una señal de control que es muy común
en los bloques funcionales combinacionales, que es la señal de validación o ENABLE.
Esta señal habilita que el bloque realice la función para la que ha sido diseñado o bien
esté deshabilitado.

• Cuando ENABLE está activo entonces las salidas están habilitadas y por
consiguiente toman el valor que les corresponda según la función que
implementa el bloque y el valor de las entradas en ese momento.
• Cuando ENABLE está inactivo entonces las salidas están deshabilitadas y por
consiguiente consideraremos que valdrán 0 aquellas que funcionen por lógica
positiva o bien valdrán 1 aquellas que funcionen por lógica negativa,
independientemente del valor de las entradas.

La señal de ENABLE, al igual que el resto de señales de entrada, puede ser activa por
lógica positiva o bien por lógica negativa.

Cuando estamos hablando del tipo de señal, lógica positiva o lógica negativa, es
importante diferenciar si estamos haciendo referencia a la salida de la función o bien a
la señal de ENABLE. Es decir, por un lado, la función que queremos implementar puede
tener su salida por lógica positiva o por lógica negativa, y por otro lado la señal de
ENABLE puede ser activa por lógica positiva o bien por lógica negativa.

Ejemplo 4.4

Supongamos que tenemos un bloque funcional 𝑓𝑓’ que implementa un comparador de


dos números de 4 bits cuya salida nos indica cuándo estos números son iguales y lo
hace por lógica negativa. Al bloque anterior le añadimos una señal de 𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸 que es
activa por lógica positiva y por consiguiente con ella tenemos un bloque funcional final
𝑓𝑓 que realiza la comparación cuando 𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸 = 1 pero cuando 𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸 = 0 las salidas
han de quedar deshabilitadas. Intentemos deducir la tabla de verdad del sistema.

8
Introducción a los ordenadores

Observamos que tenemos dos entradas 𝐴𝐴[3. .0] y 𝐵𝐵[3. .0] de 4 bits cada una.
Imaginemos que con ellas implementamos un comparador 𝑓𝑓’ cuya salida sea activa por
lógica negativa.

𝐴𝐴[3. .0] 𝐵𝐵[3. .0] 𝑓𝑓′


0000 0000 0
0001 0001 0
… 0
1110 1110 0
1111 1111 0
otras combinaciones 1

Tabla 4.9. Tabla de verdad de la función 𝒇𝒇’ que realiza la comparación de dos números de 4 bits y
cuya salida es activa por lógica negativa.

Si ahora añadimos el comportamiento de la señal 𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸 activa por lógica positiva


tenemos que considerar lo siguiente: cuando 𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸 = 1 el sistema tiene que
funcionar con toda normalidad, es decir 𝑓𝑓 = 𝑓𝑓’ mientras que si 𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸 = 0 entonces el
bloque final ha de quedar deshabilitado y puesto que nos dicen que el comparador
funciona por lógica negativa entonces 𝑓𝑓 = 1. En resumen, de manera sintética vemos
que la implementación podría responder al siguiente esquema.

4
A 4 f’
B f

ENABLE

Figura 4.9. Implementación de la señal de 𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬 activa por lógica positiva en una función que
funciona por lógica negativa. Vemos que cuando 𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬 = 𝟏𝟏 entonces 𝒇𝒇 = 𝒇𝒇’ mientras que
cuando 𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬𝑬 = 𝟎𝟎 entonces 𝒇𝒇 = 𝟏𝟏.

Si bien la señal de ENABLE podría considerarse como una entrada más de la tabla de
verdad del bloque funcional, en realidad vemos por el ejemplo anterior que suele
implementarse como un “ajuste final” que se realiza antes de la salida del bloque, es
decir primero se suele diseñar el bloque sin considerar la existencia de ENABLE y una
vez tenemos este bloque se le añade un circuito a la salida que funcione según esta
entrada de control. Veamos cómo se hace.

Consideraremos que queremos diseñar un bloque que implemente una función 𝑓𝑓 la cual
incluya una entrada de ENABLE (𝐸𝐸) y otras entradas operativas (𝑂𝑂𝑂𝑂), es decir 𝑓𝑓(𝐸𝐸, 𝑂𝑂𝑂𝑂).
Lo que haremos será diseñar una función f’ que dependa sólo de las entradas operativas
𝑓𝑓’(𝑂𝑂𝑂𝑂) y posteriormente diseñaremos 𝑓𝑓 a partir de 𝑓𝑓’ y de 𝐸𝐸, es decir 𝑓𝑓(𝑓𝑓’, 𝐸𝐸). Según si
f’ y 𝐸𝐸 funcionan por lógica positiva o por lógica negativa podemos encontrarnos con 4
situaciones distintas y por consiguiente 4 implementaciones distintas.

• Supongamos que 𝐸𝐸 es activa por lógica negativa y 𝑓𝑓’ es una función por lógica
negativa.

En este caso y tal y como vemos en la siguiente tabla, es necesario que 𝐸𝐸 valga
0 para estar activa y por consiguiente para facilitar que la función 𝑓𝑓 tome el
mismo valor que 𝑓𝑓’, es decir 𝑓𝑓 = 𝑓𝑓’. En cambio cuando 𝐸𝐸 está inactiva por valer

9
Introducción a los ordenadores

1 entonces la función 𝑓𝑓 ha de quedar deshabilitada, en este caso 1 puesto que


𝑓𝑓’ es activa por lógica positiva. Vemos por consiguiente que 𝑓𝑓 = 𝐸𝐸 + 𝑓𝑓’.

𝐸𝐸 𝑓𝑓′ 𝑓𝑓
0 0 0
0 1 1
1 0 1
1 1 1

Tabla 4.10. Tabla de verdad para implementar la señal de ENABLE activa por lógica negativa en
una función que también funciona por lógica negativa.

De esta manera la implementación consiste en poner una puerta OR “justo


antes” de la salida del bloque funcional.

N
Op f’
f

Figura 4.10. Implementación de la señal de ENABLE activa por lógica negativa en una función que
también funciona por lógica negativa.

• Supongamos que 𝐸𝐸 es activa por lógica positiva y 𝑓𝑓’ es una función por lógica
positiva.

En este caso y tal y como vemos en la siguiente tabla, es necesario que 𝐸𝐸 valga
1 para estar activa y por consiguiente para facilitar que la función 𝑓𝑓 tome el
mismo valor que 𝑓𝑓’, es decir 𝑓𝑓 = 𝑓𝑓’. En cambio cuando 𝐸𝐸 está inactiva por valer
0 entonces la función 𝑓𝑓 ha de quedar deshabilitada, en este caso 0 puesto que
𝑓𝑓’ es activa por lógica positiva. Vemos por consiguiente que 𝑓𝑓 = 𝐸𝐸 × 𝑓𝑓’.

𝐸𝐸 𝑓𝑓′ 𝑓𝑓
0 0 0
0 1 0
1 0 0
1 1 1

Tabla 4.11. Tabla de verdad para implementar la señal de ENABLE activa por lógica positiva en una
función que también funciona por lógica positiva.

De esta manera la implementación consiste en poner una puerta AND “justo


antes” de la salida del bloque funcional.

N
Op f’
f

Figura 4.11. Implementación de la señal de ENABLE activa por lógica positiva en una función que
también funciona por lógica positiva.

10
Introducción a los ordenadores

• Supongamos que 𝐸𝐸 es activa por lógica negativa y 𝑓𝑓’ es una función por lógica
positiva.

En este caso y tal y como vemos en la siguiente tabla, es necesario que 𝐸𝐸 valga
0 para estar activa y por consiguiente para facilitar que la función 𝑓𝑓 tome el
mismo valor que 𝑓𝑓’, es decir 𝑓𝑓 = 𝑓𝑓’. En cambio cuando 𝐸𝐸 está inactiva por valer
1 entonces la función 𝑓𝑓 ha de quedar deshabilitada, en este caso 0 puesto que
𝑓𝑓’ es activa por lógica positiva. Vemos por consiguiente que 𝑓𝑓 = 𝐸𝐸� × 𝑓𝑓’.

𝐸𝐸 𝑓𝑓′ 𝑓𝑓
0 0 0
0 1 1
1 0 0
1 1 0

Tabla 4.12. Tabla de verdad para implementar la señal de ENABLE activa por lógica negativa en
una función que funciona por lógica positiva.

De esta manera la implementación consiste en poner una puerta AND “justo


antes” de la salida del bloque funcional para implementar 𝐸𝐸� × 𝑓𝑓’.

N
Op f’
f

Figura 4.12. Implementación de la señal de ENABLE activa por lógica negativa en una función que
funciona por lógica positiva.

• Supongamos que 𝐸𝐸 es activa por lógica positiva y 𝑓𝑓’ es una función por lógica
negativa.

Este último caso es el que hemos visto en el anterior ejemplo del comparador
con señal de ENABLE, sobre el que hemos visto que la solución pasa por
implementar una puerta OR “justo antes” de la salida del bloque que calcula 𝑓𝑓 =
𝐸𝐸� + 𝑓𝑓’.

Ejemplo 4.5

Tenemos que diseñar la implementación de una alarma activa por lógica positiva. Dicha
alarma se tendrá que activar cuando se detecte la presencia de un intruso o bien cuando
se sobrepase una cierta temperatura. Para ello el sistema dispone de dos entradas 𝑃𝑃 y
𝑇𝑇 que respectivamente indican la presencia de un intruso o una temperatura elevada,
siendo la primera una entrada por lógica negativa y la segunda por lógica positiva. El
circuito ha de disponer de una entrada 𝐸𝐸 que habilite su funcionamiento y que funcione
por lógica negativa.

11
Introducción a los ordenadores

Primero planteamos la tabla de verdad de la alarma según las entradas 𝑃𝑃 y 𝑇𝑇. Al no ser
aún la salida final del sistema, puesto que aún nos queda considerar la otra señal 𝐸𝐸, a
esta alarma provisional la denominaremos 𝐴𝐴’.

𝑃𝑃 𝑇𝑇 𝐴𝐴′
0 0 1
0 1 1
1 0 0
1 1 1

Tabla 4.13. Tabla de verdad para implementar la señal de alarma 𝑨𝑨′ por lógica positiva a partir de
una entrada 𝑷𝑷 activa por lógica negativa y otra entrada 𝑻𝑻 activa por lógica positiva. La alarma 𝑨𝑨′ se
ha de activar ante la activación de cualquiera de estas dos entradas.

Vemos que 𝐴𝐴’ = 𝑃𝑃� + 𝑇𝑇. Ahora queda aplicar un circuito que habilite la salida 𝐴𝐴 activa por
lógica positiva a partir de 𝐴𝐴’ y de una señal de validación 𝐸𝐸 que funciona por lógica
negativa. Como hemos visto anteriormente la solución sería 𝐴𝐴 = 𝐴𝐴′ × 𝐸𝐸� .

P
T
A

Figura 4.13. Implementación de la señal de alarma 𝑨𝑨 por lógica positiva a partir de una entrada 𝑷𝑷
activa por lógica negativa y otra entrada 𝑻𝑻 activa por lógica positiva, así como una entrada de
validación 𝑬𝑬 activa por lógica negativa.

Comentar finalmente que si bien hemos considerado que cuando ENABLE está
desactivado entonces las salidas valen 0 o 1 según si funcionan por lógica positiva o
negativa respectivamente, en realidad hay muchos bloques funcionales en los que la
salida queda realmente desconectada, es decir, ni vale 0 ni vale 1 sino que es como si
esa conexión no existiera, como si fuera un circuito abierto. Es lo que se llama una salida
de alta impedancia. No obstante, esto lo dejaremos para más adelante en tanto que su
implementación precisa de un elemento que aún no hemos tratado.

4.2. Codificadores

Un codificador es un bloque funcional que presenta diversas líneas de entrada y un bus


de salida donde se indica, mediante una combinación binaria, cuál de las líneas de
entrada está activa.

12
Introducción a los ordenadores

Ejemplo 4.6

Supongamos que tenemos 4 líneas de entrada y queremos mediante un bus de salida


de 2 bits, saber cuál de las 4 líneas es la que está activada. Todas las líneas funcionan
por lógica positiva.

En este caso lo que necesitamos usar será lo que se denomina un “codificador 4 a 2”


cuyo bloque queda representado en la siguiente figura. Su uso es relativamente simple.
Si se activa la línea de menor peso entonces el bus de salida valdrá 00; si se activa la
siguiente línea el bus de salida valdrá 01; si se activa la siguiente línea el bus valdrá 10
y finalmente si se activa la línea de mayor peso la salida valdrá 11. Vemos pues cómo
el valor de salida en binario natural nos indica qué línea se ha activado.

D0
D1 Q0
D2 Q1
D3

Figura 4.14. Codificador 4 a 2 con entradas y salidas por lógica positiva.

Los codificadores pueden ser muy variados según distintos parámetros:

• Según el rango de valores del bus de salida


o Un codificador completo es aquel en el que si tenemos 𝑀𝑀 líneas de
salida entonces tenemos 2𝑀𝑀 líneas de entrada. Visto de otra forma lo que
satisface es que cada una de las combinaciones del bus de salida se
corresponde a una de las líneas de entrada. Así un codificador 4 a 2 es
completo o también un codificador 8 a 3.
o Un codificador incompleto es aquel en el que si tenemos 𝑀𝑀 líneas de
salida entonces tenemos menos de 2𝑀𝑀 líneas de entrada. Visto de otra
forma lo que satisface es que algunas de las combinaciones del bus de
salida no se corresponden a ninguna de las líneas de entrada. Así un
codificador 10 a 4 es incompleto puesto que para codificar hasta 10
valores necesitamos 4 bits, pero con 4 bits podríamos llegar a codificar
un número mayor de entradas.
• Según el código binario utilizado para la codificación del bus de salida
o Un codificador binario natural es aquel en el que el bus de salida indica
mediante el código binario natural el valor de la entrada que está
activada. Si no se especifica un código distinto es el que se considera por
defecto.
o Un codificador Gray es aquel en el que el bus de salida indica mediante
el código Gray el valor de la entrada que está activada.
o Un codificador BCD es aquel en el que el bus de salida indica mediante
el código BCD el valor de la entrada que está activada.
o etc.
• Según la activación por unos o por ceros de las entradas
o Un codificador con entradas por lógica positiva es aquel en el que para
activar una entrada se tiene que aplicar un 1. Se entiende que el resto de
entradas estarán desactivadas y por consiguiente se les aplicará un 0.

13
Introducción a los ordenadores

o Un codificador con entradas por lógica negativa es aquel en el que para


activar una entrada se tiene que aplicar un 0. Se entiende que el resto de
entradas estarán desactivadas y por consiguiente se les aplicará un 1.
Quedará indicado por un círculo en las líneas de entrada.
• Según la activación por unos o por ceros del bus de salida
o Un codificador con salidas por lógica positiva es aquel en el que el bus
de salida toma los valores correspondientes a un código binario.
o Un codificador con salidas por lógica negativa es aquel en el que el bus
de salida toma los valores complementados correspondientes a un
código binario. Quedará indicado por un círculo en las líneas de salida.
• Según la posibilidad de prioridades
o Un codificador sin prioridad es aquel en el que se supone que sólo se
activa una entrada cada vez y en caso contrario el bus de salida tomará
cualquier valor indeterminado.
o Un codificador con prioridad por el bit de más peso (MSB) es aquel en
el que si se activa más de una entrada a la vez entonces el bus de salida
quedará codificado según la entrada que presente mayor peso de entre
todas las que están activas.
o Un codificador con prioridad por el bit de menor peso (LSB) es aquel
en el que si se activa más de una entrada a la vez entonces el bus de
salida quedará codificado según la entrada que presente menor peso de
entre todas las que están activas.

Los codificadores más habituales en el mercado suelen ser los que codifican en binario
natural, que funcionan por lógica negativa y que presentan prioridad por el bit de más
peso. En cuanto al número de entradas y salidas los más habituales son los 8 a 3 y los
10 a 4.

Recordemos que al ser bloques funcionales los podemos mirar como circuitos
combinacionales que ya nos facilitan encapsulados, pero precisamente por el hecho de
ser circuitos combinacionales hemos de ser capaces de deducir cómo están
internamente implementados. Veámoslo mediante algunos ejemplos.

Ejemplo 4.7

Vamos a diseñar para empezar un codificador 4 a 2 cuyas entradas y salidas operen


por lógica positiva y sin prioridad. Si no nos dicen nada más entendemos que el código
a utilizar es el binario natural.

Básicamente partimos de la tabla de verdad del circuito de 4 entradas y 2 salidas.

𝐷𝐷3 𝐷𝐷2 𝐷𝐷1 𝐷𝐷0 𝑄𝑄1 𝑄𝑄0


0 0 0 1 0 0
0 0 1 0 0 1
0 1 0 0 1 0
1 0 0 0 1 1
otras combinaciones X X

Tabla 4.14. Tabla de verdad de un codificador 4 a 2 con entradas y salidas por lógica positiva y sin
prioridad.

14
Introducción a los ordenadores

Podemos ver que para implementar el codificador de hecho tan sólo tenemos que
implementar un par de circuitos combinacionales que son 𝑄𝑄1 = 𝐷𝐷2 + 𝐷𝐷3 y 𝑄𝑄0 = 𝐷𝐷1 + 𝐷𝐷3 .

D0
D1 Q0
D2 Q1
D3

Figura 4.15. Implementación interna de un codificador 4 a 2 con entradas y salidas por lógica
positiva y sin prioridad.

Es interesante observar un par de aspectos en este ejemplo que están relacionados


entre sí. Por un lado vemos que la entrada 𝐷𝐷0 no tiene ninguna repercusión en la salida.
Por otro lado también vemos que en caso que no se active ninguna entrada, es decir
que todas valgan cero, entonces el codificador mostrará a su salida el valor 00 que nos
podría hacer pensar que está activada la entrada 𝐷𝐷0 según la tabla de verdad.

Esto hace que cuando usemos un codificador sea importante que siempre haya alguna
entrada activada. En caso contrario, es decir si en la aplicación se puede dar la
posibilidad que todas las entradas estén desactivadas, entonces tendremos que
generarnos una señal que nos indique este hecho, tal y como se muestra por ejemplo
en la siguiente figura.

D0
D1 Q0
D2 Q1
D3

Figura 4.16. Codificador 4 a 2 combinado con una puerta OR de 4 entradas que nos permite saber
si el valor del codificador se corresponde a la activación de una entrada, es decir si 𝑨𝑨 = 𝟏𝟏 entonces
el código que marque el bus 𝑸𝑸 es correcto mientras que si 𝑨𝑨 = 𝟎𝟎 entonces sabremos que no hay
ninguna entrada activa por mucho que 𝑸𝑸𝟏𝟏 = 𝟎𝟎 y que 𝑸𝑸𝟎𝟎 = 𝟎𝟎.

El código correspondiente a la descripción en VHDL de un codificador 4 a 2 con entradas


y salidas por lógica positiva y sin prioridad podría ser el siguiente:

library ieee;
use ieee.std_logic_1164.all;

entity Ejemplo_4_7 is

port (
D : in std_logic_vector(3 downto 0);
Q : out std_logic_vector(1 downto 0));

end Ejemplo_4_7;

15
Introducción a los ordenadores

architecture dataflow of Ejemplo_4_7 is

begin

Q <= "00" when D = "0001" else


"01" when D = "0010" else
"10" when D = "0100" else
"11" when D = "1000" else
"00";

end dataflow;

Fijémonos que la asignación condicional de valores a la salida Q va asignando los


valores correspondientes a las combinaciones de entrada en las que sólo hay una
entrada activa, y, por defecto, asigna el valor “00” para cualquier otra combinación de
las entradas (sería incorrecto no especificar un valor por defecto para la salida Q si no
se han contemplado anteriormente todas las posibles combinaciones de valores de
entrada). En principio, si se usa correctamente este codificador, nunca debería
presentarse en su entrada una combinación que no fuese una de las 4 indicadas (una
única entrada activa), pero si por lo que sea se aplica una combinación distinta de estas
4, este codificador suministrará en su salida la combinación “00”.

A continuación podemos ver el resultado de la simulación del bloque anterior con el


Quartus Prime, donde se observa el correcto funcionamiento del codificador (las 4
primeras combinaciones) y el valor “00” de salida para otras combinaciones distintas de
las anteriores.

Figura 4.17. Simulación de la entidad Ejemplo_4_7 correspondiente a un codificador 4 a 2 con


entradas y salidas por lógica positiva y sin prioridad.

Ejemplo 4.8
Diseñemos ahora un codificador 8 a 3 con entradas y salidas por lógica negativa y sin
prioridad.

Nuevamente partimos de la tabla de verdad del circuito de 8 entradas y 3 salidas,


teniendo ahora en consideración que una entrada activa será cuando ésta valga 0 y que
el bus de salida codificará en binario natural pero con todos los bits complementados.

16
Introducción a los ordenadores

𝐷𝐷7 𝐷𝐷6 𝐷𝐷5 𝐷𝐷4 𝐷𝐷3 𝐷𝐷2 𝐷𝐷1 𝐷𝐷0 𝑄𝑄2 𝑄𝑄1 𝑄𝑄0
1 1 1 1 1 1 1 0 1 1 1
1 1 1 1 1 1 0 1 1 1 0
1 1 1 1 1 0 1 1 1 0 1
1 1 1 1 0 1 1 1 1 0 0
1 1 1 0 1 1 1 1 0 1 1
1 1 0 1 1 1 1 1 0 1 0
1 0 1 1 1 1 1 1 0 0 1
0 1 1 1 1 1 1 1 0 0 0
otras combinaciones X X X

Tabla 4.15. Tabla de verdad de un codificador 8 a 3 con entradas y salidas por lógica negativa y sin
prioridad.

A partir de la tabla de verdad podemos ver que el codificador quedará definido con las
siguientes expresiones 𝑄𝑄2 = 𝐷𝐷4 × 𝐷𝐷5 × 𝐷𝐷6 × 𝐷𝐷7 , 𝑄𝑄1 = 𝐷𝐷2 × 𝐷𝐷3 × 𝐷𝐷6 × 𝐷𝐷7 y 𝑄𝑄0 =
𝐷𝐷1 × 𝐷𝐷3 × 𝐷𝐷5 × 𝐷𝐷7.

D0
D1
D2
Q0
D3
Q1
D4
Q2
D5
D6
D7

Figura 4.18. Implementación interna de un codificador 8 a 3 con entradas y salidas por lógica
negativa y sin prioridad.

Ejemplo 4.9
Diseñemos ahora un codificador 4 a 2 con entradas y salidas por lógica positiva y con
prioridad por el bit de menor peso.

Partimos de la tabla de verdad del circuito de 4 entradas y 2 salidas. En este caso


tendremos que considerar las combinaciones en las que se puedan activar más de una
entrada y para esos casos dar prioridad a la entrada de menor peso.

𝐷𝐷3 𝐷𝐷2 𝐷𝐷1 𝐷𝐷0 𝑄𝑄1 𝑄𝑄0


X X X 1 0 0
X X 1 0 0 1
X 1 0 0 1 0
1 0 0 0 1 1
0 0 0 0 X X

Tabla 4.16. Tabla de verdad de un codificador 4 a 2 con entradas y salidas por lógica positiva y con
prioridad por el bit de menor peso. Observad cómo en una misma fila de la tabla de verdad se
explicitan diversas combinaciones mediante los símbolos de indeterminaciones (X). Por ejemplo la
primera fila de la tabla de verdad equivale a 8 combinaciones, la segunda fila a 4 combinaciones y
la tercera fila a 2 combinaciones.

17
Introducción a los ordenadores

Para hallar las funciones correspondientes a las salidas podemos dibujar las tablas de
Karnaugh sobre las que haremos simplificaciones por ceros.

𝐷𝐷1 𝐷𝐷0 𝐷𝐷1 𝐷𝐷0


𝑄𝑄1 𝑄𝑄0
00 01 11 10 00 01 11 10
00 X 0 0 0 00 X 0 0 1
01 1 0 0 0 01 0 0 0 1
𝐷𝐷3 𝐷𝐷2

𝐷𝐷3 𝐷𝐷2
11 1 0 0 0 11 0 0 0 1
10 1 0 0 0 10 1 0 0 1

Tabla 4.17. Simplificación por el método de ceros de Karnaugh de las funciones del codificador 4 a
2 con entradas y salidas por lógica positiva y con prioridad por el bit de menor peso.

De este modo extraemos las funciones simplificadas para implementar el codificador


𝑄𝑄1 = ��� ���0 y 𝑄𝑄0 = ���
𝐷𝐷1 × 𝐷𝐷 ���2 + 𝐷𝐷1 ). De hecho, con un poco de práctica estas funciones
𝐷𝐷0 × (𝐷𝐷
se pueden extraer directamente de la tabla de verdad. Os proponemos que intentéis
deducirlas vosotros mismos.

D0
D1 Q1
D2 Q0

D3

Figura 4.19. Implementación interna de un codificador 4 a 2 con entradas y salidas por lógica
positiva y con prioridad por el bit de menor peso.

Ejemplo 4.10
En este ejemplo diseñaremos un codificador 6 a 3 con entradas por lógica positiva,
salidas por lógica negativa y con prioridad por el bit de mayor peso. El código utilizado
para la codificación será el Gray.

Nuevamente partimos de la tabla de verdad. Como novedades nos encontramos ante


un codificador incompleto puesto que con 3 bits de salida podríamos llegar a codificar 8
posibles entradas. De esta manera las combinaciones que no utilicemos darán lugar a
indeterminaciones en las salidas. Además, el código utilizado será el Gray pero vigilando
que sus valores tendrán que estar complementados bit a bit puesto que la salida es por
lógica negativa.

𝐷𝐷5 𝐷𝐷4 𝐷𝐷3 𝐷𝐷2 𝐷𝐷1 𝐷𝐷0 𝑄𝑄2 𝑄𝑄1 𝑄𝑄0


1 X X X X X 0 0 0
0 1 X X X X 0 0 1
0 0 1 X X X 1 0 1
0 0 0 1 X X 1 0 0
0 0 0 0 1 X 1 1 0
0 0 0 0 0 1 1 1 1
otras combinaciones X X X

Tabla 4.18. Tabla de verdad de un codificador 6 a 3 con entradas por lógica positiva, salidas por
lógica negativa y prioridad por el bit de mayor peso. El código utilizado es el Gray.

18
Introducción a los ordenadores

En este caso hacer el Karnaugh puede ser tedioso teniendo en cuenta que tenemos 6
variables de entrada por lo que es aconsejable llegar a deducir las expresiones
directamente. En este caso las funciones que implementan las tres salidas serían 𝑄𝑄2 =
���5 × ���
𝐷𝐷 𝐷𝐷4 = ����������
𝐷𝐷5 + 𝐷𝐷4 , 𝑄𝑄1 = ���𝐷𝐷5 × ��� ���3 × ���
𝐷𝐷4 × 𝐷𝐷 𝐷𝐷2 = ����������
𝐷𝐷5 + 𝐷𝐷4 × ���������� ���5 × (𝐷𝐷4 + 𝐷𝐷3 +
𝐷𝐷3 + 𝐷𝐷2 y 𝑄𝑄0 = 𝐷𝐷
���2 ) × (𝐷𝐷4 + 𝐷𝐷3 + 𝐷𝐷2 + 𝐷𝐷
𝐷𝐷 ���1 ) = ��� ���2 × ���
𝐷𝐷5 × (𝐷𝐷4 + 𝐷𝐷3 + 𝐷𝐷 𝐷𝐷1 ) =
= ���
𝐷𝐷5 × (𝐷𝐷4 + 𝐷𝐷3 + 𝐷𝐷����������
2 + 𝐷𝐷1 ).

D0
D1
Q0
D2
Q1
D3
Q2
D4
D5

Figura 4.20. Implementación interna de un codificador 6 a 3 con entradas por lógica positiva, salidas
por lógica negativa y prioridad por el bit de mayor peso. El código utilizado es el Gray.

Como hemos visto la sistemática para diseñar un dispositivo codificador es siempre la


misma y básicamente hemos de vigilar en el momento de elaborar la tabla de verdad de
las particularidades que pueda presentar el codificador en cuanto al tipo de lógica
utilizada y la existencia de prioridad.

El código correspondiente a la descripción en VHDL de un codificador Gray 6 a 3 con


entradas por lógica positiva, salidas por lógica negativa y prioridad por el bit de mayor
peso podría ser el siguiente:

library ieee;
use ieee.std_logic_1164.all;

entity Ejemplo_4_10 is

port (
D : in std_logic_vector(5 downto 0);
Qn : out std_logic_vector(2 downto 0));

end Ejemplo_4_10;

architecture dataflow of Ejemplo_4_10 is

begin

Qn <= "000" when D(5) = '1' else


"001" when D(4) = '1' else
"101" when D(3) = '1' else
"100" when D(2) = '1' else
"110" when D(1) = '1' else
"111" when D(0) = '1' else
"011"; -- Salida si no hay ninguna entrada activa

end dataflow;

19
Introducción a los ordenadores

Fijémonos que la asignación condicional de valores a la salida Q va asignando los


valores correspondientes empezando por el valor correspondiente a si el bit de más
peso, D5, está activo, independientemente del valor del resto de bits de entrada. Si esta
condición es falsa, se mira el valor del siguiente bit de más peso, D4, y así
sucesivamente. El orden en que se evalúen las condiciones de entrada asigna la
prioridad a las entradas del codificador.

A continuación podemos ver el resultado de la simulación del bloque anterior con el


Quartus Prime, donde se observa el correcto funcionamiento del codificador y el valor
“011” de salida cuando ninguna entrada está activa.

Figura 4.21. Simulación del codificador Gray 6 a 3 con entradas por lógica positiva, salidas por
lógica negativa y prioridad por el bit de mayor peso.

Ejemplo 4.11
Os proponemos que diseñéis un codificador 4 a 2 con entradas por lógica negativa,
salidas por lógica positiva y prioridad por el bit de mayor peso. El código utilizado es el
Gray.

Una vez diseñado el circuito codificador os proponemos que hagáis las modificaciones
necesarias si al circuito le añadimos una señal de validación ENABLE que sea activa
por lógica negativa.

Más adelante veremos el uso de codificadores para facilitar la implementación de


aplicaciones complejas. No obstante, vamos a comentar un ejemplo de utilización
relativamente simple para poder imaginarnos posibles usos reales.

Ejemplo 4.12
Supongamos que tenemos que diseñar un sistema que informe de la cantidad de
combustible que hay en el interior de un depósito. Disponemos de 7 sensores que al
entrar en contacto con un líquido entonces facilitan un 1 lógico, mientras que en caso
contrario dan un 0 lógico. El esquema de los sensores que se ubican para detectar la
cantidad de combustible se muestra en la siguiente figura:

20
Introducción a los ordenadores

S6
S5
S4
S3
S2
S1
S0

Figura 4.22. Sensores para detectar el nivel de combustible de un depósito. Los sensores facilitan
un 1 si están en contacto con un líquido o bien 0 en caso contrario. Según la figura y suponiendo
que el combustible líquido se encuentra entre el sensor S4 y el sensor S5 entonces los sensores
S0 hasta S4 darían un 1 lógico mientras que el resto darían un 0 lógico.

Para resolver el problema simplemente tenemos que usar un codificador 8 a 3 con


prioridad por el bit de mayor peso en el que conectaremos los valores que facilitan los 7
sensores. La idea es que a la salida del codificador tengamos un código que nos diga
exactamente hasta qué sensor cubre el combustible y por consiguiente el nivel de
combustible del depósito.

No obstante, tenemos 8 entradas en el codificador y tan solo 7 sensores. Entonces,


¿cómo los tenemos que conectar? De hecho, vamos a ver un posible truco que facilita
la implementación cuando tenemos más entradas que valores a conectar.

A la entrada de menor peso del codificador conectaremos el sensor S0, pero


complementado. El motivo es que si todos los sensores, incluido S0, están inactivos
significará que no hay combustible dentro del depósito y en este caso nos interesa que
el codificador responda con la combinación 000. Efectivamente vemos que cuando no
haya combustible, el valor complementado de S0 será 1 que aplicado a la entrada de
menor peso del codificador forzará el 000 a su salida. Cuando exista combustible y éste
alcance a cubrir cualquier sensor, como que el codificador funciona por prioridad del bit
de mayor peso, a la salida tendremos el código correspondiente al sensor, pudiendo
saber con exactitud hasta qué sensor cubre el combustible.

D7
D6
D5 Q2 Q2
D4
Q1 Q1
D3
Q0 Q0
D2
D1
D0

Figura 4.23. Conexión de los sensores del depósito de combustible a un codificador para
determinar el nivel de combustible.

Al fin y al cabo se trata de una solución que evita la necesidad de añadir una señal que
controle la situación en la que todas las entradas del codificador estén inactivas, similar
al caso que habíamos visto anteriormente en la Figura 4.16. Esto lo hemos podido hacer
al disponer de menos señales de activación que valores de entrada admite el codificador
escogido.

Comentar finalmente que, si los sensores hubieran funcionado de manera inversa, es


decir dando un 0 lógico cuando están en contacto con un líquido y un 1 lógico en caso
contrario, simplemente la solución podría ser la misma pero entonces habríamos tenido
que elegir un codificador con entradas por lógica negativa.

21
Introducción a los ordenadores

4.3. Decodificadores

Un decodificador es un bloque funcional en el que, dada una combinación binaria de


entrada, se activa la salida correspondiente a su equivalente decimal.

Ejemplo 4.13
Un decodificador 3 a 8 presenta 3 líneas de entrada y 8 líneas de salida. En las líneas
de entrada se especifica una combinación binaria, por defecto y si no se dice lo contrario
según el código binario natural. El resultado será que todas las líneas de salida
responderán con un 0 excepto la que se corresponda al valor decimal especificado
según la combinación de entrada, es decir por ejemplo si las entradas valen 011
entonces la línea de salida que se activará será la 3.

Q0
Q1
D0 Q2
Q3
D1
Q4
D2
Q5
Q6
Q7

Figura 4.24. Decodificador 3 a 8 con entradas y salidas por lógica positiva.

Al tratarse de un elemento combinacional, su comportamiento queda perfectamente


definido por la tabla de verdad que indique el valor que toman las salidas para todas las
combinaciones de entrada.

𝐷𝐷2 𝐷𝐷1 𝐷𝐷0 𝑄𝑄7 𝑄𝑄6 𝑄𝑄5 𝑄𝑄4 𝑄𝑄3 𝑄𝑄2 𝑄𝑄1 𝑄𝑄0
0 0 0 0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 1 0 0
0 1 1 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 0 0 0
1 0 1 0 0 1 0 0 0 0 0
1 1 0 0 1 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0

Tabla 4.19. Tabla de verdad de un decodificador 3 a 8 con entradas y salidas por lógica positiva.

Si identificamos las funciones lógicas de las salidas en forma canónica de minterms,


vemos que éstas son la combinación binaria correspondiente a dicha salida, es decir
���2 × 𝐷𝐷
𝑄𝑄0 = ∑3(0) = 𝐷𝐷 ���1 × ���
𝐷𝐷0 , 𝑄𝑄1 = ∑3(1) = ��� ���1 × 𝐷𝐷0 , 𝑄𝑄2 = ∑3(2) = 𝐷𝐷
𝐷𝐷2 × 𝐷𝐷 ���2 × 𝐷𝐷1 × ���
𝐷𝐷0 , …
, 𝑄𝑄7 = ∑3(7) = 𝐷𝐷2 × 𝐷𝐷1 × 𝐷𝐷0 .

22
Introducción a los ordenadores

Q0

D0 Q1

D1 Q2

D2 ...

Q7

Figura 4.25. Implementación de un decodificador 3 a 8 con entradas y salidas por lógica positiva.

El código correspondiente a la descripción en VHDL de un decodificador 3 a 8 con


entradas y salidas por lógica positiva podría ser el siguiente:

library ieee;
use ieee.std_logic_1164.all;

entity Ejemplo_4_13 is

port (
D : in std_logic_vector(2 downto 0);
Q : out std_logic_vector(7 downto 0));

end Ejemplo_4_13;

architecture dataflow of Ejemplo_4_13 is

begin

Q <= "00000001" when D = "000" else


"00000010" when D = "001" else
"00000100" when D = "010" else
"00001000" when D = "011" else
"00010000" when D = "100" else
"00100000" when D = "101" else
"01000000" when D = "110" else
"10000000" when D = "111" else
"00000000";

end dataflow;

A continuación podemos ver el resultado de la simulación del bloque anterior con el


Quartus Prime, donde se observa el correcto funcionamiento del decodificador.

23
Introducción a los ordenadores

Figura 4.26. Simulación de la entidad Ejemplo_4_13 correspondiente a un decodificador 3 a 8 con


entradas y salidas por lógica positiva.

Como hemos visto en el ejemplo anterior, un decodificador presenta un funcionamiento


y una representación gráfica dual a la de los codificadores. Igualmente pueden existir
variantes en función de si las entradas funcionan en lógica positiva o bien en lógica
negativa, si las salidas funcionan en una u otra lógica, si se utiliza el código binario
natural para indicar la salida que se ha de activar u otro código binario como podría ser
el Gray o BCD, etc.

Ejemplo 4.14
Vamos a diseñar ahora un decodificador 3 a 8 pero en el que las líneas de entrada
funcionen por lógica positiva y las de salida por lógica negativa.

Q0
Q1
Q2
D0 Q3
D1 Q4
D2 Q5
Q6
Q7

Figura 4.27. Decodificador 3 a 8 con entradas por lógica positiva y salidas por lógica negativa.

Partiremos de la tabla de verdad que especifique su comportamiento. Ésta será


equivalente a la del ejemplo anterior con la salvedad que para cada combinación de
entrada tendremos que la salida activa valdrá 0 y las restantes estarán a 1.

24
Introducción a los ordenadores

𝐷𝐷2 𝐷𝐷1 𝐷𝐷0 𝑄𝑄7 𝑄𝑄6 𝑄𝑄5 𝑄𝑄4 𝑄𝑄3 𝑄𝑄2 𝑄𝑄1 𝑄𝑄0
0 0 0 1 1 1 1 1 1 1 0
0 0 1 1 1 1 1 1 1 0 1
0 1 0 1 1 1 1 1 0 1 1
0 1 1 1 1 1 1 0 1 1 1
1 0 0 1 1 1 0 1 1 1 1
1 0 1 1 1 0 1 1 1 1 1
1 1 0 1 0 1 1 1 1 1 1
1 1 1 0 1 1 1 1 1 1 1

Tabla 4.20. Tabla de verdad de un decodificador 3 a 8 con entradas por lógica positiva y salidas
por lógica negativa.

En este caso es más fácil deducir las expresiones correspondientes a las salidas
mediante la forma canónica de maxterms, con lo que 𝑄𝑄0 = ∏3(0) = 𝐷𝐷2 + 𝐷𝐷1 + 𝐷𝐷0 , 𝑄𝑄1 =
���0 , 𝑄𝑄2 = ∏3(2) = 𝐷𝐷2 + 𝐷𝐷
∏3(1) = 𝐷𝐷2 + 𝐷𝐷1 + 𝐷𝐷 ���1 + 𝐷𝐷0 , … , 𝑄𝑄7 = ∏3(7) = ��� ���1 + 𝐷𝐷
𝐷𝐷2 + 𝐷𝐷 ���0 .
De este modo la implementación es inmediata mediante puertas OR, tal y como
podemos ver en la siguiente figura.

Q0

D0 Q1

D1 Q2

D2 ...

Q7

Figura 4.28. Implementación de un decodificador 3 a 8 con entradas por lógica positiva y salidas
por lógica negativa.

Ejemplo 4.15
Como hemos comentado no todos los decodificadores funcionan según el código binario
natural. Vamos a diseñar a continuación un decodificador 4 a 10 con entradas según el
código BCD. Además, añadiremos una entrada de validación o ENABLE. Tanto las
entradas como las salidas funcionan por lógica positiva.

Q0
Q1
Q2
D0 Q3
D1 Q4
BCD

D2 Q5
D3 Q6
Q7
Q8
E Q9

Figura 4.29. Decodificador 4 a 10 con entradas y salidas por lógica positiva. El código de entrada
es BCD y dispone de una entrada de validación.

25
Introducción a los ordenadores

La tabla de verdad dispone de 5 entradas: las 4 operativas con las que se especifica el
código BCD y la de control ENABLE. Vemos que será un decodificador incompleto al
trabajar con el código BCD, en tanto que existen posibles combinaciones de entrada
sobre las que no tiene sentido especificar ninguna combinación concreta de salida.

𝐸𝐸 𝐷𝐷3 𝐷𝐷2 𝐷𝐷1 𝐷𝐷0 𝑄𝑄9 𝑄𝑄8 𝑄𝑄7 𝑄𝑄6 𝑄𝑄5 𝑄𝑄4 𝑄𝑄3 𝑄𝑄2 𝑄𝑄1 𝑄𝑄0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 1 0 0 0 0 0 0 0 0 1 0
1 0 0 1 0 0 0 0 0 0 0 0 1 0 0
1 0 0 1 1 0 0 0 0 0 0 1 0 0 0
1 0 1 0 0 0 0 0 0 0 1 0 0 0 0
1 0 1 0 1 0 0 0 0 1 0 0 0 0 0
1 0 1 1 0 0 0 0 1 0 0 0 0 0 0
1 0 1 1 1 0 0 1 0 0 0 0 0 0 0
1 1 0 0 0 0 1 0 0 0 0 0 0 0 0
1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
0 X X X X 0 0 0 0 0 0 0 0 0 0
otras combinaciones X X X X X X X X X X

Tabla 4.21. Tabla de verdad de un decodificador 4 a 10 con entradas y salidas por lógica positiva.
El código de entrada es BCD y dispone de una entrada de validación.

Para determinar las funciones que implementan cada una de las salidas podemos
considerar sólo las entradas operativas y posteriormente implementar la validación
según hemos visto al inicio del tema, es decir, aplicando una puerta AND “justo antes”
de cada una de las salidas en tanto que la entrada de validación y las salidas son activas
por lógica positiva.

Las funciones de cada una de las salidas por consiguiente tomarán la siguiente forma:
���3 × ���
𝑄𝑄0 = (𝐷𝐷 ���1 × ���
𝐷𝐷2 × 𝐷𝐷 ���3 × ���
𝐷𝐷0 ) × 𝐸𝐸 ,𝑄𝑄1 = (𝐷𝐷 𝐷𝐷2 × ���
𝐷𝐷1 × 𝐷𝐷0 ) × 𝐸𝐸 ,
���3 × ���
𝑄𝑄2 = (𝐷𝐷 𝐷𝐷2 × 𝐷𝐷1 × ���
𝐷𝐷0 ) × 𝐸𝐸 , … , 𝑄𝑄9 = (𝐷𝐷3 × ��� ���1 × 𝐷𝐷0 ) × 𝐸𝐸.
𝐷𝐷2 × 𝐷𝐷

Q0
D0

D1 Q1

D2
Q2
D3
...
E
Q9

Figura 4.30. Implementación de un decodificador 4 a 10 con entradas y salidas por lógica positiva.
El código de entrada es BCD y dispone de una entrada de validación.

Este decodificador es fácilmente escalable. Supongamos ahora que nos hubieran


pedido diseñar un decodificador cuya entrada fuera un código BCD de 3 dígitos. El
problema que nos encontramos es que tendremos 12 líneas de entrada, 4 por cada
dígito BCD, a las que les corresponden 1000 combinaciones distintas que van desde el
número decimal 000 hasta el 999. Como podéis suponer ni existe en el mercado ningún

26
Introducción a los ordenadores

decodificador con 1000 pines de salida ni tendría sentido plantearlo con una tabla de
verdad como las anteriores. La solución óptima pasaría por utilizar simplemente 3
decodificadores como los de este problema, uno para cada posible dígito de entrada.

De hecho, es habitual crear bloques funcionales “grandes” a partir de otros más


“pequeños”. En este último ejemplo la solución es directa, puesto que la señal de
entrada fácilmente se encuentra dividida en tres grupos de 4 bits, los cuales se aplican
a cada uno de los tres decodificadores. No obstante, esto no siempre es tan directo y a
veces se tiene que hacer uso de las posibles entradas de validación o ENABLE.

Ejemplo 4.16
Supongamos que disponemos de decodificadores en binario natural 3 a 8 con entrada
de validación ENABLE, cuyas entradas funcionan por lógica positiva y las salidas por
lógica negativa, con el que nos piden crear un decodificador 5 a 32.

Y0
Y1
X0 Y2
Y3
X1
Y4
X2
X3 Y5
X4 Y6
Y7
Y8
Y9
Y10
...
Y30
ENABLE Y31

Figura 4.31. Decodificador 5 a 32 con entradas por lógica positiva y salidas por lógica negativa.

Como sólo disponemos de decodificadores con 8 salidas, tendremos que hacer uso de
4 de éstos para lograr abarcar las 32 salidas necesarias. La clave está en cómo
determinar sobre cuál actuar en función del valor de entrada. Imaginemos distintos
casos.

Si el número de entrada está entre el 0 y el 7 tendremos que actuar sobre el primer


decodificador y los restantes decodificadores tendrían que quedar deshabilitados para
que no se active ninguna de sus salidas. En cambio, si el número de entrada está entre
el 8 y el 15 tendremos que actuar sobre el segundo decodificador, dejando el resto
deshabilitados. Si por el contrario ahora el número está entre el 16 y 23 actuaremos
sobre el tercer decodificador y los restantes quedarán deshabilitados. Y finalmente si el
número es una de las 8 últimas combinaciones actuaremos sobre el último decodificador
y los otros los dejaremos deshabilitados. Así pues, la clave está en crear un sistema
combinacional para cada decodificador que actúe sobre su entrada de validación o
ENABLE con el propósito que éste sepa si ha de funcionar o bien quedar deshabilitado.

Si nombramos 𝑄𝑄𝑄𝑄𝑖𝑖 a la salida i-ésima del primer decodificador y 𝐸𝐸𝐸𝐸 a su entrada de


validación, 𝑄𝑄𝑄𝑄𝑖𝑖 y 𝐸𝐸𝐸𝐸 a las del segundo, 𝑄𝑄𝐶𝐶𝑖𝑖 y 𝐸𝐸𝐸𝐸 a las del tercero y 𝑄𝑄𝑄𝑄𝑖𝑖 y 𝐸𝐸𝐸𝐸 a las del
cuarto, la idea sería que las salidas del primer decodificador, 𝑄𝑄𝑄𝑄[7. .0], fuesen las salidas
de menos peso del decodificador a diseñar de 32 salidas, 𝑌𝑌[7. .0]; que las salidas del
segundo decodificador, 𝑄𝑄𝑄𝑄[7. .0], fuesen las salidas 𝑌𝑌[15. .8]; que las salidas 𝑄𝑄𝑄𝑄[7. .0]

27
Introducción a los ordenadores

del tercer decodificador fuesen 𝑌𝑌[23. .16]; y que las salidas 𝑄𝑄𝑄𝑄[7. .0] del cuarto
decodificador fuesen 𝑌𝑌[31. .24]. Entonces obtendríamos la siguiente tabla de verdad.

𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸𝐸 𝑋𝑋4 𝑋𝑋3 𝑋𝑋2 𝑋𝑋1 𝑋𝑋0 𝐸𝐸𝐸𝐸 𝐸𝐸𝐸𝐸 𝐸𝐸𝐸𝐸 𝐸𝐸𝐸𝐸 𝑄𝑄𝑖𝑖 = 0
1 0 0 0 0 0 0 0 0 1 𝑄𝑄𝑄𝑄0 = 𝑌𝑌0
1 0 0 0 0 1 0 0 0 1 𝑄𝑄𝑄𝑄1 = 𝑌𝑌1
1 0 0 0 1 0 0 0 0 1 𝑄𝑄𝑄𝑄2 = 𝑌𝑌2
1 0 0 0 1 1 0 0 0 1 𝑄𝑄𝑄𝑄3 = 𝑌𝑌3
1 0 0 1 0 0 0 0 0 1 𝑄𝑄𝑄𝑄4 = 𝑌𝑌4
1 0 0 1 0 1 0 0 0 1 𝑄𝑄𝑄𝑄5 = 𝑌𝑌5
1 0 0 1 1 0 0 0 0 1 𝑄𝑄𝑄𝑄6 = 𝑌𝑌6
1 0 0 1 1 1 0 0 0 1 𝑄𝑄𝑄𝑄7 = 𝑌𝑌7
1 0 1 0 0 0 0 0 1 0 𝑄𝑄𝑄𝑄0 = 𝑌𝑌8
1 0 1 0 0 1 0 0 1 0 𝑄𝑄𝑄𝑄1 = 𝑌𝑌9
1 0 1 0 1 0 0 0 1 0 𝑄𝑄𝑄𝑄2 = 𝑌𝑌10

1 0 1 1 1 0 0 0 1 0 𝑄𝑄𝑄𝑄6 = 𝑌𝑌14
1 0 1 1 1 1 0 0 1 0 𝑄𝑄𝑄𝑄7 = 𝑌𝑌15
1 1 0 0 0 0 0 1 0 0 𝑄𝑄𝑄𝑄0 = 𝑌𝑌16
1 1 0 0 0 1 0 1 0 0 𝑄𝑄𝑄𝑄1 = 𝑌𝑌17
1 1 0 0 1 0 0 1 0 0 𝑄𝑄𝑄𝑄2 = 𝑌𝑌18

1 1 0 1 1 0 0 1 0 0 𝑄𝑄𝑄𝑄6 = 𝑌𝑌22
1 1 0 1 1 1 0 1 0 0 𝑄𝑄𝑄𝑄7 = 𝑌𝑌23
1 1 1 0 0 0 1 0 0 0 𝑄𝑄𝑄𝑄0 = 𝑌𝑌24
1 1 1 0 0 1 1 0 0 0 𝑄𝑄𝑄𝑄1 = 𝑌𝑌25

1 1 1 1 1 1 1 0 0 0 𝑄𝑄𝑄𝑄7 = 𝑌𝑌31
0 X X X X X 0 0 0 0 ninguna

Tabla 4.22. Tabla de verdad de un decodificador 5 a 32 con entradas por lógica positiva y salidas
por lógica negativa a partir de 4 decodificadores 3 a 8 del mismo tipo. En la tabla se indica cómo
se ha de actuar sobre las entradas de validación 𝑬𝑬𝑬𝑬, 𝑬𝑬𝑬𝑬, 𝑬𝑬𝑬𝑬, 𝑬𝑬𝑬𝑬 de los decodificadores 3 a 8 para
saber si se han de activar o no. Igualmente se indica de todas las salidas de todos los
decodificadores, aquella que se tiene que poner a 0, quedando todas las restantes a 1, puesto que
los decodificadores tienen las salidas activas por lógica negativa.

Como podemos ver, la señal de validación de cada uno de los cuatro decodificadores 3
a 8 viene determinada en función de las entradas operativas de mayor peso
𝑋𝑋4 y 𝑋𝑋3 , mientras que las entradas operativas de menor peso 𝑋𝑋2 , 𝑋𝑋1 y 𝑋𝑋0 indican
directamente la salida del decodificador 3 a 8 que está a cero. Es decir, cuando 𝑋𝑋4 = 0
y 𝑋𝑋3 = 0 entonces 𝐸𝐸𝐸𝐸 = 1 y la salida del primer decodificador 3 a 8 que se active será
la que marquen las entradas 𝑋𝑋2 , 𝑋𝑋1 y 𝑋𝑋0 . Cuando 𝑋𝑋4 = 0 y 𝑋𝑋3 = 1 entonces 𝐸𝐸𝐸𝐸 = 1 y la
salida del segundo decodificador 3 a 8 que se active será la que marquen las entradas
𝑋𝑋2 , 𝑋𝑋1 y 𝑋𝑋0 . Cuando 𝑋𝑋4 = 1 y 𝑋𝑋3 = 0 entonces ocurre lo mismo para el tercer
decodificador 3 a 8 con 𝐸𝐸𝐸𝐸 = 1. Finalmente cuando 𝑋𝑋4 = 1 y 𝑋𝑋3 = 1 entonces ocurre lo
mismo para el último decodificador 3 a 8 con 𝐸𝐸𝐸𝐸 = 1. Así pues, ya sabemos cómo
generar las señales de validación de los 4 decodificadores a partir de estas dos
entradas. Bastaría diseñar un pequeño sistema combinacional con puertas lógicas de 2
entradas, 𝑋𝑋4 y 𝑋𝑋3 , y 4 salidas, 𝐸𝐸𝐸𝐸, 𝐸𝐸𝐸𝐸, 𝐸𝐸𝐸𝐸 y 𝐸𝐸𝐸𝐸, pero observando la tabla de verdad
vemos que este sistema combinacional se puede implementar directamente con un
decodificador 2 a 4 con entradas y salidas por lógica positiva en el que se apliquen como

28
Introducción a los ordenadores

entradas 𝑋𝑋4 y 𝑋𝑋3 , de tal manera que cada una de las salidas de este decodificador sea
respectivamente las señales 𝐸𝐸𝐸𝐸, 𝐸𝐸𝐸𝐸, 𝐸𝐸𝐸𝐸 y 𝐸𝐸𝐸𝐸.

Q0 Y0 Q0 Y8
Q1 Y1 Q1 Y9
D0 Q2 Y2 D0 Q2 Y10
X0 X0
Q3 Y3 Q3 Y11
X1 D1 X1 D1
Q4 Y4 Q4 Y12
X2 D2 X2 D2
Q5 Y5 Q5 Y13
Q6 Y6 Q6 Y14
EA E Q7 Y7 EB E Q7 Y15

Q0 Y16 Q0 Y24
Q1 Y17 Q1 Y25
D0 Q2 Y18 D0 Q2 Y26
X0 X0
Q3 Y19 Q3 Y27
X1 D1 X1 D1
Q4 Y20 Q4 Y28
X2 D2 X2 D2
Q5 Y21 Q5 Y29
Q6 Y22 Q6 Y30
EC E Q7 Y23 ED E Q7 Y31

D0 EA
X3 Q0 D1 EB
X4 Q1 D2 EC
D3 ED
ENABLE E

Figura 4.32. Implementación de un decodificador 5 a 32 con entradas por lógica positiva y salidas
por lógica negativa a partir de 4 decodificadores 3 a 8 que se habilitan según las entradas
operativas de mayor peso, según un decodificador 2 a 4.

En este ejemplo hemos visto dos conceptos interesantes que vale la pena enfatizar.

Por un lado, el concepto de escalabilidad mediante las señales de validación o ENABLE.


La idea básica es que cuando tenemos que crear bloques “grandes” podemos utilizar
bloques “más pequeños” los cuales se activan o no en función del valor de las entradas
de mayor peso. Este principio es muy utilizado en sistemas digitales. Por ejemplo,
muchas memorias digitales, como las memorias RAM, pueden crearse utilizando el
mismo principio. Es decir, si tenemos que crear una memoria de 4G seguramente
podemos recurrir a 4 módulos de 1G y simplemente habilitaremos uno u otro en función
del dato al que queremos acceder, habilitando una u otra memoria. Este principio lo
iremos trabajando más adelante.

El otro concepto es el hecho de haber utilizado un decodificador 2 a 4 para implementar


las 4 señales de validación de los decodificadores 3 a 8, con lo que se puede deducir
que un decodificador es un elemento que permite crear una función lógica. Este
concepto sí que lo vamos a trabajar más en profundidad en este mismo tema.

29
Introducción a los ordenadores

4.3.1. Implementación de funciones lógicas con


decodificadores
Una aplicación específica de los decodificadores es la posibilidad de utilizarse para
implementar funciones lógicas. La idea es que su uso puede evitar la necesidad de
utilizar puertas lógicas o, al menos, un número considerable de éstas. Una posible
sistemática para realizar estas implementaciones es la siguiente:

• Buscamos un decodificador binario natural con tantas entradas como variables


de entrada tenga nuestra función lógica. Puede tener las salidas en lógica
positiva o bien en lógica negativa.
• Expresamos la función lógica en forma canónica de minterms si las salidas del
decodificador funcionan por lógica positiva o bien en forma canónica de
maxterms si funcionan por lógica negativa.
• Si las salidas del decodificador funcionan por lógica positiva se implementa una
suma lógica (OR) de todas las salidas del decodificador correspondientes a las
combinaciones de entrada de la forma canónica de minterms. Si las salidas
funcionan por lógica negativa entonces se implementa un producto lógico (AND)
de las salidas del decodificador correspondientes a las combinaciones de
entrada de la forma canónica de maxterms.

Con los siguientes ejemplos quedará más claro este proceso. Con los primeros ejemplos
veremos que existen muchas combinaciones posibles para implementar una cierta
función lógica con decodificadores, por lo que es importante al final del ejercicio siempre
intentar razonar y comprobar que la solución hallada funciona correctamente.

Ejemplo 4.17
El objetivo es implementar con un decodificador binario natural con salidas en lógica
positiva la función 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 × 𝑐𝑐̅.

Primero desarrollaremos la función para expresarla en forma canónica de minterms,


obteniendo 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = (𝑎𝑎 + 𝑎𝑎�) × 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 × �𝑏𝑏 + 𝑏𝑏�� × 𝑐𝑐̅ = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎� × 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 ×
𝑏𝑏 × 𝑐𝑐̅ + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐̅ = ∑3(5,1,6,4).

Por consiguiente, simplemente tenemos que unir con una OR las salidas del
decodificador correspondientes a las combinaciones 1, 4, 5 y 6.

Q0
Q1
Q2 f
c D0
Q3
b D1
a Q4
D2
Q5
Q6
Q7

� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄� con un decodificador con


Figura 4.33. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = 𝒃𝒃
salidas en lógica positiva.

30
Introducción a los ordenadores

Ejemplo 4.18
Implementaremos con un decodificador binario natural con salidas en lógica negativa la
misma función 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 × 𝑐𝑐̅.

En este caso tenemos que hallar la función en forma canónica de maxterms obteniendo
la siguiente expresión 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = �𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎� × �𝑏𝑏� × 𝑐𝑐 + 𝑐𝑐̅� = �𝑏𝑏� + 𝑎𝑎� × (𝑐𝑐 + 𝑎𝑎) × �𝑏𝑏� +
𝑐𝑐̅� × (𝑐𝑐 + 𝑐𝑐̅) = �𝑏𝑏� + 𝑎𝑎 + 𝑐𝑐 × 𝑐𝑐̅� × �𝑐𝑐 + 𝑎𝑎 + 𝑏𝑏 × 𝑏𝑏�� × �𝑏𝑏� + 𝑐𝑐̅ + 𝑎𝑎 × 𝑎𝑎�� = �𝑎𝑎 + 𝑏𝑏� + 𝑐𝑐� × �𝑎𝑎 +
𝑏𝑏� + 𝑐𝑐̅� × (𝑎𝑎 + 𝑏𝑏 + 𝑐𝑐) × �𝑎𝑎 + 𝑏𝑏� + 𝑐𝑐� × �𝑎𝑎 + 𝑏𝑏� + 𝑐𝑐̅� × �𝑎𝑎� + 𝑏𝑏� + 𝑐𝑐̅� = �𝑎𝑎 + 𝑏𝑏� + 𝑐𝑐� × �𝑎𝑎 + 𝑏𝑏� +
𝑐𝑐̅� × (𝑎𝑎 + 𝑏𝑏 + 𝑐𝑐) × �𝑎𝑎� + 𝑏𝑏� + 𝑐𝑐̅� = ∏3(2,3,0,7). Como era de esperar hemos obtenido las
combinaciones de entrada complementarias a las del ejemplo anterior. En este caso
tenemos que unir las salidas 0, 2, 3 y 7 mediante un producto lógico (AND) y habremos
obtenido una implementación de dicha función.

Q0
Q1 f
D0 Q2
c
Q3
b D1
a Q4
D2
Q5
Q6
Q7

� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄� con un decodificador con


Figura 4.34. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = 𝒃𝒃
salidas en lógica negativa.

Ejemplo 4.19
Implementaremos con un decodificador binario natural con entradas y salidas en lógica
negativa la función anterior 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 × 𝑐𝑐̅.

El hecho que las entradas de un decodificador estén en lógica negativa tan sólo conlleva
que tengamos que invertir el orden de líneas de salida, puesto que si por ejemplo antes
una combinación 000 activaba la primera línea de salida ahora activará la última. Así
pues, si antes uníamos con una AND las líneas 0, 2, 3 y 7 ahora uniremos las líneas 7
en vez de la 0, 5 en vez de la 2, 4 en vez de la 3 y 0 en vez de la 7.

Q0
Q1
Q2 f
c D0
Q3
b D1
a Q4
D2
Q5
Q6
Q7

� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄� con un decodificador con


Figura 4.35. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = 𝒃𝒃
entradas y salidas en lógica negativa.

También es posible implementar funciones lógicas con decodificadores que tengan un


número de entradas menor al número de variables de la función. En este caso
simplemente tenemos que decidir cuáles son las variables que se aplican a la entrada

31
Introducción a los ordenadores

del decodificador y el resto veremos que afectan al sistema combinacional de salida del
decodificador.

El proceso es similar al anterior, pero en este caso, una vez obtenida la forma canónica,
tenemos que separar de ella las variables que no se aplicarán a las entradas del
decodificador, puesto que se tendrán que aplicar a las salidas. Veámoslo con algunos
ejemplos.

Ejemplo 4.20
Implementaremos con un decodificador binario natural 2 a 4 con salidas en lógica
positiva la función 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = 𝑎𝑎 × 𝑏𝑏� + 𝑎𝑎 × 𝑐𝑐.

Primero hallamos la expresión en forma canónica de minterms, obteniendo 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) =
𝑎𝑎 × 𝑏𝑏� × (𝑐𝑐 + 𝑐𝑐̅) + 𝑎𝑎 × �𝑏𝑏 + 𝑏𝑏�� × 𝑐𝑐 = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐̅ + 𝑎𝑎 × 𝑏𝑏 × 𝑐𝑐 + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 = 𝑎𝑎 ×
𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐̅ + 𝑎𝑎 × 𝑏𝑏 × 𝑐𝑐.

Llegado este punto tenemos que elegir un par de variables de entrada para aplicar al
decodificador. Supongamos que elegimos las variables 𝑎𝑎 y 𝑏𝑏. En este caso la expresión
la podemos reescribir de la siguiente manera, agrupando los términos iguales que
dependan de las variables 𝑎𝑎 y 𝑏𝑏, 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = 𝑎𝑎 × 𝑏𝑏� × [𝑐𝑐] + 𝑎𝑎 × 𝑏𝑏� × [𝑐𝑐̅] + 𝑎𝑎 × 𝑏𝑏 × [𝑐𝑐] =
𝑎𝑎 × 𝑏𝑏� × [𝑐𝑐 + 𝑐𝑐̅] + 𝑎𝑎 × 𝑏𝑏 × [𝑐𝑐] = 𝑎𝑎 × 𝑏𝑏� × [1] + 𝑎𝑎 × 𝑏𝑏 × [𝑐𝑐].

Al igual que en los ejemplos anteriores esta función nos indica cuáles son las salidas
del decodificador que tenemos que unir con una puerta OR (𝑎𝑎 × 𝑏𝑏� correspondiente a la
salida 2 y 𝑎𝑎 × 𝑏𝑏 correspondiente a la salida 3), pero además nos indica que ha de
hacerse el producto lógico entre esta última línea y la variable restante 𝑐𝑐.

Q0
b D0 Q1
a D1 Q2 f
Q3

� + 𝒂𝒂 × 𝒄𝒄 con un decodificador 2 a 4 con


Figura 4.36. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = 𝒂𝒂 × 𝒃𝒃
salidas en lógica positiva, aplicando a las entradas del decodificador las variables 𝒂𝒂 y 𝒃𝒃.

Si en cambio hubiésemos elegido las variables 𝑎𝑎 y 𝑐𝑐 para aplicar a la entrada del


decodificador, hubiéramos obtenido la siguiente expresión 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = 𝑎𝑎 × 𝑐𝑐 × �𝑏𝑏�� +
𝑎𝑎 × 𝑐𝑐̅ × �𝑏𝑏�� + 𝑎𝑎 × 𝑐𝑐 × [𝑏𝑏] = 𝑎𝑎 × 𝑐𝑐 × [𝑏𝑏� + 𝑏𝑏] + 𝑎𝑎 × 𝑐𝑐̅ × �𝑏𝑏�� = 𝑎𝑎 × 𝑐𝑐 × [1] + 𝑎𝑎 × 𝑐𝑐̅ × �𝑏𝑏��, cuya
implementación sería:

Q0
c D0 Q1
a D1 Q2 f
Q3

� + 𝒂𝒂 × 𝒄𝒄 con un decodificador 2 a 4 con


Figura 4.37. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = 𝒂𝒂 × 𝒃𝒃
salidas en lógica positiva, aplicando a las entradas del decodificador las variables 𝒂𝒂 y 𝒄𝒄.

32
Introducción a los ordenadores

Ejemplo 4.21
Implementaremos con un decodificador binario natural 2 a 4 con salidas en lógica
positiva la función 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐, 𝑑𝑑) = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 × 𝑐𝑐 × 𝑑𝑑̅.

Como siempre primero buscamos la forma canónica de esta función, obteniendo


𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐, 𝑑𝑑) = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × �𝑑𝑑 + 𝑑𝑑̅� + 𝑎𝑎 × �𝑏𝑏 + 𝑏𝑏�� × 𝑐𝑐 × 𝑑𝑑̅ = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑 + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 ×
𝑑𝑑̅ + 𝑎𝑎 × 𝑏𝑏 × 𝑐𝑐 × 𝑑𝑑̅ + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑̅ = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑 + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑̅ + 𝑎𝑎 × 𝑏𝑏 × 𝑐𝑐 × 𝑑𝑑̅.

Como el decodificador sólo dispone de dos entradas tenemos que elegir un par de
variables de la función con las que identificaremos los términos de salida que tenemos
que unir con una suma lógica (OR), así como las posibles expresiones que dependan
del resto de variables y que modificarán las correspondientes líneas de salida.
Supongamos que elegimos como variables 𝑎𝑎 y 𝑏𝑏; entonces quedaría 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐, 𝑑𝑑) =
𝑎𝑎 × 𝑏𝑏� × �𝑐𝑐 × 𝑑𝑑 + 𝑐𝑐 × 𝑑𝑑̅� + 𝑎𝑎 × 𝑏𝑏 × �𝑐𝑐 × 𝑑𝑑̅� = 𝑎𝑎 × 𝑏𝑏� × [𝑐𝑐] + 𝑎𝑎 × 𝑏𝑏 × �𝑐𝑐 × 𝑑𝑑̅ �.

Esta expresión nos indica que tenemos que unir con una OR las salidas 2 y 3 del
decodificador correspondientes a los términos 𝑎𝑎 × 𝑏𝑏� y 𝑎𝑎 × 𝑏𝑏 respectivamente, pero antes
hemos de modificar dichas líneas haciendo el producto lógico por las expresiones 𝑐𝑐 y
𝑐𝑐 × 𝑑𝑑̅, respectivamente.

Q0
b D0 Q1
a D1 Q2
f
Q3

� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄 × 𝒅𝒅
Figura 4.38. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄, 𝒅𝒅) = 𝒂𝒂 × 𝒃𝒃 � con un decodificador 2
a 4 con salidas en lógica positiva, aplicando a las entradas del decodificador las variables 𝒂𝒂 y 𝒃𝒃.

Os proponemos que sobre este mismo ejemplo miréis de hacer distintas


implementaciones. Por ejemplo, utilizando un decodificador 2 a 4 con salidas en lógica
positiva, pero eligiendo otras variables como entradas del decodificador; utilizando un
decodificador 3 a 8 con salidas en lógica positiva y luego con salidas en lógica negativa;
etc.

Ejemplo 4.22
Os proponemos que intentéis hallar una posible implementación de la función
𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = (𝑎𝑎 + 𝑏𝑏) × (𝑎𝑎� + 𝑐𝑐).

a) Con un decodificador binario natural 3 a 8 con salidas en lógica negativa.


b) Con un decodificador binario natural 3 a 8 con salidas en lógica positiva.
c) Con un decodificador binario natural 2 a 4 con salidas en lógica negativa.
d) Con un decodificador binario natural 2 a 4 con salidas en lógica positiva.

33
Introducción a los ordenadores

4.4. Multiplexores

Un multiplexor es un bloque funcional que selecciona, por medio de 𝑁𝑁 líneas de control,


una de entre 2𝑁𝑁 líneas de entrada de datos y envía esa información a una única línea
de salida.

Los multiplexores presentan por consiguiente líneas operativas, para los datos, y líneas
de control, para seleccionar la línea de entrada que será enviada a la salida.
Generalmente los multiplexores trabajan en lógica positiva.

D0
D1
D2
Q
...
D2 N-1
EN-1 ... E1 E0

Figura 4.39. Esquema de un multiplexor genérico con N líneas de selección.

El comportamiento del dispositivo es el siguiente. Las 𝑁𝑁 líneas de selección indican


𝑖𝑖=𝑁𝑁−1
según el código binario natural la entrada a seleccionar, es decir 𝐸𝐸 = ∑𝑖𝑖=0 𝐸𝐸𝑖𝑖 × 2𝑖𝑖 |𝐸𝐸𝑖𝑖 ∈
{0,1}, de tal manera que entonces 𝑄𝑄 = 𝐷𝐷0 si 𝐸𝐸 = 0, 𝑄𝑄 = 𝐷𝐷1 si 𝐸𝐸 = 1, 𝑄𝑄 = 𝐷𝐷2 si 𝐸𝐸 = 2, etc.
hasta 𝑄𝑄 = 𝐷𝐷2𝑁𝑁−1 si 𝐸𝐸 = 2𝑁𝑁 − 1.

Ejemplo 4.23
Supongamos que tenemos un multiplexor con 3 entradas de selección y por
consiguiente 23 = 8 entradas de datos.

D0
D1
D2
D3
Q
D4
D5
D6
D7
E2 E1 E0

Figura 4.40. Esquema de un multiplexor con 3 entradas de selección.

Planteemos su tabla de verdad para ver el comportamiento del dispositivo.

34
Introducción a los ordenadores

𝐷𝐷7 𝐷𝐷6 𝐷𝐷5 𝐷𝐷4 𝐷𝐷3 𝐷𝐷2 𝐷𝐷1 𝐷𝐷0 𝐸𝐸2 𝐸𝐸1 𝐸𝐸0 𝑄𝑄
X X X X X X X 0 0 0 0 0
X X X X X X X 1 0 0 0 1
X X X X X X 0 X 0 0 1 0
X X X X X X 1 X 0 0 1 1
X X X X X 0 X X 0 1 0 0
X X X X X 1 X X 0 1 0 1
X X X X 0 X X X 0 1 1 0
X X X X 1 X X X 0 1 1 1
X X X 0 X X X X 1 0 0 0
X X X 1 X X X X 1 0 0 1
X X 0 X X X X X 1 0 1 0
X X 1 X X X X X 1 0 1 1
X 0 X X X X X X 1 1 0 0
X 1 X X X X X X 1 1 0 1
0 X X X X X X X 1 1 1 0
1 X X X X X X X 1 1 1 1

Tabla 4.23. Tabla de verdad de un multiplexor con 3 entradas de selección.

Como podemos observar, la salida adopta el valor de una u otra entrada en función del
valor decimal correspondiente a las entradas de selección.

A partir de esta tabla de verdad podemos deducir la expresión de la función lógica de


salida y deducir la estructura interna del multiplexor. Si utilizamos la forma canónica de
minterms vemos que 𝑄𝑄 = 𝐷𝐷0 × ��� 𝐸𝐸2 × ���
𝐸𝐸1 × ���
𝐸𝐸0 + 𝐷𝐷1 × ���
𝐸𝐸2 × ���
𝐸𝐸1 × 𝐸𝐸0 + 𝐷𝐷2 × ���
𝐸𝐸2 × 𝐸𝐸1 × ���
𝐸𝐸0 +
⋯ + 𝐷𝐷7 × 𝐸𝐸2 × 𝐸𝐸1 × 𝐸𝐸0 .

D0

... Q
D1

...
...
...
...
...
...
...

D7

E2 E1 E0

Figura 4.41. Implementación de un multiplexor con 3 entradas de selección.

El código correspondiente a la descripción en VHDL de un multiplexor con 3 entradas


de selección podría ser el siguiente:

35
Introducción a los ordenadores

library ieee;
use ieee.std_logic_1164.all;

entity Ejemplo_4_23 is

port (
D : in std_logic_vector(7 downto 0);
E : in std_logic_vector(2 downto 0);
Q : out std_logic);

end Ejemplo_4_23;

architecture dataflow of Ejemplo_4_23 is

begin

with E select
Q <= D(0) when "000",
D(1) when "001",
D(2) when "010",
D(3) when "011",
D(4) when "100",
D(5) when "101",
D(6) when "110",
D(7) when "111",
'0' when others;

end dataflow;

A continuación podemos ver el resultado de la simulación del bloque anterior con el


Quartus Prime, donde se observa el correcto funcionamiento del multiplexor.

Figura 4.42. Simulación de la entidad Ejemplo_4_23 correspondiente a un multiplexor de 3


entradas de selección.

36
Introducción a los ordenadores

Los multiplexores se utilizan fundamentalmente cómo elemento de selección. Una


posible aplicación la encontramos en los problemas de compartición de recursos. Se
trata del caso en el que se ha de realizar el control de acceso a un único recurso, el cual
puede ser utilizado por diversos usuarios, pero en cada instante tan sólo uno de ellos
puede utilizarlo.

Imaginemos por ejemplo una línea de comunicación que es compartida por cuatro
usuarios, una posible solución al problema lo muestra la siguiente figura, donde
podemos ver que mediante las líneas de selección escogeremos qué usuario es el que
dispone en cada momento del canal de comunicación.

Usuario 0 D0
Usuario 1 D1
Línea
Usuario 2 D2
Usuario 3 D3
E1 E0

Figura 4.43. Uso de un multiplexor para seleccionar (o multiplexar) distintos usuarios que
comparten un único canal de comunicación.

En el siguiente ejemplo podemos ver cómo se gestiona la comunicación entre un


sistema lector de datos y cuatro usuarios que transmiten palabras de 2 bits, 𝑎𝑎𝑖𝑖 𝑏𝑏𝑖𝑖 , siendo
𝑖𝑖 ∈ {0,1,2,3} el indicador del usuario. El sistema lector de datos sólo puede leer una
palabra de 2 bits en cada instante de tiempo, de tal manera que mediante sus salidas
𝑆𝑆𝑆𝑆𝑆𝑆1 y 𝑆𝑆𝑆𝑆𝑆𝑆0 elige el usuario del que quiere leer las palabras.

a0 Sistema
D0
Usuario 0 b0 lector
D1
D2
a1 D3
Usuario 1 b1 E1 E0
Sel1
a2 Sel0
Usuario 2 b2
E1 E0
D0
a3 D1
Usuario 3 b3 D2
D3

Figura 4.44. Uso de multiplexores para seleccionar (o multiplexar) distintos usuarios que
transmiten palabras a un sistema lector.

4.4.1. Implementación de funciones lógicas con


multiplexores
Una aplicación específica de los multiplexores, al igual que sucede con los
decodificadores, es la posibilidad de utilizarse para implementar funciones lógicas e
intentar evitar la necesidad de utilizar puertas lógicas o, al menos un número
considerable de éstas. El planteamiento es muy simple:

• Buscamos un multiplexor con tantas entradas de selección como variables tenga


la función que queremos implementar.

37
Introducción a los ordenadores

• Ponemos a uno las entradas de datos para las que la función ha de tomar ese
valor y fijamos a cero las entradas de datos para las que la función tenga que
tomar ese valor.

Veamos un ejemplo para comprobar la sencillez del método.

Ejemplo 4.24
Supongamos que tenemos un multiplexor con 3 entradas de selección con el que
queremos implementar la función 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = ∑3(2,3,5).

Simplemente hemos de fijar un uno lógico a las entradas 2, 3 y 5; mientras que para el
resto hemos de fijar un cero lógico. El esquema resultante es el siguiente:

‘0’ D0
‘0’ D1
‘1’ D2
‘1’ D3
f
‘0’ D4
‘1’ D5
‘0’ D6
‘0’ D7
E2 E1 E0

a b c

Figura 4.45. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = ∑𝟑𝟑(𝟐𝟐, 𝟑𝟑, 𝟓𝟓) mediante un multiplexor con 3
entradas de selección.

En general veremos que los multiplexores son más óptimos que los decodificadores
para la implementación de funciones lógicas, en tanto que se evita el uso de las puertas
que se necesitaban para unir las líneas de salida de los decodificadores.

No obstante los problemas se pueden complicar si no disponemos de un multiplexor con


tantas entradas de selección como variables tenga la función a implementar. En este
caso tendremos que elegir cuáles de las variables de la función usaremos como
variables de selección del multiplexor. El resto de variables darán lugar a posibles
funciones que se aplican a las entradas de datos del multiplexor.

Veámoslo con un par de ejemplos.

Ejemplo 4.25
Supongamos que tenemos un multiplexor con 2 entradas de selección con el que
queremos implementar la función 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐) = ∏3(1,4,5,6,7).

Si dispusiéramos de un multiplexor con 3 entradas de selección, sólo tendríamos que


fijar un cero lógico a las entradas de datos 1, 4, 5, 6 y 7 del multiplexor, mientras que las
entradas 0, 2 y 3 las fijaríamos a 1. No obstante éste no es el caso pues sólo disponemos
de un multiplexor con 2 entradas de selección.

38
Introducción a los ordenadores

Para facilitar la elección de las 2 variables que usaremos en las entradas de selección
del multiplexor, así como para determinar las funciones que aplicaremos a las entradas
de datos, lo más ágil suele ser representar la función mediante un diagrama de
Karnaugh.
𝑎𝑎 𝑏𝑏
00 01 11 10
0 1 1 0 0
𝑐𝑐
1 0 1 0 0

Tabla 4.24. Representación en diagrama de Karnaugh de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = ∏𝟑𝟑(𝟏𝟏, 𝟒𝟒, 𝟓𝟓, 𝟔𝟔, 𝟕𝟕).

El proceso pasa por comprender que una vez hayamos fijado un par de las variables de
entrada entonces la función quedará dividida en cuatro grupos, cada uno de los cuales
corresponderá a una combinación de estas dos variables elegidas y por consiguiente
definirá la función que tenemos que aplicar a la correspondiente entrada del multiplexor.

Supongamos que elegimos las variables 𝑎𝑎 y 𝑐𝑐. Tal y como se muestra en el diagrama
de Karnaugh tenemos entonces cuatro grupos.

𝑎𝑎 𝑏𝑏
00 01 11 10
0 1 1 0 0
𝑐𝑐
1 0 1 0 0

Tabla 4.25. Representación en diagrama de Karnaugh de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = ∏𝟑𝟑(𝟏𝟏, 𝟒𝟒, 𝟓𝟓, 𝟔𝟔, 𝟕𝟕) en la
que hemos marcado como entradas de selección las variables 𝒂𝒂 y 𝒄𝒄.

Para el grupo correspondiente a la combinación 𝑎𝑎 = 0 y 𝑐𝑐 = 0 vemos que la función


siempre tiene que valer 1, por lo que ese será el valor que aplicaremos a la
correspondiente entrada del multiplexor. Para el grupo correspondiente a la
combinación 𝑎𝑎 = 0 y 𝑐𝑐 = 1 vemos que la función puede tomar el valor 0 o el valor 1,
siendo la variable restante que no hemos considerado 𝑏𝑏 la que determina su valor, es
decir cuando 𝑏𝑏 = 0 entonces la función vale 0 mientras que cuando 𝑏𝑏 = 1 entonces la
función vale 1, por lo que a la correspondiente entrada del multiplexor aplicaremos la
variable 𝑏𝑏. Para los restantes grupos la función siempre vale 0, por lo que ese será el
valor que aplicaremos a las correspondientes entradas del multiplexor.

‘1’ D0
b D1
f
‘0’ D2
‘0’ D3
E1 E0

a c

Figura 4.46. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = ∏𝟑𝟑(𝟏𝟏, 𝟒𝟒, 𝟓𝟓, 𝟔𝟔, 𝟕𝟕) con un multiplexor de 2
entradas de selección en las que hemos aplicado las variables 𝒂𝒂 y 𝒄𝒄.

Si en vez de usar las variables a y c, hubiésemos elegido las variables 𝑎𝑎 y 𝑏𝑏, entonces
los grupos serían los que se muestran a continuación.

𝑎𝑎 𝑏𝑏
39
Introducción a los ordenadores

00 01 11 10
0 1 1 0 0
𝑐𝑐
1 0 1 0 0

Tabla 4.26. Representación en diagrama de Karnaugh de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = ∏𝟑𝟑(𝟏𝟏, 𝟒𝟒, 𝟓𝟓, 𝟔𝟔, 𝟕𝟕) en la
que hemos marcado como entradas de selección las variables 𝒂𝒂 y 𝒃𝒃.

En este caso vemos que tendríamos tres grupos homogéneos en tanto que los valores
que contienen son idénticos, como son el grupo con 𝑎𝑎 = 0 y 𝑏𝑏 = 1 que siempre contiene
unos, el grupo con 𝑎𝑎 = 1 y 𝑏𝑏 = 1 que siempre contiene ceros y finalmente el grupo con
𝑎𝑎 = 1 y 𝑏𝑏 = 0 que siempre contiene ceros. Finalmente tenemos el grupo con 𝑎𝑎 = 0 y 𝑏𝑏 =
0 que vemos que no es homogéneo y cuyo valor dependerá de la restante variable 𝑐𝑐,
de tal manera que cuando 𝑐𝑐 = 0 entonces la función vale 1 mientras que cuando 𝑐𝑐 = 1
la función vale 0, por lo que a la correspondiente entrada del multiplexor tendremos que
aplicar 𝑐𝑐̅.

c D0
‘1’ D1
‘0’ D2
‘0’ D3
E1 E0

a b

Figura 4.47. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄) = ∏𝟑𝟑(𝟏𝟏, 𝟒𝟒, 𝟓𝟓, 𝟔𝟔, 𝟕𝟕) con un multiplexor de 2
entradas de selección en las que hemos aplicado las variables 𝒂𝒂 y 𝒃𝒃.

Os proponemos que intentéis deducir la implementación correspondiente si hubiésemos


elegido como variables de selección la 𝑏𝑏 y la 𝑐𝑐.

Ejemplo 4.26
Supongamos que queremos implementar la función 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐, 𝑑𝑑) = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 + 𝑎𝑎 × 𝑐𝑐 × 𝑑𝑑̅
mediante un multiplexor con 3 entradas de selección.

Si expandimos la función en forma canónica de minterms para identificar las


combinaciones para las que la función vale uno, nos encontramos que 𝑓𝑓(𝑎𝑎, 𝑏𝑏, 𝑐𝑐, 𝑑𝑑) =
𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × �𝑑𝑑 + 𝑑𝑑̅� + 𝑎𝑎 × �𝑏𝑏 + 𝑏𝑏�� × 𝑐𝑐 × 𝑑𝑑̅ = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑 + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑̅ + 𝑎𝑎 × 𝑏𝑏 × 𝑐𝑐 ×
𝑑𝑑̅ + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑̅ = 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑 + 𝑎𝑎 × 𝑏𝑏� × 𝑐𝑐 × 𝑑𝑑̅ + 𝑎𝑎 × 𝑏𝑏 × 𝑐𝑐 × 𝑑𝑑̅ = ∑4(11,10,14).

A continuación representaremos esta función mediante un diagrama de Karnaugh para


facilitar la identificación de las variables.

𝑎𝑎𝑎𝑎
00 01 11 10
00 0 0 0 0
01 0 0 0 0
𝑐𝑐𝑐𝑐
11 0 0 0 1
10 0 0 1 1
� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄 × 𝒅𝒅
Tabla 4.27. Representación por Karnaugh de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄, 𝒅𝒅) = 𝒂𝒂 × 𝒃𝒃 �.

40
Introducción a los ordenadores

Ahora tenemos que intentar hallar las 3 variables de entrada que aplicaremos a las 3
entradas de selección del multiplexor. En la medida de lo posible se han de buscar
variables de entrada que den lugar a grupos lo más homogéneos posibles. Si por
ejemplo elegimos las variables 𝑎𝑎, 𝑏𝑏 y 𝑑𝑑, obtenemos los siguientes grupos.

𝑎𝑎𝑎𝑎
00 01 11 10
00 0 0 0 0
01 0 0 0 0
𝑐𝑐𝑐𝑐
11 0 0 0 1
10 0 0 1 1
� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄 × 𝒅𝒅
Tabla 4.28. Representación por Karnaugh de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄, 𝒅𝒅) = 𝒂𝒂 × 𝒃𝒃 � en la que
hemos marcado como entradas de selección las variables 𝒂𝒂, 𝒃𝒃 y 𝒅𝒅.

Como podemos ver todos los grupos son homogéneos en cuanto que todos siempre
valen cero, excepto tres casos que son los grupos correspondientes a 𝑎𝑎 = 1, 𝑏𝑏 = 1 y
𝑑𝑑 = 0; 𝑎𝑎 = 1, 𝑏𝑏 = 0 y 𝑑𝑑 = 0; y 𝑎𝑎 = 1, 𝑏𝑏 = 0 y 𝑑𝑑 = 1. Para estos tres grupos podemos ver
que la salida toma distintos valores pero que estos coinciden con el mismo valor que
toma, dentro de cada grupo, la variable que no habíamos considerado 𝑐𝑐.

‘0’ D0
‘0’ D1
‘0’ D2
‘0’ D3
f
c D4
c D5
c D6
‘0’ D7
E2 E1 E0

a b d

� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄 × 𝒅𝒅
Figura 4.48. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄, 𝒅𝒅) = 𝒂𝒂 × 𝒃𝒃 � en la que hemos
marcado como entradas de selección del multiplexor las variables 𝒂𝒂, 𝒃𝒃 y 𝒅𝒅.

Si en vez de disponer de un multiplexor con 3 entradas de selección tan sólo tuviéramos


un multiplexor con 2 entradas de selección, el proceso sería el mismo, pero en vez de
tener ocho grupos en el diagrama de Karnaugh, resultantes de considerar 3 variables
de selección, ahora sólo tendremos 4 grupos. Supongamos que elegimos como
variables de selección las variables 𝑎𝑎 y 𝑐𝑐. En este caso el diagrama de Karnaugh
presentaría los siguientes grupos.

𝑎𝑎𝑎𝑎
00 01 11 10
00 0 0 0 0
01 0 0 0 0
𝑐𝑐𝑐𝑐
11 0 0 0 1
10 0 0 1 1
� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄 × 𝒅𝒅
Tabla 4.29. Representación por Karnaugh de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄, 𝒅𝒅) = 𝒂𝒂 × 𝒃𝒃 � en la que
hemos marcado como entradas de selección las variables 𝒂𝒂 y 𝒄𝒄.

Como podemos ver todos los grupos son homogéneos con valor cero, excepto el grupo
correspondiente a 𝑎𝑎 = 1 y 𝑐𝑐 = 1 en el que la salida dependerá de los valores de las otras
dos variables 𝑏𝑏 y 𝑑𝑑. Si buscamos la expresión necesaria que identifica los valores de

41
Introducción a los ordenadores

�������
este grupo veremos que es 𝑏𝑏� + 𝑑𝑑̅ = 𝑏𝑏 × 𝑑𝑑, siendo ésta la función que tendremos que
aplicar a la correspondiente entrada del multiplexor.

‘0’ D0
‘0’ D1
f
‘0’ D2
D3
E1 E0

a c
b d

� × 𝒄𝒄 + 𝒂𝒂 × 𝒄𝒄 × 𝒅𝒅
Figura 4.49. Implementación de la función 𝒇𝒇(𝒂𝒂, 𝒃𝒃, 𝒄𝒄, 𝒅𝒅) = 𝒂𝒂 × 𝒃𝒃 � en la que hemos
marcado como entradas de selección del multiplexor las variables 𝒂𝒂 y 𝒄𝒄.

Os proponemos que consideréis esta misma función y la implementéis con un


multiplexor de 2 entradas de selección, modificando las variables que son aplicadas a
las entradas de selección.

4.5. Demultiplexores

Un demultiplexor es un bloque funcional que selecciona, por medio de 𝑁𝑁 líneas de


control, a cuál de las 2𝑁𝑁 líneas de salida de datos enviamos la información que se recibe
en la única línea de entrada. Los demultiplexores presentan por consiguiente un
comportamiento dual a los multiplexores.

Q0
Q1
Q2
D
...
Q2 N-1
EN-1 ... E1 E0

Figura 4.50. Esquema de un demultiplexor genérico con N líneas de selección.

El comportamiento del dispositivo es el siguiente. Las 𝑁𝑁 líneas de selección indican


según el código binario natural, la salida donde enviar la información, es decir 𝐸𝐸 =
𝑖𝑖=𝑁𝑁−1
∑𝑖𝑖=0 𝐸𝐸𝑖𝑖 × 2𝑖𝑖 |𝐸𝐸𝑖𝑖 ∈ {0,1}, de tal manera que entonces 𝑄𝑄0 = 𝐷𝐷 si 𝐸𝐸 = 0, 𝑄𝑄1 = 𝐷𝐷 si 𝐸𝐸 = 1,
𝑄𝑄2 = 𝐷𝐷 si 𝐸𝐸 = 2, etc. hasta 𝑄𝑄2𝑁𝑁−1 = 𝐷𝐷 si 𝐸𝐸 = 2𝑁𝑁 − 1.

Ejemplo 4.27
Supongamos un demultiplexor con 2 entradas de selección.

42
Introducción a los ordenadores

Q0
Q1
D
Q2
Q3
E1 E0

Figura 4.51. Demultiplexor con 2 líneas de selección.

En este caso la tabla de verdad que muestra el comportamiento del sistema es la


siguiente:

𝐷𝐷 𝐸𝐸1 𝐸𝐸0 𝑄𝑄3 𝑄𝑄2 𝑄𝑄1 𝑄𝑄0


0 0 0 0 0 0 0
1 0 0 0 0 0 1
0 0 1 0 0 0 0
1 0 1 0 0 1 0
0 1 0 0 0 0 0
1 1 0 0 1 0 0
0 1 1 0 0 0 0
1 1 1 1 0 0 0

Tabla 4.30. Tabla de verdad de un demultiplexor con 2 entadas de selección.

Como hemos ido viendo, al tratarse al fin y al cabo de un dispositivo combinacional, a


partir de la tabla de verdad podemos deducir las expresiones necesarias para
implementar el demultiplexor, es decir 𝑄𝑄0 = 𝐷𝐷 × ���𝐸𝐸1 × ���
𝐸𝐸0 , 𝑄𝑄1 = 𝐷𝐷 × ���
𝐸𝐸1 × 𝐸𝐸0 , 𝑄𝑄2 =
𝐷𝐷 × 𝐸𝐸1 × ���
𝐸𝐸0 y 𝑄𝑄3 = 𝐷𝐷 × 𝐸𝐸1 × 𝐸𝐸0 .

D
Q0

Q1

Q2

Q3

E1 E0

Figura 4.52. Implementación de un demultiplexor con 2 líneas de selección.

El hecho es que los demultiplexores son dispositivos que pueden evitarse puesto que
su comportamiento hace que la misma función pueda implementarse mediante
decodificadores con entrada de validación o ENABLE. La idea pasa por aplicar a dicha
entrada de validación la línea de entrada de datos del demultiplexor y aplicar a las
entradas del decodificador las variables de selección del demultiplexor. Es decir el

43
Introducción a los ordenadores

demultiplexor de 2 entradas de selección se puede implementar con un decodificador 2


a 4 y entrada de validación, tal y como muestra la siguiente figura.

D0 Q0
E0 Q0 D1 Q1
E1 Q1 D2 Q2
D3 Q3
D E

Figura 4.53. Implementación de un demultiplexor con 2 líneas de selección mediante un


decodificador 2 a 4. Podemos ver que según las entradas 𝑬𝑬𝟏𝟏 y 𝑬𝑬𝟎𝟎 elegimos cuál de las salidas
activamos a uno, siempre y cuando la entrada de validación esté a uno, puesto que si la entrada de
validación vale cero entonces dicha salida (y también el resto) valen cero. Es decir, muestra el
mismo comportamiento que un demultiplexor.

4.6. Comparadores

Un comparador es un bloque funcional que realiza la comparación de dos números


codificados en binario natural.

A ALB
AEB
B AGB

Figura 4.54. Diagrama de un comparador. Presenta tres salidas que indican si A es menor que B
(ALB), si A es igual a B (AEB) o bien si A es mayor que B (AGB).

El punto de partida de éstos está en lo que sería un bloque comparador de dos números
de un bit, el cuál ha de decir cuál de los dos números es mayor o bien si son iguales,
según la siguiente tabla de verdad.

𝐴𝐴 𝐵𝐵 𝐴𝐴𝐴𝐴𝐴𝐴 𝐴𝐴𝐴𝐴𝐴𝐴 𝐴𝐴𝐴𝐴𝐴𝐴


0 0 0 1 0
0 1 1 0 0
1 0 0 0 1
1 1 0 1 0

Tabla 4.31. Tabla de verdad de un comparador de dos números de 1 bit.

De la tabla de verdad podemos deducir que 𝐴𝐴𝐴𝐴𝐴𝐴 = 𝐴𝐴̅ × 𝐵𝐵 , 𝐴𝐴𝐴𝐴𝐴𝐴 = �������


𝐴𝐴⨁𝐵𝐵 y que 𝐴𝐴𝐴𝐴𝐴𝐴 =
𝐴𝐴 × 𝐵𝐵�.

44
Introducción a los ordenadores

ALB
A

AEB

B
AGB

Figura 4.55. Implementación de un comparador de dos números de 1 bit.

En la práctica un comparador de un único bit es poco útil, de tal manera que al


comparador de un bit se le añaden unas entradas adicionales que permiten conectar en
serie diversos comparadores de un bit con la finalidad de crear un comparador de N bits.

A
B

ALBin ALBout
AEBin AEBout
AGBin AGBout

Figura 4.56. Diagrama de un comparador de 1 bit con entradas que permiten su conexión en serie
con otros comparadores de un bit. Podemos ver que las entradas adicionales son análogas a las
salidas que tiene el comparador, con la finalidad de ir interconectando en serie las salidas de un
comparador con las entradas de otro comparador.

La idea que se busca es utilizar un comparador de 1 bit para comparar los bits de mayor
peso y si éstos son distintos entonces éste decidirá el resultado, pero si son iguales
esperará que sea el comparador del siguiente bit el que facilite el resultado de la
comparación. Veamos la tabla de verdad de este comparador y un ejemplo para
entender su funcionamiento.

𝐴𝐴𝐴𝐴𝐴𝐴𝑖𝑖𝑖𝑖 𝐴𝐴𝐴𝐴𝐴𝐴𝑖𝑖𝑖𝑖 𝐴𝐴𝐴𝐴𝐴𝐴𝑖𝑖𝑖𝑖 𝐴𝐴 𝐵𝐵 𝐴𝐴𝐴𝐴𝐴𝐴𝑜𝑜𝑜𝑜𝑜𝑜 𝐴𝐴𝐴𝐴𝐴𝐴𝑜𝑜𝑜𝑜𝑜𝑜 𝐴𝐴𝐴𝐴𝐴𝐴𝑜𝑜𝑜𝑜𝑜𝑜


X X X 0 1 1 0 0
X X X 1 0 0 0 1
1 0 0 0 0 1 0 0
0 1 0 0 0 0 1 0
0 0 1 0 0 0 0 1
1 0 0 1 1 1 0 0
0 1 0 1 1 0 1 0
0 0 1 1 1 0 0 1
otras combinaciones X X X

Tabla 4.32. Tabla de verdad de un comparador de dos números de 1 bit con entradas adicionales
que permitan conectar diversos comparadores en serie.

Ejemplo 4.28
Supongamos que queremos comparar dos números de 4 bits mediante 4 comparadores
de un bit conectados en serie según la figura siguiente.

45
Introducción a los ordenadores

A[0] A A[1] A A[2] A A[3] A


B[0] B B[1] B B[2] B B[3] B

‘0’ ALBin ALBout ALBin ALBout ALBin ALBout ALBin ALBout ALB
‘1’ AEBin AEBout AEBin AEBout AEBin AEBout AEBin AEBout AEB
‘0’ AGBin AGBout AGBin AGBout AGBin AGBout AGBin AGBout AGB

Figura 4.57. Interconexión de 4 comparadores de dos números de 1 bit para crear un comparador
de dos números de 4 bits.

Supongamos como ejemplo que los números son 𝐴𝐴[3. .0] = "0110" y 𝐵𝐵[3. .0] = "0101".

Si empezamos por la derecha donde tenemos el comparador de 1 bit que termina


facilitando el resultado, vemos que a sus entradas se les aplican los bits de mayor peso.
Como que 𝐴𝐴[3] = 𝐵𝐵[3] = 0 entonces y según la tabla de verdad, este comparador se
limitará a enviar a su salida el resultado que le facilite el penúltimo comparador por medio
de las entradas de conexión en serie. En este caso el penúltimo comparador tiene que
𝐴𝐴[2] = 𝐵𝐵[2] = 1 por lo que entonces y según la tabla de verdad, este comparador
también enviará a su salida (y por consiguiente al último comparador) el resultado que
le facilite el antepenúltimo comparador. Ahora el antepenúltimo comparador tiene que
𝐴𝐴[1] = 1 y que 𝐵𝐵[1] = 0 por lo que él envía a su salida como resultado la activación a
𝐴𝐴𝐴𝐴𝐴𝐴 = 1 mientras que el resto de salidas las pone a cero. Como hemos visto este
resultado será propagado por los restantes comparadores hasta la salida (puesto que
éstos no podían determinar cuál de los dos números era mayor en tanto que sus bits
eran idénticos). Finalmente el último comparador también presenta bits de entrada 𝐴𝐴0 y
𝐵𝐵[0] distintos, pero es indiferente el resultado que propague al siguiente comparador
pues éste ya habrá determinado qué número es mayor comparando 𝐴𝐴[1] y 𝐵𝐵[1]. Es
interesante observar que el comparador con los bits de menor peso siempre tiene que
tener las entradas 𝐴𝐴𝐴𝐴𝐴𝐴 = 1, 𝐴𝐴𝐴𝐴𝐴𝐴 = 0 y 𝐴𝐴𝐴𝐴𝐴𝐴 = 0 puesto que en caso que todos los bits
sean idénticos entonces el resultado que ha de propagarse hasta el final ha de ser
precisamente éste que queda a la entrada del comparador de menor peso.

Veamos a continuación cómo describiríamos en VHDL la construcción de un


comparador de dos números de 4 bits a partir de la interconexión de 4 comparadores
de números de 1 bit.

En primer lugar, describiríamos la entidad correspondiente a un comparador de números


de 1 bit, que podría ser la siguiente:

library ieee;
use ieee.std_logic_1164.all;

entity Comp_1_bit is

port (
A, B, ALB_in, AEB_in, AGB_in : in std_logic;
ALB_out, AEB_out, AGB_out : out std_logic);

end Comp_1_bit;

architecture behavioral of Comp_1_bit is

46
Introducción a los ordenadores

begin

process (A, B, ALB_in, AEB_in, AGB_in) is


begin
if A>B then
ALB_out <= '0';
AEB_out <= '0';
AGB_out <= '1';
elsif A<B then
ALB_out <= '1';
AEB_out <= '0';
AGB_out <= '0';
else
if (ALB_in = '1' and AEB_in = '0' and AGB_in = '0') then
ALB_out <= '1';
AEB_out <= '0';
AGB_out <= '0';
elsif (ALB_in = '0' and AEB_in = '0' and AGB_in = '1') then
ALB_out <= '0';
AEB_out <= '0';
AGB_out <= '1';
elsif (ALB_in = '0' and AEB_in = '1' and AGB_in = '0') then
ALB_out <= '0';
AEB_out <= '1';
AGB_out <= '0';
else
ALB_out <= '0';
AEB_out <= '0';
AGB_out <= '0';
end if;
end if;

end process;

end behavioral;

En la figura siguiente podemos ver el resultado de la simulación de la entidad anterior


(Comp_1_bit) con el Quartus Prime, donde se observa el correcto funcionamiento del
comparador.

47
Introducción a los ordenadores

Figura 4.58. Simulación de la entidad Comp_1_bit correspondiente a un comparador de números


de 1 bit.

A continuación, declararemos una nueva entidad (Ejemplo_4_28) que será el


comparador de números de 4 bits, construido a partir de 4 instanciaciones del
comparador de números de 1 bit anterior conectadas adecuadamente.

library ieee;
use ieee.std_logic_1164.all;

entity Ejemplo_4_28 is

port (
A, B : in std_logic_vector(3 downto 0);
ALB_in, AEB_in, AGB_in : in std_logic;
ALB_out, AEB_out, AGB_out : out std_logic);

end Ejemplo_4_28;

architecture structural of Ejemplo_4_28 is

component Comp_1_bit
port (
A, B, ALB_in, AEB_in, AGB_in : in std_logic;
ALB_out, AEB_out, AGB_out : out std_logic);
end component;

signal ALB_1, ALB_2, ALB_3, AEB_1, AEB_2, AEB_3, AGB_1, AGB_2, AGB_3 : std_logic;

begin

C0: Comp_1_bit
port map (A => A(0), B => B(0), ALB_in => ALB_in, AEB_in => AEB_in, AGB_in => AGB_in,
ALB_out => ALB_1, AEB_out => AEB_1, AGB_out => AGB_1);

C1: Comp_1_bit
port map (A => A(1), B => B(1), ALB_in => ALB_1, AEB_in => AEB_1, AGB_in => AGB_1,

48
Introducción a los ordenadores

ALB_out => ALB_2, AEB_out => AEB_2, AGB_out => AGB_2);

C2: Comp_1_bit
port map (A => A(2), B => B(2), ALB_in => ALB_2, AEB_in => AEB_2, AGB_in => AGB_2,
ALB_out => ALB_3, AEB_out => AEB_3, AGB_out => AGB_3);

C3: Comp_1_bit
port map (A => A(3), B => B(3), ALB_in => ALB_3, AEB_in => AEB_3, AGB_in => AGB_3,
ALB_out => ALB_out, AEB_out => AEB_out, AGB_out => AGB_out);

end structural;

A este tipo de descripción de una entidad en base a su descomposición en entidades


de menor nivel se le denomina descripción estructural. En la figura siguiente podemos
ver el resultado de la simulación de la entidad anterior (Ejemplo_4_28) con el Quartus
Prime, donde se observa el correcto funcionamiento del comparador de números de 4
bits.

Figura 4.59. Simulación de la entidad Ejemplo_4_28 correspondiente a un comparador de números


de 4 bits.

Existen diversos comparadores comerciales que basan su funcionamiento interno en el


esquema que acabamos de ver. Así por ejemplo el circuito integrado 7485 realiza la
comparación de dos números de 4 bits, internamente mediante cuatro comparadores de
un bit. Además, presenta entradas que permiten su conexión en serie con otros
comparadores del mismo tipo para crear comparadores de mayor número de bits.

A0
B0
A1
B1
A2 7485
B2
A3
B3

ALBin ALBout
AEBin AEBout
AGBin AGBout

Figura 4.60. Comparador 7485 que permite comparar dos números de 4 bits.

49
Introducción a los ordenadores

A0 A0 A4 A0 A8 A0
B0 B0 B4 B0 B8 B0
A1 A1 A5 A1 A9 A1
B1 B1 B5 B1 B9 B1
A2 A2 7485 A6 A2 7485 A10 A2 7485
B2 B2 B6 B2 B10 B2
A3 A3 A7 A3 A11 A3
B3 B3 B7 B3 B11 B3

‘0’ ALBin ALBout ALBin ALBout ALBin ALBout ALB


‘1’ AEBin AEBout AEBin AEBout AEBin AEBout AEB
‘0’ AGBin AGBout AGBin AGBout AGBin AGBout AGB

Figura 4.61. Interconexión de tres comparadores 7485 para crear un comparador de dos números
de 12 bits 𝑨𝑨[𝟏𝟏𝟏𝟏. . 𝟎𝟎] y 𝑩𝑩[𝟏𝟏𝟏𝟏. . 𝟎𝟎]. En caso que necesitáramos un comparador de dos números con
menos bits tan sólo sería necesario poner a cero los bits de mayor peso del comparador, es decir
si por ejemplo sólo hubiéramos de comparar dos números de 10 bits entonces las entradas de
mayor peso las dejaríamos a cero (o bien todas a uno): 𝑨𝑨[𝟏𝟏𝟏𝟏] = 𝑩𝑩[𝟏𝟏𝟏𝟏] = 𝑨𝑨[𝟏𝟏𝟏𝟏] = 𝑩𝑩[𝟏𝟏𝟏𝟏] = 𝟎𝟎.

Finalmente es importante remarcar que los comparadores vistos sólo comparan


números codificados en binario natural, es decir, si tenemos números codificados en
otro sistema, por ejemplo, código Gray, o bien sistemas que aún no hemos visto y que
conoceremos más adelante, como son los sistemas de representación de números con
signo, no podemos utilizar directamente estos comparadores y en caso de tenerlos que
utilizar primero tendremos que convertir los números a binario natural.

4.7. Aplicaciones con bloques funcionales

Con los comparadores hemos visto un abanico suficiente de bloques funcionales con
los que ya tenemos que ser capaces de ver problemas en los que se diseñen
aplicaciones simples. De hecho, todos los distintos bloques funcionales que hemos visto
hasta el momento se pueden adquirir con facilidad y en la siguiente tabla podemos ver
algunos de los más habituales.

Dispositivo Descripción
7442 Decodificador 4 a 10
7447 Decodificador de BCD a 7 segmentos
7485 Comparador de 4 bits
74147 Codificador 10 a 4 con prioridad
74148 Codificador 8 a 3 con prioridad
74150 Multiplexor 16 a 1
74151 Multiplexor 8 a 1
74153 2 Multiplexores 4 a 1
74157 4 Multiplexores 2 a 1

Tabla 4.33. Circuitos integrados correspondientes de la serie 74 más habituales dentro de los que
implementan bloques funcionales combinacionales.

Los únicos bloques funcionales combinacionales que prácticamente nos quedan por ver
son los que realizan operaciones aritméticas. Pero éstos los dejamos para un próximo
tema. Pasemos pues a ver algunos ejemplos de aplicaciones.

50
Introducción a los ordenadores

Ejemplo 4.29
Procederemos a diseñar un sistema que mueva un ascensor en un edificio de seis pisos,
el cual sólo puede activarse cuando un usuario ha introducido un código concreto. El
esquema es el siguiente:

1
P1
1
P2
1
P3
1
P4 1
Up
1
P5
1 1
P6 Down
4
Piso actual
4
Clave usuario
4
Clave registrada

Figura 4.62. Sistema de control de un ascensor.

Las entradas y salidas son las siguientes:


• 𝑃𝑃1, 𝑃𝑃2, 𝑃𝑃3, 𝑃𝑃4, 𝑃𝑃5 y 𝑃𝑃6 son entradas de un bit que por lógica positiva indican el
piso deseado al que quiere desplazarse el usuario.
• 𝑃𝑃𝑃𝑃𝑃𝑃𝑃𝑃 𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎 es un bus de 4 bits que indica el piso actual en el que se halla el
ascensor.
• 𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢 es un bus de 4 bits que indica la clave introducida por el usuario.
• 𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟 es un bus de 4 bits que indica la clave registrada en el sistema.
• 𝑈𝑈𝑈𝑈 es una salida por lógica positiva que mueve el ascensor hacia arriba.
• 𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷 es una salida por lógica positiva que mueve el ascensor hacia abajo.

Si la 𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢 coincide con la 𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟 entonces el sistema ha de activar


𝑈𝑈𝑈𝑈 o 𝐷𝐷𝐷𝐷𝐷𝐷𝐷𝐷 según si el 𝑃𝑃𝑃𝑃𝑃𝑃𝑃𝑃 𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎 es menor o mayor que el piso solicitado por el
usuario. Para diseñar el sistema se puede hacer uso de bloques funcionales y puertas
lógicas. En cualquier caso, no puede utilizarse más de un bloque comparador que tenga
como entradas buses de 4 bits.

A partir del enunciado parece lógico usar un bloque que compare el 𝑃𝑃𝑃𝑃𝑃𝑃𝑃𝑃 𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎 con el
piso deseado por el usuario. En cualquier caso, el bloque comparador tendrá que
comparar dos buses de la misma longitud, motivo por el cual primero codificaremos la
solicitud de piso en un bus. A partir de aquí las salidas del comparador que directamente
nos indicarán si el ascensor ha de desplazarse hacia arriba o hacia abajo tendrán que
validarse según si la 𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢𝑢 coincide con la 𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟. No obstante, y
como no podemos usar más comparadores, esta última comparación la
implementaremos mediante puertas NXOR y AND. El esquema propuesto es pues el
siguiente.

51
Introducción a los ordenadores

Clave usuario[3]
Clave registrada[3]
Clave usuario[2]
Clave registrada[2]
Clave usuario[1]
Clave registrada[1]
Clave usuario[0]
Clave registrada[0]

0 D0 0
P1 D1
1 (MSB)
P2 D2
P3 D3 3 4
Q A
P4 D4 4
B
P5 D5
ALBin ALBout Down
P6 D6 0
Piso actual
0 D7 1 AEBin AEBout
AGBin AGBout Up
0

Figura 4.63. Propuesta de solución al control de un ascensor.

Ejemplo 4.30
Tenemos un sistema de dos teclados de 16 teclas cada uno (hexadecimales), los cuales
facilitan en binario natural la tecla que en cada momento está pulsada. Aparte tenemos
un bus de entrada de 2 bits 𝑆𝑆[1. .0] que, en función de su valor, se determina la operación
a realizar a partir de la información de los teclados. Más concretamente:

• Si 𝑆𝑆 = 00 entonces el sistema ha de indicar si el primer teclado presenta pulsado


un número que tenga 2 o más divisores (sin contar ni el mismo número ni el
número 1). Es decir, el 4 sólo presenta como divisor el número 2 mientras que el
10 tiene dos divisores, el 2 y el 5.
• Si 𝑆𝑆 = 01 entonces el sistema ha de indicar si el segundo teclado presenta
pulsado un número que tenga 2 o más divisores (sin contar ni el mismo número
ni el número 1).
• Si 𝑆𝑆 = 10 entonces el sistema ha de indicar si los dos teclados tienen pulsados
un número par (incluido el cero).
• Si 𝑆𝑆 = 11 entonces el sistema ha de indicar si los dos teclados tienen pulsados
un número impar.

0 1 2 3
4 5 6 7 T1 4
8 9 A B
C D E F 1
R
0 1 2 3
4 5 6 7 T2 4
8 9 A B
C D E F

Figura 4.64. Sistema de decisión a partir de la información de dos teclados hexadecimales.

52
Introducción a los ordenadores

Primero diseñaremos un bloque que determine si un número de 4 bits tiene 2 o más


divisores. Por consiguiente se trata de implementar el sistema 𝑧𝑧(𝑎𝑎, 𝑏𝑏, 𝑐𝑐, 𝑑𝑑) =
∑4(8,10,12,14,15).

𝑎𝑎 𝑏𝑏 𝑐𝑐 𝑑𝑑 𝑧𝑧
0 0 0 0 0
0 0 0 1 0
0 0 1 0 0
0 0 1 1 0
0 1 0 0 0
0 1 0 1 0
0 1 1 0 1
0 1 1 1 0
1 0 0 0 1
1 0 0 1 0
1 0 1 0 1
1 0 1 1 0
1 1 0 0 1
1 1 0 1 0
1 1 1 0 1
1 1 1 1 1

Tabla 4.34. Tabla de verdad de un sistema que calcula si un número de 4 bits presenta 2 o más
divisores, sin contar para ello ni con el mismo número ni con el número 1.

Esta función aparentemente la podemos implementar como consideremos más


adecuado. No obstante, supongamos que para ello nos pidan usar un decodificador 3 a
8 (para poder repasar temas anteriores). Recordemos que, en este caso, al disponer de
un decodificador con un número menor de entradas (3) que las entradas del sistema (4),
hemos de seleccionar una de estas entradas para que sea aplicada a las salidas del
decodificador. Lo veremos mejor si representamos la función en forma de diagrama de
Karnaugh y agrupamos los valores de salida en 8 grupos de 2 elementos (equivalente
a usar 3 entradas de selección).
𝑎𝑎𝑎𝑎
00 01 11 10
00 0 0 1 1
01 0 0 0 0
𝑐𝑐𝑐𝑐
11 0 0 1 0
10 0 1 1 1

Tabla 4.35. Diagrama de Karnaugh de la función 𝒛𝒛(𝒂𝒂, 𝒃𝒃, 𝒄𝒄, 𝒅𝒅) = ∑𝟒𝟒(𝟔𝟔, 𝟖𝟖, 𝟏𝟏𝟏𝟏, 𝟏𝟏𝟏𝟏, 𝟏𝟏𝟏𝟏, 𝟏𝟏𝟏𝟏). Vemos
que si usamos un decodificador 3 a 8 en el que aplicamos a las entradas del mismo las
variables 𝒂𝒂,𝒄𝒄 y 𝒅𝒅 entonces la variable 𝒃𝒃 afecta a la salida del decodificador de la siguiente
manera. Cuando 𝒂𝒂 = 𝟏𝟏, 𝒄𝒄 = 𝟎𝟎 y 𝒅𝒅 = 𝟎𝟎 o bien cuando 𝒂𝒂 = 𝟏𝟏, 𝒄𝒄 = 𝟏𝟏 y 𝒅𝒅 = 𝟎𝟎 entonces la salida
siempre ha de valer 1; cuando 𝒂𝒂 = 𝟏𝟏, 𝒄𝒄 = 𝟏𝟏 y 𝒅𝒅 = 𝟏𝟏 o bien cuando 𝒂𝒂 = 𝟎𝟎, 𝒄𝒄 = 𝟏𝟏 y 𝒅𝒅 = 𝟎𝟎
entonces la salida siempre ha de valer lo mismo que 𝒃𝒃; para el resto de combinaciones la
salida siempre vale 0.

53
Introducción a los ordenadores

Q0
Q1
d D0
Q2
Q3
c D1
Q4 z
Q5
a D2
Q6
Q7

Figura 4.65. Implementación de la función 𝒛𝒛(𝒂𝒂, 𝒃𝒃, 𝒄𝒄, 𝒅𝒅) = ∑𝟒𝟒(𝟔𝟔, 𝟖𝟖, 𝟏𝟏𝟏𝟏, 𝟏𝟏𝟏𝟏, 𝟏𝟏𝟏𝟏, 𝟏𝟏𝟏𝟏) mediante un
decodificador 3 a 8.

Si en vez de pedirnos implementar esta parte mediante un descodificador nos hubiesen


dado a elegir entre un descodificador 3 a 8 o bien un multiplexor con 3 entradas de
selección, tendríamos que haber visto que esta última opción era más óptima en tanto
que no requeriríamos de puertas lógicas adicionales. Dejamos para vosotros que miréis
de implementar la función con un multiplexor y comparéis las dos opciones.

Recuperando el enunciado del ejercicio lo que proponemos es multiplexar los dos


teclados para aplicar sus valores al sistema decisor anterior para determinar si la tecla
pulsada del teclado seleccionado presenta 2 o más divisores. De esta manera nos
ahorraremos tener que doblar el sistema decisor anterior. Como que si 𝑆𝑆 = 00 hemos
de analizar el primer teclado y si 𝑆𝑆 = 01 hemos de analizar el segundo teclado entonces
haremos la selección mediante 𝑆𝑆[0]. Posteriormente vemos que si 𝑆𝑆[1] = 0 entonces el
valor de salida es el que determine el sistema anterior mientras que si 𝑆𝑆[1] = 1 entonces
la salida viene determinada en función de si los dos teclados muestran un número par
o impar, lo cual puede determinarse directamente mirando los bits de menor peso de 𝑇𝑇1
y de 𝑇𝑇2 pues si el bit de menor peso es un cero entonces el número es par mientras que
si el bit de menor peso es un uno entonces el número es impar.
El sistema final sería el siguiente.

4
T1 D0 4
4
z(a,b,c,d)
T2 D1
E0
D0
S[0]
R
D1
T1[0]
T2[0] D0 E0

T1[0] D1 S[1]
T2[0]
E0

S[0]

Figura 4.66. Implementación de un sistema de decisión a partir de la información de dos teclados


hexadecimales.

54
Introducción a los ordenadores

Ejemplo 4.31
Para practicar os proponemos que diseñéis un sistema de control sobre un conjunto de
sensores que muestrean la temperatura de cuatro salas. En caso que alguna de las
salas sobrepase una cierta temperatura entonces se tendrá que activar una alarma.

1
ST1
1
ST2 1
Alarma
1
ST3 1
ST4 1 Actividad
6
Valor

6 6 6 6

LST1 LST2 LST3 LST4

Figura 4.67. Sistema de control de una alarma a partir de la medición de la temperatura de cuatro
salas y los límites correspondientes.

Las entradas son las siguientes:

• 𝑆𝑆𝑆𝑆1 es el sensor de temperatura de la primera sala, 𝑆𝑆𝑆𝑆2 es el de la segunda sala,


𝑆𝑆𝑆𝑆3 es el de la tercera y 𝑆𝑆𝑆𝑆4 es el de la cuarta. Todos ellos son señales de un
bit que informan por lógica positiva cuál de los cuatro sensores disponibles
envían información por el bus de datos denominado 𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉.
• 𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉 es un bus de datos de 6 bits que indica el valor que envía uno de los cuatro
sensores.
• 𝐿𝐿𝐿𝐿𝐿𝐿1 es un valor de 6 bits que indica el límite de temperatura de la primera sala
a partir de la que se produce una anomalía. Lo mismo ocurre con 𝐿𝐿𝐿𝐿𝐿𝐿2, 𝐿𝐿𝐿𝐿𝐿𝐿3 y
𝐿𝐿𝐿𝐿𝐿𝐿4 para las restantes salas.

Las salidas son las siguientes:


• 𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴 es una salida de un bit que por lógica positiva indica si el sensor del cual
leemos el valor sobrepasa el límite correspondiente.
• 𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴 es una salida de un bit que indica cuándo un sensor envía un valor
por el bus denominado 𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉.
Así, por ejemplo, imaginemos que el sensor de temperatura de la segunda sala envía
un valor. En este caso las entradas 𝑆𝑆𝑆𝑆2 = 1 y 𝑆𝑆𝑆𝑆1 = 𝑆𝑆𝑆𝑆3 = 𝑆𝑆𝑆𝑆4 = 0. Supongamos que
el valor de la temperatura de la segunda sala es de 29 grados y por consiguiente 𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉𝑉 =
011101. Si el límite de la temperatura 𝐿𝐿𝐿𝐿𝐿𝐿2 fuera igual o superior a 29 entonces
𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴 = 0 mientras que en caso contrario 𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴 = 1. Además y por el hecho que se
está enviando un valor de temperatura entonces 𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝑎𝑎𝑑𝑑 = 1.

Se trata de diseñar el sistema anterior para que funcione según los requisitos
planteados, usando en la medida de lo posible bloques funcionales. En el caso de usar
comparadores éstos tendrán entradas de 4 bits.

Opcional: Escribe el código VHDL correspondiente al sistema de control anterior. Prueba


a sintetizar el sistema con el software Quartus Prime y simularlo para comprobar el
correcto funcionamiento de tu diseño.

55

También podría gustarte