Está en la página 1de 20

Elaboración de la ALU en VHDL

12) ALU: Realice un sistema que compruebe la siguiente tabla de verdad de una Unidad Lógica
Aritmética de datos de 8 bits, la cual realiza las siguientes operaciones lógicas, aritméticas, de
desplazamiento y comparación, despliegue el resultado en 2 displays de 7 segmentos y 3 leds para
la salida de comparación:

Operación S A B F M m i

A AND B 0 93h 49h 01h 0 0 0

A OR B 1 93h 49h DBh 0 0 0

NOT (A) 2 93h XX 6Ch 0 0 0

A NAND B 3 93h 49h FEh 0 0 0

A NOR B 4 93h 49h 24h 0 0 0

A XOR B 5 93h 49h DAh 0 0 0

A XNOR B 6 93h 49h 25h 0 0 0

A+B 7 93h 49h DCh 0 0 0

A-B 8 93h 49h 4Ah 0 0 0

A*B 9 93h 49h EBh 0 0 0

A^2 10 93h XX 69h 0 0 0

SLL(A, 1) 11 93h XX 26h 0 0 0

SRL(A, 1) 12 93h XX 49h 0 0 0

SLL(A, 4) 13 93h XX 30h 0 0 0

SRL(A, 4) 14 93h XX 09h 0 0 0

A>B 93h 49h 93h 1 0 0

A<B 15 49h 93h 93h 0 1 0


A=B 93h 93h 93h 0 0 1
Para comenzar, tomamos de referencia el código del multiplexor, definiendo los puertos A y B de 8
bits, la entrada selectora en un rango de 0 a 15 y la salida igual de 8 bits (por el momento, ya que la
salida debe ser desplegada en 2 displays 7 segmentos):

Como se observa, solamente se llegó al caso 6, que se refiere a las operaciones lógicas, las cuales se
pueden realizar con los datos std_logic_vector sin problema. Ahora bien, para realizar las
operaciones aritméticas, debemos convertir el puerto A y B de std_logic_vector a un tipo de dato
entero, esto lo hacemos de la siguiente manera:

Las funciones aritméticas, conv_integer y conv_std_logic_vector están dentro de las librerías:


