Bienvenidos a este primer tema de la tercera semana del curso. Esta lección la vamos a dedicar a estudiar las herramientas automáticas para la síntesis de circuitos combinacionales. Veremos en primer lugar un tema que no habíamos introducido hasta ahora, que son los términos redundantes de una función, y luego estudiaremos algunas herramientas, a nivel educacional, que nos permitirán simplificar funciones booleanas de una manera automática y construir, también de una forma automática, el circuito combinacional que las implementa. Los términos redundantes, o terminos "don't care" en inglés, son combinaciones de los valores de las entradas que nunca van a llegar a un circuito y que por lo tanto, a las salidas asociadas a estas combinaciones de entrada les podemos asignar cualquier valor 0 o 1, el que queramos, porque estas salidas nunca se van a generar en la práctica. Bien, si podemos asignar cualquier combinación de ceros y unos a las salidas, podríamos optar por una solución simple que sería pues,... a todas las combinaciones de entradas que nunca van a suceder les asignamos siempre ceros o siempre unos. Lo que ocurre es que veremos que dependiendo de los ceros y unos que asignemos a estas salidas, vamos a conseguir funciones booleanas más sencillas y, por lo tanto, circuitos más simples. Vamos a verlo en un ejemplo. Queremos construir un circuito capaz de visualizar una cifra decimal. La entrada será una cifra de 0 a 9. Para codificar las cifras de 0 a 9 necesitamos cuatro bits que serán estas cuatro entradas x3, x2, x1 y x0. un 7-segmentos es un dispositivo que tiene ocho leds, ocho diodos emisores de luz. Siete de ellos en forma de pequeñas barras, como muestra esta figura, y un octavo, redondo, que sirve para marcar el punto decimal. Este led no lo vamos a utilizar. El 7-segmentos tiene todas estas entradas y cada entrada va directamente asociada a un led de una manera que si activamos la entrada A, se va a iluminar el led A. Si activamos la entrada G, se va a iluminar el led G. Por ejemplo, si quisiésemos visualizar un 3, visualizar un 3 querría decir activar este led, este led, éste, éste, y éste. Deberíamos generar un 1 por la entrada A, por la entrada B, por la entrada G, por la entrada C, y por la entrada D, y el resto estarían a 0s. La tabla de verdad es tan sencilla que vamos a obviar el paso de la descripción funcional. Vemos aquí en esta tabla que, cuando le entra el 3 en decimal, cuando entra 0, 0, 1, 1 por las entradas x3, x2, x1, x0, las salidas toman estos valores, que al llegar al 7- segmentos, activan todos los leds, salvo los correspondientes a los segmentos E y F, es decir, nos daría la configuración que hemos visto antes del 3. Si por ejemplo llega un 0 en decimal, que serían todos 0s en binario, se me activan todos los leds salvo el G, que es este segmento central, dándome una configuración como ésta. O, por ejemplo, si me llega el 8 en decimal, se me activan todos los leds, dándome una configuración como ésta, que se corresponde con, digamos, la sensación visual de un 8. En esta tabla, aquí hemos dejado una porción, toda esta caja blanca donde no sabemos que hay aquí, qué 0s y 1s hay aquí. Esta caja blanca corresponde a las entradas en decimal 10, 11, 12, ... hasta el 15. Estas entradas ocurre que no son códigos BCD, es decir, para representar cualquiera de estos números en un 7-segmentos, necesitaríamos, de hecho, dos 7-segmentos: uno para representar las decenas y otro para representar las unidades. Quiere decir, que si el circuito que nosotros estamos construyendo forma parte de un circuito mayor que funciona correctamente, estas combinaciones de entrada nunca nos van a aparecer por x3, x2, x1 y x0, y por lo tanto, los valores 0 y 1 que les asignemos como salidas son irrelevantes porque nunca los vamos a ver por la salida de un circuito. Si las combinaciones de 0s y 1s que pongamos aquí son irrelevantes, podríamos optar por una solución sencilla, de decir: vamos a rellenar toda esta porción de la tabla con 0s o tal vez con 1s. Lo que ocurre es que dependiendo de la combinación precisa de 0s y 1s que asignemos a la salida, vamos a obtener circuitos más sencillos o más complejos, con más o menos puertas lógicas. Aquí en un primer ejemplo, lo que hemos hecho es asignar 0 a todas estas combinaciones de salida. Hemos hallado los minterms, hemos minimizado las funciones y nos han salido estas funciones de aquí. Esto parece muy complejo, pero lo hemos hecho con un programa de minimización automática de funciones que veremos más adelante. Vamos a analizar, por ejemplo, la función b. Es decir, vamos a analizar esta columna, y vamos a suponer que como términos redundantes escogemos los minterms 10, 11, 12 y 15; 10, 11, 12 y 15. Quiere decir que añadimos a esta función estos términos, y, a la función resultante pues, apliquemos todo el conjunto de propiedades de álgebra de Boole que nos sirve para minimizar la función, y con un poco de paciencia obtendríamos esta nueva ecuación equivalente a la primera. Analicemos un poco lo que hemos hecho: Para implementar la función b original, esta parte, ¿qué necesitamos? Necesitamos dos puertas AND de tres entradas. Necesitamos eh, con esto implementaríamos estos dos términos productos. Dos puertas AND más de dos entradas. Necesitamos, para hacer la suma, una puerta OR de cuatro entradas, y necesitamos cuatro inversores para implementar, x0 barra, x1 barra, x2 barra x3 barra. Por otro lado, para implementar esta función necesitamos dos puertas AND de dos entradas para implementar estos dos productos. Una puerta OR de tres entradas y tres inversores para implementar x0 barra, x1 barra, y x2 barra. Sin necesidad de dibujar el circuito, fijaros el ahorro que supone el trabajar con esta función en vez de con esta función original. Y esto lo hemos conseguido asignando estos valores precisos y concretos de salidas a las entradas redundantes. Un segundo ejemplo: vamos a trabajar ahora con la función c, y en este caso, vamos a escoger todos los minterms salvo el 10. Es decir, vamos a escoger el 11, el 12, el 13, el 14 y el 15. Haríamos exactamente lo mismo; añadir aquí los términos redundantes y aplicar las propiedades del álgebra de Boole, y con esto llegaríamos a una función como ésta que tenemos aquí, que es equivalente a la primera. ¿Cuántas puertas necesitamos para implementar la primera puerta? Pues, tres puertas AND de dos entradas para implementar los tres productos, una puerta OR de tres entradas, y x1 barra, x2 barra, x3 barra, tres inversores. Por otro lado, para implentar esta función de aquí, necesitamos una puerta OR, simplemente de tres entradas y un inversor para implementar x1 barra. Otra vez fijaros el ahorro de puertas que significa trabajar con la función original, o con la función cuando hemos entrado estos términos redundantes. Evidentemente queda por ver la cuestión de cómo escogemos, cómo sabemos que estas combinaciones de salidas son las correctas. Esto veremos que también nos lo hace este programa automático de minimización de funciones. Bueno, pues aquí tenéis las funciones que nos habían salido asignando 0s a los términos redundantes. Y aquí tenéis las funciones que podemos obtener si escogemos convenientemente los términos redundantes. Y aquí simplemente me he dedicado a hacer una suma y decir: bueno pues en este caso, términos redundantes igual a 0, en total necesito 25 puertas AND, no he escrito de cuantas entradas son cada una de ellas, 7 ORs y 4 inversores En cambio, con la versión optimizada necesito solo 16 puertas AND. Queda un tema que es ... bueno y ¿cómo escoges qué términos redundantes escoges y cuáles no? ¿Cómo sabes cuál es la mejor combinación de 0s y 1s a la salida que te va a minimizar más la función? Y la verdad es que en principio no lo sabes, pero para eso tenemos unas herramientas automáticas de minimización de funciones que veremos a continuación