Esta lección trata de un tipo particular de circuitos. Los circuitos dedicados a realizar cálculos aritméticos y sus componentes. Los bloques aritméticos constituyen una parte muy importante de prácticamente todos los circuitos digitales y merecen por ello un tratamiento diferenciado. A lo largo de este tema veremos simplemente acciones de las cuatro operaciones básicas de suma, resta, multiplicación y división. La suma binaria ya la hemos estudiado en las lecciones L2.2 y L2.3 de la segunda semana. Vimos cómo se podía construir un sumador de números de n bits concatenando n componentes capaces de sumar 2 números de 1 bit más el posible acarreo, y generando la suma de ambos más el acarreo que va a parar a la etapa siguiente. Estos bloques reciben el nombre de "sumadores completos" o "Full Adders". La segunda operación aritmética que nos interesa es la resta. Dados los números X e Y de n bits, calcularemos la diferencia como X menos Y, menos un posible acarreo de entrada. En este caso, el resultado nunca puede ser mayor que X, es decir, la D siempre es menor o igual que 2 elevando a n-1. Pero a cambio, a diferencia de lo que sucedía en la suma, el resultado puede ser un número negativo que tendremos que ver cómo representar. Vamos a colocar aquí la X, la Y y el acarreo, y el resultado de la resta, acarreo0. El valor máximo que puede tomar D corresponde al caso en que X toma su valor máximo, que en el caso de ser un número de n bits, será éste, y tanto la Y como el acarreo es 0. El valor mínimo que puede tomar D será menos 2 elevado a n, que se corresponde con el caso en que la X es 0, la Y toma su valor máximo, y además el acarreo es 1. Bien, ¿cómo representamos un número negativo? Hay varias maneras de representarlo, pero nosotros vamos a explicar simplemente la más utilizada, la más frecuente. Si D es un número no negativo, es decir, si D es 0 o un número positivo, lo representamos en base-2 de la manera habitual, como íbamos haciendo hasta ahora. Si D es negativo, a este valor le añadiremos un bit adicional que tendrá un peso 2 elevado a n, y que se restará del resultado del cálculo que hemos realizado en esta parte. Esta forma de representar los número negativos, recibe el nombre de "complemento a 2" del número, en este caso, D. Bien, ¿cómo realizamos la resta manualmente? Vamos a poner aquí el número X es 12, el número Y es 9, y aquí tenemos los mismos números pero cambiados, de manera que aquí vamos a hacer la resta de 12 menos 9 y aquí vamos a hacer la resta de 9 menos 12. Al igual que en la suma, lo que hacemos manualmente es ir trabajando columna a columna y movernos desde el bit menos significativo hacia el bit más significativo. En la primera etapa, ¿qué haríamos? Miraríamos si el número X es mayor que el número Y Vamos a empezar por este caso que es más sencillo. En este caso la X es 1, la Y es 0, 1 menos 0 es 1 y continuaríamos moviéndonos hacia la izquierda. Este caso es distinto, porque si intentamos hacer la resta de 0 menos 1, en principio no podemos hacerla, asi que lo que hacemos, es quitar un bit a la etapa siguiente, este bit ponerlo aquí y, en vez de hacer la resta de 0 menos 1, vamos a hacer la resta de 10 (que es n 2), menos 1. 2 menos 1 es 1. y seguimos moviéndonos hacia la izquierda. Aquí tendríamos que hacer la resta de 0, menos 0, menos 1, como no sabemos representar el número menos 1, el bit menos 1, lo que hacemos de nuevo es quitar un dígito a la etapa siguiente, colocarlo aquí, y vamos a hacer la resta de 10 cero (que es 2) menos 0 menos 1, que es 1. Aquí estaríamos haciendo la resta de 1 menos 0, menos 1, que es 0, y aquí la resta de 1 menos 1, que es 0. En total el resultado nos daría 3, un número positivo. En cambio, si hacemos la resta en este otro caso, en la primera etapa no hay problema, la segunda 0 menos 0 es 0, la tercera, 0 menos 1 lo que vamos a hacer es quitar un dígito a la etapa siguiente, colocarlo aquí, y hacer la resta de 10 (2) menos 1, que es 1. Aquí hemos de hacer la resta de 1 menos 1, menos 1, otra vez deberíamos quitar un dígito a la etapa siguiente, colocar este dígito aquí, y entonces haríamos la resta de 11, menos 1 que es 10; 10 menos 1, 1. Y aquí nos queda este menos 1. Este número es 2 elevado a 3 más 2 elevado a 2, más 2 elevado a 0, y este menos 1 lo vamos a representar como 2 elevado a 4, pero negativo. Es decir, que el resultado va a ser menos 16 más 8 más 4 = 12, más 1 = 13, es decir, menos 3. Sale el número correcto de una manera natural y fijaros que la manera de calcular el número coincide exactamente con la representación de complemento a 2, que hemos definido anteriormente. Bueno, más formalmente lo que hacemos es repetir n veces, siendo n el número de bits de los números a restar, un proceso en el cual vamos calculando para cada etapa el bit de resta y el bit de acarreo. El bit de resta, si la X es mayor que Y más el acarreo, el resultado de la resta es X menos Y, menos el acarreo. Por el contrario, si X es menor que Y más el acarreo, lo que hemos hecho es quitar un bit a la etapa siguiente y sumárselo a la X, es decir, lo que hemos hecho es la resta de 2.X menos Y menos el acarreo. Y además hemos generado un acarreo igual a 1 para la etapa siguiente. Bien. Estas dos cálculos, si trabajamos módulo-2, estos dos cálculos son exactamente iguales a hacer X menos Y, menos el acarreo módulo-2, que es la expresión que tenemos aquí. ¿De acuerdo?. En cada paso lo que hacemos es calcular el bit de diferencia o de resta de esta manera, y calcular el acarreo igual a 1 en caso de que este cálculo sea menor que 1. Aquí tenemos un primer algoritmo para la operación resta. Como vemos, aquí hay un loop que se repite n veces, en el cual se calcula la diferencia d, y el acarreo de la etapa siguiente. La diferencia d la hemos puesto como la suma de xi más yi, más el acarreo módulo-2, porque si se trabaja en módulo-2 esta expresión se cumple. Es decir, la resta de "a" menos "b", en general, menos "c" módulo-2, coincide con la suma de los 3 valores. Aquí se supone que previamente hemos definido un módulo, un procedimiento que calcula el signo de x menos y, menos el acarreo. En este segundo algoritmo lo hemos modificado para que se adecúe más a la implementación con puertas lógicas. Lo primero que hemos hecho es sustituir xi más yi más el acarreo por la xor de los tres valores. Se puede ver fácilmente haciendo la tabla de verdad de la operación xi menos yi menos el acarreo módulo-2, o bien, si queremos, la suma porque sabemos que es lo mismo, y haciendo la tabla de verdad de xi O-exclusiva yi, O-exclusiva el acarreo, que estos valores siempre coinciden. Por otro lado, en el cálculo del acarreo lo hemos sustituido por la expresión booleana xi-negado por yi, más xi-negado por el acarreo de la etapa i más yi por el acarreo, que se corresponde ¿con qué situaciones?: Si nos estamos imaginando cada una de las columnas de la resta, este primer producto corresponde a la situación en la cual la xi es 0 y la yi es 1. Cuando hacemos la resta de 0 menos 1, por supuesto generamos un carry para la etapa siguiente. Esta situación corresponde al caso en que la x es 0, la y toma cualquier valor, pero hay un acarreo que nos viene de la etapa anterior. En este caso tendríamos que hacer siempre la resta de 0, menos 0 menos 1, pero en todo caso menos 1 más, es decir, o 0 menos 0, menos 1, que daría negativo, o 0 menos 1, menos 1, que también daría negativo y por lo tanto también generaría un acarreo, o este caso que corresponde a aquella situación en la cual x toma cualquier valor, la y toma el valor 1, y nos llevamos un acarreo de la etapa anterior. Esto, si la x fuese 0, tendríamos que hacer 0 menos 1, menos 1. Si la x fuese 1, tendríamos que hacer 1 menos 1 menos 1, que en ambos casos da un resultado negativo. Bien, pues este es el algoritmo adecuado para la implementación directa con puertas lógicas con circuitos digitales. Ahora ya estamos en condiciones de construir el restador para números de n bits. Lo primero que hacemos es construir, como siempre, un módulo básico al que llamamos Full Substractor o FS, capaz de restar dos números de un bit, x1 menos yi, menos el acarreo de entrada. Este módulo básico realiza las operaciones internas al loop que tenemos ya en forma de ecuaciones booleanas, o sea, que su traducción a puertas lógicas es inmediata. Y finalmente lo que hacemos es concatenar, puesto que se trata de un loop de n etapas, concatenar n módulos idénticos, para construir el restador de números de n bits. Os dejo ahora un pequeño ejercicio a realizar. Bueno, la solución es sencilla. Vamos a seguir la sugerencia y vamos a calcular x-y y y-x, utilizando dos restadores como los que hemos diseñado anteriormente. Éste hace la resta x-y, éste hace la resta y-x. El bit más significativo del restador se corresponde con el acarreo de la última etapa. Se corresponde en el fondo con lo que nosotros habíamos llamado el dn, que está dando el signo del resultado. En este caso si dn es igual a 0 la resta de x-y es un número positivo. Si dn es 1 nos está indicando que la resta de x-Y es un número negativo. Es decir, directamente, esta salida ya es el bit de signo que buscamos. Por lo que respecta al valor absoluto de d, si el resultado ha sido positivo, aquí tendremos un 0, y, por lo tanto, en dn tendremos la resta de x-y como corresponde. Por el contrario, si el resultado era negativo, lo que tendremos en d no es x-y sino y-x, que sí será un número positivo. Lo que sí debemos tener en cuenta, aunque no lo hayamos puesto, es que todas estas líneas estamos hablando de buses de, en general, n bits.