miércoles, 8 de septiembre de 2010

Como hacer una ALU en la Spartan 3

Según la revista Master Magazinel la Unidad Aritmético Lógica, o simplemente ALU (por Arithmetic Logic Unit) es una de las unidades que conforman la Unidad Central de Procesos (CPU) mediante la cual se pueden realizar un conjunto de operaciones aritméticas básicas (resta, suma, división y multiplicación) y de operaciones lógicas (OR, NOT, AND, etc.)

Los circuitos mediante los que la ALU ejecuta dichas operaciones pueden ser desde muy simples a muy complejos. Entre estos últimos se encuentran, por ejemplo, los de los chips de losmicroprocesadores. En general, la mayoría de las acciones de una computadora se realizan a través de una ALU. Y en dichos circuitos se encuentras diversos componentes que permiten que la ALU pueda efectuar las operaciones.

Para esta practica se realizo una ALU con las siguientes operaciones:
1.      NOT de 2 bits
2.      AND de 2 bits
3.      OR de 2 bits
4.      XOR de 2 bits
5.      Suma de 2 bits + 2bits
6.      Multiplicación de 2 bits * 2 bits
7.      Corrimiento a la izquierda
8.      Corrimiento a la derecha



Ahora para pasar a la realizacion del codigo se tiene que debido a que la tarjeta Spartan 3 solo tiene 8 switches se realizo un arreglo en la declaracion de variables como se explicara mas adelante.
En las variables todas las tuvimos que hacer un arreglo del mismo tipo aunque no usara todas las posibles combinaciones ya que si no marcaba algunos errores y de este modo ya no marco nada. Asi que es una recomendacion a seguir.

entity ALU is
    Port ( x : in  STD_LOGIC_vector(3 downto 0); --arreglo de 4 bits
           y : in  STD_LOGIC_vector(3 downto 0);
           Operation : in  STD_LOGIC_vector(3 downto 0);  
 result : out std_logic_vector(3 downto 0)
);
end ALU;

En este caso X y Y seran tus dos numeros de dos bits cada uno
Result sera el resultado a imprimir y Operation sera la variable que complementa el case y el process para que cuando esa variable cambie, todas las demas cambien.

architecture Behavioral of ALU is
signal Temp : STD_LOGIC;
begin

process (operation, x, y) --inicio del process
*Nota: lo que hace un process es como un arreglo donde los valores que estan dentro de parentesis cuando cambian lo inicializan y los valores que tenian asignados cambian.
begin
case operation is  -- el case son como tus condiciones a seguir dentro del programa
when "0000" => result <= "0000"; --NOT
result <= not x;
Este ejemplo de la primer linea dice que cuando tu numero binario sea "0000" tu variable result se le asignara la operacion negacion de X y "0000" que esta antes es solo para que cuando cambien las variables empiezen desde 0 y no haya error de que se les quedo guardado un valor de  la operacion anterior a la hora de cambiar a otra. Es por ello que  la parte de "0000" aparece en todo el codigo.

when "0001" => result <= "0000"; --AND
result(0) <= x(0) and y(0);
Esta segunda parte hace una simple compuerta AND de X y Y pero solo de su primer bit, es decir del menos significativo, ya que si recuerdan X y Y son numeros de dos bits pero aqui solo hace la AND de los dos primeros.
De aqui en adelante es la misma metodologia para las demas.
when "0010" => result <= "0000";
result(0) <= x(0) or y(0); --OR
when "0011" => result <= "0000";
result(0) <= x(0) xor y(0); --XOR

Esta linea es de las mas complejas de entender ya que si se fijaron en el principio tras el architecture se declaro una variable temporal, esta es para la suma ya que si ven el diagrama de una suma de un numero de dos bits con otro, encontraran que hay carrys que en este caso pasan a ser la variables temp y que las siguientes partes  es la secuencia logica que sigue un full adder.
when "0100" => result <= "0000"; --ADD
result(0) <= x(0) xor y(0);
Temp<= x(0) and y(0);
result(1) <= x(1) xor y(1) xor Temp;
result(2) <= (x(1) and y(1)) or (x(1) and Temp) or (y(1) and Temp);
Los corrimientos se hacen con una sustitucion ya que si saben como funciona un corrimiento quiere decir que el valor que venia antes de el pasa a ser su nuevo valor del actual, es decir si x=0 y el siguiente valor es 1 ahora x pasara a ser 1
when "0101" => result <= "0000"; --x<<y
result(0) <= x(1); --al primer valor pasale el valor que tiene x(1)
result(1) <= y(0); -- al siguiente valor pasale el valor que tiene y(0)
when "0110" => result <= "0000"; --x>>y
result(0) <= y(0);
result(1) <= x(0);
La parte mas compleja de visualizar es la multiplicacion ya que para llevarla acabo tienes que deducir una logica similiar a cuando multiplicas con numeros base 10, ya que vas multiplicando bit por bit y luego tienes que sumar los resultados que te van saliendo en caso de ser posible.
Para darte una idea aqui esta el siguiente ejemplo:


Cuando multiplicas 1*1= 1, luego 1*0=0 y asi sucesivamente, te daras cuenta de que multiplicas el primer bit por todos los de arriba y continuas con el procedimiento como mencionaba antes como si fuera base 10 y asi te da el resultado de la multiplicacion pero en binario, posteriormente tienes que sumar los valores para obtener una sola expresion y el numero final es el que tienes que visualizar. 




Para saber que compuertas tienes que usar aqui esta el siguiente ejemplo:

 Si te das cuenta la multiplicacion de un bit por un bit se asemeja a la compuerta AND por lo tanto las compuertas que usas para multiplicar son ANDs y EXORs para hacer las sumas de los bits temporales tal como vimos en la parte del adder. Con esta logica encuentras el siguiente codigo para la multiplicacion de dos bits por dos bits.


when others => result <= "0000"; --multiplicación
result(0) <= x(0) and y(0);
result(1) <= (x(1) and y(0)) xor (y(1) and x(0));
Temp <= (x(1) and y(0)) and(y(1) and x(0));
result(2)<= ((x(1) and y(1)) xor Temp);
result(3)<=((x(1) and y(1)) and Temp);
end case; --cierre de los case
   end process; -cierre de process
end Behavioral; --cierre de programa

Por último cabe resaltar que a la hora de programar te marcara el código unos warnins pero puedes hacer caso omiso de ellos pues pese a esto el codigo funciona muy bien y hace las operaciones que se especifican de manera correcta. 
Recuerda tambien con el planAhead asignar pines y con el programa adept bajarlo a tu tarjeta para probarlo.

No hay comentarios:

Publicar un comentario