use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all; por lo que hay que agregarlas.
Se observa que la operación aritmética (en este caso la suma y la resta, se hace con las señales
enteras, obtenidas a partir de los puertos A y B, y después se regresa al tipo de dato
std_logic_vector, indicando que el tamaño del vector es de 8 bits.

Ahora bien, se muestran los demás casos, donde además se incluyen los desplazamientos lógicos,
los cuales se harán con multiplicaciones y divisiones, por lo que se realizan igual con las señales AA
y BB. Así mismo se agrega el caso 15 de comparación con los 3 posibles casos:

En este momento lo guardamos como alu.vhd, creamos el proyecto, lo compilamos y simulamos


para ver que nos genere la salida, recordando que aún está en 8 bits, por lo que falta decodificarlo:
Recuerden que no importan los warnings, solamente que no existan errores, les dejo el encabezado
para que observen las librerías

Para simular, creamos un archivo vector waveform, agregamos los nodos y colocamos A, B y F en
radix hexadecimal, Mmi en binario y S en unsigned decimal:
A los puertos A y B les damos un valor arbitrario (ícono con el símbolo ¿), de acuerdo a los valores
de la tabla:
Y a la selectora le asignamos un count value (incluso pueden mover el puerto para que quede de la
siguiente manera:
Y al guardarlo y darle simular nos da las siguientes salidas:
Si observan nos genera las salidas tal como se muestran en la tabla del inicio, ahora bien,
modificaremos los datos del vector de forma de onda. Pueden abrir el archivo de simulación original
(sin la salida generada) para modificar los valores de los puertos de entrada, dando CTRL+O y
seleccionando el tipo de archivo .vwf:
Así con el archivo original .vwf modificaremos los datos para que demostremos también los demás
casos de la comparación, así como también podemos asignarles valores “don’t care” para que se
apegue más a la tabla:
Ya con los valores asignados en la tabla de verdad, guardamos y volvemos a simular:
Aún no acabamos, ya que la salida de la última simulación está en binario, y se requiere la salida en
hexadecimal, lo que haremos es un proceso conocido como “enmascaramiento” en el cual
partiremos el dato de 8 bits de la salida para convertirlo en 2 datos de 4 bits cada uno:

El proceso de “enmascaramiento” se hace de la siguiente manera, simplemente es partir el dato F


de 8 bits en 2 de 4 bits y convertirlos a entero, esto para meterlo al decodificador en cada display:
Como se crearon diferentes variables, éstas se declaran como señales de la siguiente manera:

Y ya con las señales definidas y el enmascaramiento, simplemente incluímos 2 decodificadores, uno


para cada datos (F1 y F2), que ya están en decimal de 0 a 15:
Ahora bien, volvemos a generar otro archivo “vector waveform”, para actualizar los puertos
(recordar que el puerto de salida F de 8 bits se convirtió a señal y se crearon 2 puertos (D1 y D2),
para la salida a los 2 displays 7 segmentos, los cuales veremos en binario):
Para demostrar el resultado, se agregaron dos columnas para el valor correspondiente de los 2
displays, en ánodo común, para poder implementarlos físicamente en la tarjeta de desarrollo FPGA:

Operación S A B F M m i D2 D1

A AND B 0 93h 49h 01h 0 0 0 0000001 1001111

A OR B 1 93h 49h DBh 0 0 0 1000010 1100000

NOT (A) 2 93h XX 6Ch 0 0 0 0100000 0110001

A NAND B 3 93h 49h FEh 0 0 0 0111000 0110000

A NOR B 4 93h 49h 24h 0 0 0 0010010 1001100

A XOR B 5 93h 49h DAh 0 0 0 1000010 0001000

A XNOR B 6 93h 49h 25h 0 0 0 0010010 0100100

A+B 7 93h 49h DCh 0 0 0 1000010 0110001

A-B 8 93h 49h 4Ah 0 0 0 1001100 0001000

A*B 9 93h 49h EBh 0 0 0 0110000 1100000

A^2 10 93h XX 69h 0 0 0 0100000 0000100

SLL(A, 1) 11 93h XX 26h 0 0 0 0010010 0100000

SRL(A, 1) 12 93h XX 49h 0 0 0 1001100 0000100

SLL(A, 4) 13 93h XX 30h 0 0 0 0000110 0000001

SRL(A, 4) 14 93h XX 09h 0 0 0 0000001 0000100

A>B 93h 49h 93h 1 0 0 0000100 0000110

A<B 15 49h 93h 93h 0 1 0 0000100 0000110


A=B 93h 93h 93h 0 0 1 0000100 0000110
Código VHDL
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity alu is
port(A,B:in std_logic_vector(7 downto 0);
S:in integer range 0 to 15;
Mmi:out std_logic_vector(2 downto 0);
D1,D2:out std_logic_vector(6 downto 0));
end entity;

architecture arq of alu is


signal AA,BB:integer range 0 to 255;
signal F:std_logic_vector(7 downto 0);
signal FL,FH:std_logic_vector(7 downto 0);
signal FLi,FHi:integer range 0 to 255;
signal FL4,FH4:std_logic_vector(3 downto 0);
signal F1,F2:integer range 0 to 15;
begin
process(S)
begin
AA<=conv_integer(A);BB<=conv_integer(B);
case S is
when 0 => F <= A and B;Mmi<="000";
when 1 => F <= A or B;Mmi<="000";
when 2 => F <= not A;Mmi<="000";
when 3 => F <= A nand B;Mmi<="000";
when 4 => F <= A nor B;Mmi<="000";
when 5 => F <= A xor B;Mmi<="000";
when 6 => F <= A xnor B;Mmi<="000";
when 7 => F <= conv_std_logic_vector(AA + BB,8);Mmi<="000";
when 8 => F <= conv_std_logic_vector(AA - BB,8);Mmi<="000";
when 9 => F <= conv_std_logic_vector(AA * BB,8);Mmi<="000";
when 10 => F <= conv_std_logic_vector(AA ** 2,8);Mmi<="000";
when 11 => F <= conv_std_logic_vector(AA * 2,8);Mmi<="000";
when 12 => F <= conv_std_logic_vector(AA / 2,8);Mmi<="000";
when 13 => F <= conv_std_logic_vector(AA * 16,8);Mmi<="000";
when 14 => F <= conv_std_logic_vector(AA / 16,8);Mmi<="000";
when 15 => if (A > B) then
F <= A;Mmi<="100";
elsif (A < B) then
F <= B;Mmi<="010";
else
F <= A or B;Mmi<="001";
end if;
end case;
FL<=F and "00001111";
FLi<=conv_integer(FL);
FL4<=conv_std_logic_vector(FLi,4);
F1<=conv_integer(FL4);

FH<=F and "11110000";


FHi<=conv_integer(FH);
FH4<=conv_std_logic_vector(FHi/16,4);
F2<=conv_integer(FH4);

case F1 is
when 0 => D1 <= not"1111110";
when 1 => D1 <= not"0110000";
when 2 => D1 <= not"1101101";
when 3 => D1 <= not"1111001";
when 4 => D1 <= not"0110011";
when 5 => D1 <= not"1011011";
when 6 => D1 <= not"1011111";
when 7 => D1 <= not"1110000";
when 8 => D1 <= not"1111111";
when 9 => D1 <= not"1111011";
when 10 => D1 <= not"1110111";
when 11 => D1 <= not"0011111";
when 12 => D1 <= not"1001110";
when 13 => D1 <= not"0111101";
when 14 => D1 <= not"1001111";
when 15 => D1 <= not"1000111";
end case;
case F2 is
when 0 => D2 <= not"1111110";
when 1 => D2 <= not"0110000";
when 2 => D2 <= not"1101101";
when 3 => D2 <= not"1111001";
when 4 => D2 <= not"0110011";
when 5 => D2 <= not"1011011";
when 6 => D2 <= not"1011111";
when 7 => D2 <= not"1110000";
when 8 => D2 <= not"1111111";
when 9 => D2 <= not"1111011";
when 10 => D2 <= not"1110111";
when 11 => D2 <= not"0011111";
when 12 => D2 <= not"1001110";
when 13 => D2 <= not"0111101";
when 14 => D2 <= not"1001111";
when 15 => D2 <= not"1000111";
end case;
end process;
end architecture;
Simulación en Quartus II

Fácil, ¿no? 