Sumador de 8 Bits

Última modificación: 22 de febrero del 2023

Problema

Una de las primeras ideas al trabajar con circuitos lógicos es fabricar nuestro propio sumador. En teoría es una tarea muy sencilla, simplemente escribimos nuestras entradas y salidas en una tabla de verdad y buscamos una expresión lógica que haga que se cumplan todas las condiciones. Con este enfoque se podrían crear sumadores de N bits pero implicaría tener que hacer la sintetización de una nueva tabla de verdad por cada bit que añadamos, por ello podemos intentar hacer un sumador de un solo bit y buscar la forma de reutilizarlo para sumar N bits.

En la siguiente imagen se puede apreciar la tabla de verdad de un sumador de 1 bit cuyas entradas son X e Y y tiene como salidas el resultado de la suma y el bit de acarreo de salida.

Podríamos usar álgebra booleana o mapas de Karnaugh para encontrar un circuito que satisfaga esta tabla, pero de manera intuitiva podemos ver que el resultado de 'S' es el XOR de X e Y y el resultado de acarreo es el AND de X e Y, por lo tanto podemos implementar este circuito usando solo esas dos compuertas, a este sumador de dos cantidades de 1 bit se le conoce como "Half Adder".

Si queremos reutilizar este circuito para hacer una suma de más bits no sería posible porque no tendríamos forma de conocer el acarreo producido por el módulo anterior, para lograr este cometido tendríamos que agregar un bit más que tenga un acarreo de entrada y de esta forma podríamos conectar el acarreo de salida de un sumador al acarreo de entrada del siguiente, a este sumador de tres cantidades de 1 bit se le conoce como "Full Adder".

Podemos comenzar analizando la tabla de verdad de este nuevo circuito.

De manera intuitiva podemos notar que 'S' tiene la misma tabla de verdad que un XOR de 3 entradas por lo que podemos obtener su valor de esa forma, pero para el acarreo de salida tendremos que encontrar la expresión usando álgebra booleana. Si obetenemos una SOP (Suma de Productos) en base a esta tabla llegamos a la siguiente expresión:

Podemos minimizar la expresión hasta llegar a:

La implementación de este circuito es la siguiente:

Con el Full Adder construido podemos hacer un sumador de 8 bits conectando cada uno de los bits de entrada de los buses X e Y a un Full Adder independiente y concatenar los acarreos de salida del Full Adder previo al Full Adder actual. A este método se le conoce como "Ripple Carry Adder".

Si bien ya podríamos intentar describir este circuito con un HDL no sería lo más eficiente ya que el Ripple Carry Adder tiene un gran inconveniente, mientras más Full Adders se agregan más tiempo tarda en dar una respuesta, ya que el segundo Full Adder debe esperar a que se genere el acarreo de salida del primer Full Adder para poder calcular su respuesta, a su vez el tercer Full Adder debe esperar a que el segundo Full Adder calcule el acarreo de salida para entonces dar su respuesta final y como pudimos observar en la figura 6 el acarreo de salida debe pasar a través de dos niveles de compuertas (AND-OR) lo que significa que el tiempo que tarda en dar una respuesta es el tiempo de propagación de dos compuertas lógicas, para el segundo Full Adder debido a que debemos esperar al primero tardaría 4 tiempos de propagación y así sucesivamente, entonces para nuestro octavo Full Adder el tiempo de espera para obtener una respuesta sólida es de 16 tiempos de propagación por ello no es conveniente usar un Ripple Carry Adder para valores grandes.

La alternativa es usar un Carry-LookAhead Adder, la idea es que podamos determinar de una forma más rápida si el acarreo de salida será 0 o 1 y con ello eliminar los retrasos por tiempo de propagacipón de sumadores de varios bits.

Si partimos de la ecuación booleana que simplificamos en la figura 5 podemos factorizar el acarreo de entrada y obtener la siguiente expresión:

En esta nueva expresión equivalente vemos que tenemos separados dos términos, como ambos se unen por un OR significa que con que al menos uno sea verdadero vamos a obtener un acarreo de salida, el primer término "XY" quiere decir que si X e Y son verdaderos se asegura un acarreo de salida ya que la suma daría 2 que en binario es 10 y el bit más significativo representa el acarreo, por otro lado en el segundo término "X+Y" quiere decir que si almenos una de las dos entradas X o Y es verdadera vamos a obtener en el acarreo de salida el mismo valor que tiene el acarreo de entrada.

Para este punto puede parecer que solo se reorganizó la ecuación original, pero hacer esto nos da grandes libertades, por ejemplo, podemos llamar al término "XY" como G_i y al término "X+Y" como P_i y renombrar a los acarreos como C_i+1 para el acarreo de salida y C_i para el acarreo de entrada. De esa forma podemos calcular el acarreo siguiente con una sintaxis más simple.

Siguiendo esta misma lógica podemos calcular el acarreo en dos instantes posteriores metiendo expresiones dentro de expresiones como se aprecia en la siguiente imagen:

Bajo esta misma idea podemos obtener las expresiones para todos los acarreos posteriores usando un número constante de compuertas. Como una forma de entender a que me refiero, asi se vería un sumador de 2 bits usando este método y las expresiones que ya calculamos.

Finalmente así se vería el Carry-LookAhead de 8 bits.

Es fácil darnos cuenta que este circuito adquiere demasiada complejidad muy rapidamente y esto solo con 8 bits, si intentaramos crear sumadores más convencionales de 32 o incluso 64 bits el número de compuertas necesarias se dispararía, por ello hoy en día nadie se procupa por alambrar estos circuitos ya que con la llegada de los HDL's podemos hacer el proceso de sintetización y alambrado de este circuito que a mi me tomó más de 5 horas en tan solo 5 minutos.

Antes de pasar a los ejemplos en HDL's quiero recalcar que al diseñar un circuito sumador podemos optar por usar menos compuertas con un Ripple Carry Adder o buscar eficiencia y velocidad a coste de un incremento de hardware con un Carry-LookAhead Adder. Ninguna de estas es la mejor opción y debemos siempre implementar la que más nos convenga para cada aplicación.

Descripción del Circuito

AHDL

Implementación de compuerta Sumador con operadores aritméticos en AHDL.

SUBDESIGN Adder8 (
    A[7..0], B[7..0] : INPUT;
    Z[8..0]          : OUTPUT;
)

BEGIN
    Z[] = (0, A[])+(0, B[]);
END;

VHDL

Implementación de compuerta Sumador con operadores aritméticos en VHDL.

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ENTITY Adder8 IS 
    PORT(A, B : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
         Z    : OUT STD_LOGIC_VECTOR(8 DOWNTO 0));
END Adder8;

ARCHITECTURE Sumador OF Adder8 IS
BEGIN
    Z <= ('0'&A)+('0'&B);
END Sumador;

Verilog

Implementación de compuerta Sumador con operadores aritméticos en Verilog.

module Adder8(A, B, Z);
    input [7:0] A, B;
    output [8:0] Z;
        
    assign Z = A+B;
endmodule