Está en la página 1de 25

UPIITA-IPN Materia: Circuitos Lógicos

Práctica No. 3 y 4: Circuitos combinacionales básicos. Circuitos Número de mesa: 1


combinacionales aritméticos y Lógicos. Nombre de la empresa: Mexilogics
Álvarez Gómez Julio César Grupo: 2MV12
Galván Escobar Adrián Raúl
Mata Prieto Varush
Varela Alpizar Benjamin

Resumen
En el presente documento se reporta la implementación de los diferentes circuitos
combinacionales para una ALU (Unidad Lógica Aritmética) para variables de 4 bits mediante
el uso del lenguaje descriptivo de hardware VHDL
Abstract
In this paper is reported the implementation of the differents combinational circuits for an
ALU (Arithmetic Logic Unit) for 4-bits variables throught the use of hardware descriptive
language VHDL.
Résumé
Dans ce document on signale l’implementation des differents circuits combinationnels pour
un ALU (Unité aritmétique et Logique) pour des variables de 4 bits via l’utilisation du
langage descriptive de hardware VHDL.
Tabla de contenidos
Puntos VHDL Verilog UCF Fotos Diagramas Tabla Simulación
1.- Unipolar
step motor
control
2.- D&C 3-
floors light
controller
3.- 5 bits
divider
4.- Algebraic
functions
5.- Scale
6.- 8 logic
functions
CH1(1-2)
CH2 (1-2)
CH3(3-5)
CH4(3-6) ✓ ✓ ✓ ✓
1
Introducción
Teclado Matricial 4X4
Un teclado matricial 4x4 es un dispositivo que agrupa varios pulsadores y permite
controlarlos empleando un número de conductores inferior al que necesitaríamos al usarlos
de forma individual. Los pulsadores se agrupan en filas y columnas formando una matriz de
disposición de 4x4 (es decir, 16 pulsadores en un arreglo cuadrado).
El teclado 4x4 se encuentra formado por la matriz de pulsadores que se encuentran dispuestos
en filas (L1, L2, L3 y L4), y las columnas (C1, C2, C3 y C4) (ver figura 1) y esta organización
se emplea con el fin de reducir el número de pines requeridos para su conexión de 16 que
serían normalmente por cada pulsador a solo 8. Para poder realizar la lectura de los botones
pulsados es necesario utilizar una técnica de barrido. En la figura _ se muestra la disposición
de los conectores y las filas y columnas.

Figura 1.- Disposición de filas y columnas del teclado matricial 4x4

Entre sus especificaciones tenemos:


• Máximo voltaje de operación de 24V en DC
• Máxima corriente de operación de 30mA
• Dimensiones del teclado: 69 mm * 77 mm
• Temperatura máxima de operación de 50°C.
Metodología desplazar y añadir 3 (Shift and Add 3)
Esta metodología es utilizada cuando buscamos convertir un número de binario a decimal y
este número es de un valor grande.
Este algoritmo consiste en desplazar (shift) el vector inicial (que será el número que
deseemos codificar, en binario) el número de veces necesario según sea el número de bits, y
cuando alguno de los bloques de 4 bits (Unidad-Decena-Centena-Unidad de Millar o U-D-
C-UM) que es el número de bits necesario para que cuente de 0 a 9 por cifra) sea igual o

2
mayor a 5 se le debe sumar 3 a ese bloque, después se continua desplazando hasta que otro
(o el mismo) bloque cumpla con esa condición y se le sumen 3. Finalmente se asigna a otro
vector el vector ya convertido, que cuenta con 4 bloques para las 4 cifras de 4 bits cada una.
Para ilustrar mejor lo antes mencionado, en la siguiente tabla (ver tabla 1) se realizará esta
metodología para el número 5629 (en binario 1_0101_1111_1101).
Tabla 1.- Metodología Shift-and-Add 3 para el número 5629 decimal

Es importante resaltar que, para poder realizar esta metodología para todos los números
posibles en 4 displays de 7 segmentos (de 0 a 9999) es necesario conocer los bits necesarios
para realizar este algoritmo con el número más grande (es decir, con 9999 o
10_0111_0000_1111 en binario)
Por lo tanto, el total de bits es: 14 bits para los números en binario a convertir en decimal +
(4 bits por bloque de unidad * 4 unidades) el cual nos da un total de: 14 + 16 = 30 bits para
realizar este algoritmo con todos los números mostrables posibles en 4 displays de 7
segmentos.
Unidad Lógica Aritmética - ALU
La unidad lógica aritmética, también conocida como ALU, es un circuito digital que calcula
operaciones aritméticas y operaciones lógicas entre valores (generalmente 2) de los
argumentos. Es una unidad de creación fundamental presente en cualquier procesador de
CPU en la actualidad.
Entre las operaciones aritméticas de una ALU tenemos:
• Adición
• Sustracción

3
• Multiplicación
• División
Entre las operaciones lógicas de una ALU tenemos:
• AND
• OR
• NOT
• NOR
• XOR
• XNOR
Algunas de las ALU pueden realizar funciones adicionales u operaciones más complejas,
como son:
• Operación de desplazamiento de bits
• Cálculo de Raíz cuadrada
Entradas y salidas de la ALU: Las entradas de una ALU son los datos a los cuales se les harás
las operaciones (denominados operandos) y un selector que indicará que operación realizar
o mostrar (dependiendo del diseño de la ALU). La salida de una ALU será el resultado de las
operaciones y para su visualización generalmente se implementa el uso de indicadores como
displays LCD, displays de 7 segmentos o cualquier otro que permita la visualización de los
resultados.
Para nuestra ALU, los operandos serán de 4 bits ingresados por medio de un teclado matricial
(componente que se conectará a los puertos de expansión de la tarjeta de desarrollo FPGA
Amiba2). De igual manera los resultados se mostrarán en los displays de 7 segementos y leds
incorporados en la tarjeta de desarrollo FPGA antes mencionada.
ALU en VHDL con diseño de alto nivel
Se emplearon los siguientes componentes para la codificación de la ALU:
• Programa principal: Ingreso de datos en hexadecimal vía teclado matricial 4x4.
• 1er componente: Lectura de datos ingresados mediante el teclado matricial 4x4
• 2do componente: Sumador-Restador-Divisor-Multiplicador y operadores lógicos de
4 bits con salida a display de 7 segmentos y leds testigos
• 3er componente: Convertidor BCD mediante el algoritmo Shift and Add 3.
• 4to componente: Controlador de display de 7 segmentos
• 5to componente: Divisor de frecuencia para la señal de barrido de los displays
A continuación, en el desarrollo, se detallará en cada uno de los componentes antes
mencionados.

4
Desarrollo
Challenge 4:
El desafío 4 consistía en la implementación de una ALU de 4 bits que diera como resultado
las operaciones de suma, resta, multiplicación, división, and, or, xor y not) de los operandos
ingresados mediante un teclado matricial 4x4 y que tuviera como elementos de salida leds y
displays de 7 segmentos.
En primer lugar, para conectar el teclado matricial a la FPGA, fueron necesarias resistencias
cuyos valores fueron determinados basándonos en las especificaciones mencionadas en la
introducción (tensión máxima de 24V en DC y corriente de 30mA) y recordando que el nivel
de voltaje para 1 lógico en la tarjeta de desarrollo Amiba2 es de 3.2V (ver figura 2):
(24 − 3.2)[𝑉]
𝑅 = = 693.33 [Ω] ≅ 680[Ω]
0.03 [𝑚𝐴]

Esquemático:

Figura 2.- Conexión leds a teclado matricial. Asignación vectores para las filas y columnas del
teclado matricial para FPGA

5
De igual manera, como se mencionó en la introducción, implementando diseño de alto nivel
TLD, el programa resultante para nuestra ALU se compone del programa principal y 5
componentes, los cuales realizan las siguientes tareas (ver figura 3):

Figura 3.- Entidad para la ALU de 4 bits hecho en TLD

• Programa principal: Ingreso de operandos mediante el teclado matricial 4x4 (estos


se introducen en formato binario). (Bloque “OBTENER NUM”)
• 1er componente: Lectura de las teclas presionadas para regresar un valor en
hexadecimal (Bloque “LIBRERÍA TECLADO 4x4”).
• 2do componente: Realizar las operaciones aritméticas y lógicas. (Bloque “ALU”)
• 3er componente: Convertir los resultados de 8 bits de las operaciones aritméticas en
decimal separando por bloques de unidades, decenas, centenas y unidades de millar
(empleando la metodología “shift and add 3”). (Bloque “SHIFT-ADD3)
• 4to componente: Control de los displays de 7 segmentos, así como sus nodos para
mostrar los resultados en decimal o indicar que operación lógica se esta mostrando
en los leds incorporados a la FPGA. (Bloque “DISPLAY”)
• 5to componente: Divisor de frecuencia para la señal de barrido en los displays y
hacer posible la visualización de los resultados. (Bloque “DIV”).
Programa principal:
En este archivo .vhd se llama a los 5 componentes que conforman a nuestra ALU, lee los
datos ingresados en el teclado matricial 4x4, los cuales serán números en formato binario.
----------------------------------------------------------------------
------------
--MEXILOGICS
--ALU de 4 bits controlado por un teclado 4x4
--------------------------------------------------------
--Sumador, restador, multiplicador y división
--Con salida a display

6
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
--Declaracin de la entidad
entity ALU_TLD is
Port(
CLK: in std_logic; --Reloj de 50MHz
COLUMNAS : in std_logic_vector(3 downto 0); -- columnas
teclado 4x4
FILAS : out std_logic_vector (3 downto 0); -- filas teclado
4x4
LEDs : out std_logic_vector (7 downto 0); --Salida a LEDs
testigos
DISPLAY: out std_logic_vector (7 downto 0); --Segmentos del
display
AN: out std_logic_vector (7 downto 0) ); --nodos del display
end ALU_TLD;

architecture Behavioral of ALU_TLD is

component LIB_TEC_MATRICIAL_4x4_INTESC_RevA is

--Llamando a la librera para controlar el teclado


GENERIC(
FREQ_CLK : INTEGER := 50_000_000 ); --
FRECUENCIA DE LA TARJETA

PORT(
CLK : IN STD_LOGIC;
--RELOJ FPGA
COLUMNAS : IN STD_LOGIC_VECTOR(3 DOWNTO 0); --PUERTO
CONECTADO A LAS COLUMNAS DEL TECLADO
FILAS : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --PUERTO
CONECTADO A LA FILAS DEL TECLADO
BOTON_PRES : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --PUERTO QUE
INDICA LA TECLA QUE SE PRESION
IND : OUT STD_LOGIC);
--BANDERA QUE INDICA CUANDO SE PRESION UNA TECLA (SLO
DURA UN CICLO DE RELOJ)

end component LIB_TEC_MATRICIAL_4x4_INTESC_RevA;

--Declaracin de seal que indica los valores de A y de B


signal NuA:std_logic_vector(3 downto 0); --Asigna el nmero A
signal NuB:std_logic_vector(3 downto 0); --Asigna el nmero B

--Declaracin de seal que indica si se presion un botn


signal boton_pres : std_logic_vector (3 downto 0) := (others => '0');

--Declaracin de seal que indica la direccin del botn presionado


signal ind : std_logic := '0';

--Declaracin de seales del divisor

7
signal SAL_400Hz: std_logic;

--Declaracin de seales del resultado


signal resultado: std_logic_vector (7 downto 0);

--Declaracin de seales de asignacin de U-D-C-UM


signal UNIint,DECint,CENint,signoint: std_logic_vector (3 downto 0); -
-U-D-C-signo

--Declaracin del selector


signal selOPint: std_logic_vector (3 downto 0):="0000";

begin
-- Asignación para el módulo de teclado matricial
libreria : LIB_TEC_MATRICIAL_4x4_INTESC_RevA
Generic map (FREQ_CLK => 50000000)
port map (
CLK => CLK,
COLUMNAS => COLUMNAS ,
FILAS => FILAS,
BOTON_PRES => BOTON_PRES,
ind => IND );

process(clk,ind,boton_pres,NuA,NuB)
--Proceso para declarar A y B
variable u: integer :=0;
begin
if rising_edge(clk) then
--Se usa un ciclo for para poner 1 o 0 en las entradas de los nmeros
para
--realizar las operaciones
--Los nmeros se ingresan del bit ms significativo al menos

if u=0 then
if ind = '1' and boton_pres=x"0" then
NuA(3)<='0';u:=u+1; --Si se presiona 0, se ingresa a 0
elsif ind = '1' and boton_pres=x"1" then
NuA(3)<='1';u:=u+1; --Al presionar 1 se ingresa como un 1
else u:=0;
end if;

elsif u=1 then


if ind = '1' and boton_pres=x"0" then
NuA(2)<='0';u:=u+1; --Si se presiona 0, se ingresa a 0
elsif ind = '1' and boton_pres=x"1" then
NuA(2)<='1';u:=u+1; --Al presionar 1 se ingresa como un 1
end if;

elsif u=2 then


if ind = '1' and boton_pres=x"0" then
NuA(1)<='0';u:=u+1; --Si se presiona 0, se ingresa a 0
elsif ind = '1' and boton_pres=x"1" then
NuA(1)<='1';u:=u+1; --Al presionar 1 se ingresa como un 1
end if;

8
elsif u=3 then
if ind = '1' and boton_pres=x"0" then
NuA(0)<='0';u:=u+1; --Si se presiona 0, se ingresa a 0
elsif ind = '1' and boton_pres=x"1" then
NuA(0)<='1';u:=u+1; --Al presionar 1 se ingresa como un 1
end if;

elsif u=4 then


if ind = '1' and boton_pres=x"0" then
NuB(3)<='0';u:=u+1; --Si se presiona 0, se ingresa a 0
elsif ind = '1' and boton_pres=x"1" then
NuB(3)<='1';u:=u+1; --Al presionar 1 se ingresa como un 1
end if;

elsif u=5 then


if ind = '1' and boton_pres=x"0" then
NuB(2)<='0';u:=u+1; --Si se presiona 0, se ingresa a 0
elsif ind = '1' and boton_pres=x"1" then
NuB(2)<='1';u:=u+1; --Al presionar 1 se ingresa como un 1
end if;

elsif u=6 then


if ind = '1' and boton_pres=x"0" then
NuB(1)<='0';u:=u+1; --Si se presiona 0, se ingresa a 0
elsif ind = '1' and boton_pres=x"1" then
NuB(1)<='1';u:=u+1; --Al presionar 1 se ingresa como un 1
end if;

elsif u=7 then


if ind = '1' and boton_pres=x"0" then
NuB(0)<='0';u:=u+1; --Si se presiona 0, se ingresa a 0
elsif ind = '1' and boton_pres=x"1" then
NuB(0)<='1';u:=u+1; --Al presionar 1 se ingresa como un 1
end if;

--Proceso para obtener el valor para seleccionar la operacin


--Leemos el siguiente valor, el cual ser presionado en el
teclado
--Dependiendo del valor se mostrar la operacin deseada

elsif u=8 then


if ind = '1' and (boton_pres = x"1" or
boton_pres = x"2" or boton_pres = x"3" or boton_pres = x"A"
or boton_pres = x"4" or boton_pres = x"5" or
boton_pres = x"6" or boton_pres = x"B" or boton_pres =x"7"
or boton_pres = x"8") then selOPint<=boton_pres;
elsif ind ='1' and boton_pres=x"E" then u:=0;
NuA<=x"0";NuB<=x"0"; selOPint<=x"0";
end if;
end if;
end if;
end process;

9
--Declaracin para realizar las operaciones
--aritméticas lógicas
U1: entity work.ALU_op port map(
A => NuA,
B => NuB,
C => resultado,
selOP => selOpint,
signo => signoint,
ledt=> leds );

--Declaracin del componente que convierte de binario a decimal


--por la metodologa de correr y sumar 3 (shift and add 3)
U2: entity work.SHIFT_ADD port map(
C => resultado, --a seal p/LD y srmd (U1)
UNI => UNIint, -- Seales a los displays
DEC => DECint,
CEN => CENint );

--Controlador de display de 7 segmentos


U3: entity work.DISPLAYS port map(
UNI => UNIint, -- Seales a los displays
DEC => DECint,
CEN => CENint,
signo => signoint,
SAL_400Hz => SAL_400Hz, --A seal de reloj U4
DISPLAY => DISPLAY, --A segmentos de display
AN => AN, --A nodos del display
selOP => selOPint);

--Declaracin del componente divisor (2.5ms=400Hz)


U4: entity work.DIV_CLK port map(
clk => clk,
SAL_400Hz => SAL_400Hz);
end Behavioral;

• 1er componente:
La librería del teclado matricial (ver figura 4) tiene la
función de regresar el dato que pulsamos en el teclado
matricial en hexadecimal e indica si se ha pulsado un
botón. Este componente fue consultado de la página
de Intesc (los desarrolladores de la tarjeta Amiba2) y
se puede descargar desde el link
https://intesc.mx/libreria-teclado-matricial/

Figura 4.- Entidad “Librería Teclado


Matricial”, cortesía de Intesc

10
• 2do componente:
Este componente se encarga de realizar las operaciones aritméticas y lógicas de los datos
ingresados. Cabe resaltar que para las operaciones aritméticas las respuestas las guarda como
señales que serán utilizadas para su muestra en los displays de 7 segmentos, mientras que los
resultados de las operaciones lógicas los mostrará en los leds incorporados en la FPGA.
--------------------------------------------------------
--MEXILOGICS
--programa de sumador, restador, divisor y multiplicador
--de 4 bits con salida a display y led testigos con BCD
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
--------------------------------------------------------
--Declaracin de la entidad
entity ALU_op is
Port(
A,B: in std_logic_vector(3 downto 0); --Entradas ingresadas
por teclado 4x4
c: inout std_logic_vector (7 downto 0); --Salida a LED
testigos
signo : out std_logic_vector (3 downto 0); --Salida para el
signo
selOP: in std_logic_vector (3 downto 0);
ledt : out std_logic_vector (7 downto 0) );
end ALU_op;

--Declaracin de la arquitectura
architecture Behavioral of ALU_op is
begin
--Este proceso realiza las operaciones segn el selector selOP
process(A,B,selOP)
begin
case selOP is
when x"1"=>c<=("0000" & A) + ("0000" & B); signo <= x"E"; --
suma
when x"2"=>
if A>B then c<=("0000" & A)-
("0000" & B); signo <= x"E";
else c<=("0000" & B)-("0000" &
A); signo <= x"F";
end if;
when x"3"=>c<= A*B; signo <= x"E";
when x"4"=>
if B = x"0" then c <=x"FF"; signo
<= x"E"; --Si es divisin entre 0
else c <=
conv_std_logic_vector((conv_integer(A)/conv_integer(B)),8); signo <=
x"E"; --Cualquier otro caso
end if;

11
when x"5"=>c<= ("0000" & A) and ("0000" & B); --AND
when x"6"=>c<= ("0000" & A) or ("0000" & B); --OR
when x"7"=>c<= ("0000" & A) xor ("0000" & B); --XOR
when x"8"=>c<= "0000" & not(A);--NOT A
when x"A"=>c<="0000"& A;
when x"B"=>c<="0000" & B;
when others =>c<=(others =>'0'); signo<=x"E";--Cualquier otro
caso
end case;
end process;
ledt <= c;
end Behavioral;

• 3er componente:
Este componente recolecta los resultados de las operaciones aritméticas para realizar el
algoritmo de “shift and add 3” con el fin de convertir los resultados de binario a decimal.
----------------------------------------------------------------------
------------
--MEXILOGICS
--Convertidor SHIFt and add 3
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;

--------------------------------------------------------
--Declaracin de la entidad
entity SHIFT_ADD is
port(
c: in std_logic_vector (7 downto 0):=(others=>'0'); --8 bits
UNI,DEC,CEN: out std_logic_vector (3 downto 0) );
end SHIFT_ADD;
--------------------------------------------------------
--Declaracin de la arquitectura
architecture Behavioral of SHIFT_ADD is
--DECLARACIN DE SEALES DE ASIGNACIN DE U-D-C
signal P:std_logic_vector(11 downto 0); --Asigna UNI,DEC,CEN
-----------CONVERTIR DE BIN A BCD------------------
-- Este proceso contiene un algoritmo recorre y suma 3 para
-- convertir un nmero binario abcd, que se manda a los displays.
begin
PROCESS(C)
--20 bits para separar las Centenas-Decenas-Unidades
VARIABLE C_D_U:STD_LOGIC_VECTOR(19 DOWNTO 0);
BEGIN
--ciclo de inicializacin-------------------------------
FOR I IN 0 TO 19 LOOP -- manda ceros a los 18 bits +2
C_D_U(I):='0'; -- se inicializa con 0
END LOOP;
C_D_U(7 DOWNTO 0):=C(7 downto 0); --c del SRM de 8 bits
--ciclo de asignacin C-D-U--------------------------

12
FOR I IN 0 TO 7 LOOP -- hace 8 veces el ciclo shift-add3
IF C_D_U(11 DOWNTO 8) > 4 THEN -- U --
C_D_U(11 DOWNTO 8):= C_D_U(11 DOWNTO 8)+3;
END IF;
IF C_D_U(15 DOWNTO 12) > 4 THEN -- D --
C_D_U(15 DOWNTO 12):= C_D_U(15 DOWNTO 12)+3;
END IF;
IF C_D_U(19 DOWNTO 16) > 4 THEN -- C --
C_D_U(19 DOWNTO 16):= C_D_U(19 DOWNTO 16)+3;
END IF;
-- shift -- realiza el corrimiento -----------
C_D_U(19 DOWNTO 1):= C_D_U(18 DOWNTO 0);
END LOOP;
P <= C_D_U(19 DOWNTO 8); -- guarda en P y en seguida se separan C-D-U
END PROCESS; -- fin del proceso Display
-- separa C-D-U --
-- UNIDADES --
UNI<=P(3 DOWNTO 0);
-- DECENAS --
DEC<=P(7 DOWNTO 4);
-- CENTENAS --
CEN<=P(11 DOWNTO 8);
------------------------------------------------
end Behavioral; -- fin de la arquitectura

• 4to componente:
Para el muestreo de los resultados en los displays de 7 segmentos, se almacenan los bloques
de 4 bits que corresponden a las unidades, decenas y centenas (obtenidas del componente
anterior) y se codifican.
----------------------------------------------------------------------
--MEXILOGICS
--CONTROLADOR DE DISPLAY DE 4 DGITOS
----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
use IEEE.STD_LOGIC_arith.ALL;
entity DISPLAYS is
Port(
selOP : in std_logic_vector (3 downto 0); --Selector de la
operacin
UNI,DEC,CEN,signo : in std_logic_vector (3 downto 0); --U-D-C
SAL_400Hz : in std_logic; --Reloj de 400Hz
DISPLAY : out STD_LOGIC_VECTOR(7 downto 0); --segmentos del
display
AN : out std_logic_vector (7 downto 0) --nodos del display
);
end DISPLAYS;
----------------------------------------------------------------
-- Declaracin de la arquitectura
architecture Behavioral of DISPLAYS is

13
-- Declaracin de seales de la multiplexacin y asignacin de letras al
disp
signal SEL: std_logic_vector (1 downto 0):="00"; -- selector de
barrido
signal Dig: std_logic_vector (3 downto 0); --Almacena los valores del
disp
signal segments : std_logic_vector (7 downto 0):=x"00";
-- Declaracin de constantes para las letras (AND, OR, XOR, NOT) al
disp
constant A: std_logic_vector (7 downto 0):= "00010001"; -- A
constant N: std_logic_vector (7 downto 0):= "11010101"; -- n
constant D: std_logic_vector (7 downto 0):= "10000101"; -- d
constant V: std_logic_vector (7 downto 0):= "11111111"; -- V sin dato
constant O: std_logic_vector (7 downto 0):= "00000011"; -- O
constant R: std_logic_vector (7 downto 0):= "11110101"; -- r
constant X: std_logic_vector (7 downto 0):= "00111011"; -- ^
constant T: std_logic_vector (7 downto 0):= "11100001"; -- t

begin

---MULTIPLEXOR
Process(SAL_400Hz,selOP,signo,dig,UNI,DEC,CEN)
begin
IF SAL_400Hz'EVENT and SAL_400Hz='1' THEN SEL <= SEL + '1';
--dependiendo de la operacin, muestra un resultado
case(SEL) is
when "00" =>AN<="11110111";
if selOP=x"5" then segments <= V; --andV
elsif selOP=x"6" then segments <= V; --orV
elsif selOP=x"7" then segments <= V; --xorV
elsif selOP=x"8" then segments <= V; --notV
elsif selOP=x"1" or selOP=x"2" or selOP=x"3" or selOP=x"4"
or selOP =x"A" or selOP=x"B" then

case(UNI) is
WHEN x"0" => segments <= "00000011"; --0
WHEN x"1" => segments <= "10011111"; --1
WHEN x"2" => segments <= "00100101"; --2
WHEN x"3" => segments <= "00001101"; --3
WHEN x"4" => segments <= "10011001"; --4
WHEN x"5" => segments <= "01001001"; --5
WHEN x"6" => segments <= "01000001"; --6
WHEN x"7" => segments <= "00011111"; --7
WHEN x"8" => segments <= "00000001"; --8
WHEN x"9" => segments <= "00001001"; --9
WHEN x"F" => segments <= "11111101"; --signo
WHEN OTHERS => segments <= "11111111"; --apagado
end case;
else segments<=V; end if;

when "01" =>AN<="11111011"; --Primer


if selOP=x"5" then segments <= D; --andV
elsif selOP=x"6" then segments <= V; --orV
elsif selOP=x"7" then segments <= R; --xorV

14
elsif selOP=x"8" then segments <= T; --notV
elsif selOP=x"1" or selOP=x"2" or selOP=x"3" or selOP=x"4"
or selOP =x"A" or selOP=x"B" then

case(DEC) is
WHEN x"0" => segments <= "00000011"; --0
WHEN x"1" => segments <= "10011111"; --1
WHEN x"2" => segments <= "00100101"; --2
WHEN x"3" => segments <= "00001101"; --3
WHEN x"4" => segments <= "10011001"; --4
WHEN x"5" => segments <= "01001001"; --5
WHEN x"6" => segments <= "01000001"; --6
WHEN x"7" => segments <= "00011111"; --7
WHEN x"8" => segments <= "00000001"; --8
WHEN x"9" => segments <= "00001001"; --9
WHEN x"F" => segments <= "11111101"; --signo
WHEN OTHERS => segments <= "11111111"; --apagado
end case;
else segments<=V; end if;

when "10" =>AN<="11111101";


if selOP=x"5" then segments <= N; --andV
elsif selOP=x"6" then segments <= R; --orV
elsif selOP=x"7" then segments <= O; --xorV
elsif selOP=x"8" then segments <= O; --notV
elsif selOP=x"1" or selOP=x"2" or selOP=x"3" or selOP=x"4"
or selOP =x"A" or selOP=x"B"then

case(CEN) is
WHEN x"0" => segments <= "00000011"; --0
WHEN x"1" => segments <= "10011111"; --1
WHEN x"2" => segments <= "00100101"; --2
WHEN x"3" => segments <= "00001101"; --3
WHEN x"4" => segments <= "10011001"; --4
WHEN x"5" => segments <= "01001001"; --5
WHEN x"6" => segments <= "01000001"; --6
WHEN x"7" => segments <= "00011111"; --7
WHEN x"8" => segments <= "00000001"; --8
WHEN x"9" => segments <= "00001001"; --9
WHEN x"F" => segments <= "11111101"; --signo
WHEN OTHERS => segments <= "11111111"; --apagado
end case;
else segments<=V; end if;

when "11" =>AN<="11111110";


if selOP=x"5" then segments <= A; --andV
elsif selOP=x"6" then segments <= O; --orV
elsif selOP=x"7" then segments <= X; --xorV
elsif selOP=x"8" then segments <= N; --notV
elsif selOP=x"1" or selOP=x"2" or selOP=x"3" or selOP=x"4"
or selOP =x"A" or selOP=x"B"then

case(SIGNO) is
WHEN x"0" => segments <= "00000011"; --0

15
WHEN x"1" => segments <= "10011111"; --1
WHEN x"2" => segments <= "00100101"; --2
WHEN x"3" => segments <= "00001101"; --3
WHEN x"4" => segments <= "10011001"; --4
WHEN x"5" => segments <= "01001001"; --5
WHEN x"6" => segments <= "01000001"; --6
WHEN x"7" => segments <= "00011111"; --7
WHEN x"8" => segments <= "00000001"; --8
WHEN x"9" => segments <= "00001001"; --9
WHEN x"F" => segments <= "11111101"; --signo
WHEN OTHERS => segments <= "11111111"; --apagado
end case; --signo
else segments<=V; end if;

when others =>AN<="11111111";


if selOP=x"5" then segments <= V; --andV
elsif selOP=x"6" then segments <= V; --orV
elsif selOP=x"7" then segments <= V; --xorV
elsif selOP=x"8" then segments <= V; --notV
elsif selOP=x"1" or selOP=x"2" or selOP=x"3" or selOP=x"4"
or selOP =x"A" or selOP=x"B" then

case(SIGNO) is
WHEN x"0" => segments <= "00000011"; --0
WHEN x"1" => segments <= "10011111"; --1
WHEN x"2" => segments <= "00100101"; --2
WHEN x"3" => segments <= "00001101"; --3
WHEN x"4" => segments <= "10011001"; --4
WHEN x"5" => segments <= "01001001"; --5
WHEN x"6" => segments <= "01000001"; --6
WHEN x"7" => segments <= "00011111"; --7
WHEN x"8" => segments <= "00000001"; --8
WHEN x"9" => segments <= "00001001"; --9
WHEN x"F" => segments <= "11111101"; --signo
WHEN OTHERS => segments <= "11111111"; --apagado
end case;
else segments<=V; end if;
end case;
end if;
end process; --Fin de proceso de displays
DISPLAY<=segments;
end Behavioral; --Fin de la arquitectura

• 5to componente:
En este se codifica los divisores de frecuencia: de 400 Hz para la señal de barrido de los
displays.
----------------------------------------------------------------------
--MEXILOGICS
--DIVISOR DE 2.5ms
----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

16
use IEEE.STD_LOGIC_unsigned.ALL;
use IEEE.STD_LOGIC_arith.ALL;

--Declaracin de entidad
entity DIV_CLK is
port(
clk: in std_logic; --reloj de 50MHz
SAL_400Hz: inout std_logic --salida 2.5ms
);
end DIV_CLK;
----------------------------------------------------------------------
--Declaracin de la arquitectura
architecture Behavioral of DIV_CLK is
--Declaracin de seales de divisores
signal conta_1250us : integer range 1 to 62_500 := 1; --pulso de 1250
us@400Hz (0.25ms)

begin
--Divisor 2.5ms = 400Hz
--Divisor nodos
process(clk) begin
if rising_edge(clk) then
if(conta_1250us = 62_500) then --cuenta 1250us (50MHz = 62500)
SAL_400Hz <= not(SAL_400Hz); --Genera un barrido de 2.5ms
conta_1250us <= 1;

else conta_1250us <= conta_1250us + 1;


end if;
end if;
end process; --Fin del proceso divisor de nodos
----------------------------------------------------------------------
--fin de la arquitectura
end Behavioral;

• Y el archivo de asignación a los puertos de expansión de la tarjeta (.ucf) es:


//MEXILOGICS
//Archivo de restricciones de usuario (UCF)//

//DISPLAYS
net "DISPLAY(7)" LOC="K13";//A
net "DISPLAY(6)" LOC="L15";//B
net "DISPLAY(5)" LOC="M15";//C
net "DISPLAY(4)" LOC="P15";//D
net "DISPLAY(3)" LOC="P14";//E
net "DISPLAY(2)" LOC="K15";//F
net "DISPLAY(1)" LOC="L14";//G
net "DISPLAY(0)" LOC="N15";//P

//NODOS
net "AN(7)" LOC="K12";//DP8
net "AN(6)" LOC="J13";//DP7
net "AN(5)" LOC="K11";//DP6
net "AN(4)" LOC="H13";//DP5

17
net "AN(3)" LOC="G13";//DP4
net "AN(2)" LOC="H12";//DP3
net "AN(1)" LOC="F13";//DP2
net "AN(0)" LOC="G12";//DP1

//FILAS del teclado matricial 4X4


net "FILAS(3)" LOC="B13";
net "FILAS(2)" LOC="B15";
net "FILAS(1)" LOC="D15";
net "FILAS(0)" LOC="F15";

//COLUMNAS DEL TECLADO MATRICIAL 4X4


net "COLUMNAS(3)" LOC = "A12";
net "COLUMNAS(2)" LOC = "B14";
net "COLUMNAS(1)" LOC = "C15";
net "COLUMNAS(0)" LOC = "E15";

//CLK RELOJ 50MHz


net "clk" LOC = "E7";

//SALIDAS HACIA LOS LEDS TESTIGOS


net "LEDS(7)" loc = "L2" ; # LD0
net "LEDS(6)" loc = "P1" ; # LD1
net "LEDS(5)" loc = "R5" ; # LD2
net "LEDS(4)" loc = "N8" ; # LD3
net "LEDS(3)" loc = "R10" ; # LD4
net "LEDS(2)" loc = "M3" ; # LD5
net "LEDS(1)" loc = "M5"; # LD6
net "LEDS(0)" loc = "N9"; # LD6

Funcionamiento de la ALU en la FPGA


Para mostrar el correcto funcionamiento de nuestro circuito, elegimos dos números a los
cuales les realizamos las distintas operaciones algebraicas. Estos números fueron el 4 (0100)
y el 9 (1001).
Recordemos que para nuestro circuito es necesario ingresar estos valores en formato binario
necesariamente de 4 bits, esto lo hacemos con las teclas “0” y “1” del teclado.
Inmediatamente después de rellenar los cuatro bits con el primer valor procedemos a rellenar
los siguientes cuatro bits con el segundo valor. Es cierto que en términos de funcionalidad
no es lo más adecuado, así que tendremos muy en cuenta, en siguientes prácticas, el sustituir
el sistema binario por el decimal, de esta forma el alcance de nuestro circuito será mayor,
pues más personas podrán utilizarlo debido a la sencillez del sistema decimal.
A continuación, mostramos gráficamente la representación de cada tecla (ver figura 5).

18
Figura 5.- Operaciones asignadas a las teclas

Para empezar, les asignamos el operador suma a los números previamente mencionados;
por lo que: 4 + 9 = 13

Figura 6.- Resultado operador suma

19
Al ver que el resultado es correcto con el operador suma, seguimos con el operador resta:
4 - 9 = -5

Figura 7.- Resultado operador resta

Procedemos con la demostración de la multiplicación; para esto: 4 * 9 = 36

Figura 8.- Resultado operador multiplicación

20
Ahora para la división: 4 / 9 = 0.444

Figura 9.- Resultado operador división

Una vez comprobados los resultados de los operadores algebraicos, continuamos con las
compuertas lógicas. Aquí solo tiene que mostrarse en el display que tipo de compuerta lógica
estamos eligiendo. Para que el usuario verifique que los resultados de las operaciones lógicas
son correctos, hay que recordar que ingresamos los números de 4 bits en binario, por lo que
los leds indicadores de la FPGA realizan esta operación bit a bit de cada número, es decir, el
más significativo del primer operando con el más significativo del segundo operando y así
sucesivamente. Recordando que el primer operando es 4 (en binario 0100) y el segundo 9 (en
binario 1001). Los leds indicadores usados fueron los que están encima de los switches
debajo de los displays de 7 segmentos. El más significativo se ubica más a la izquierda y el
menos significativo más a la derecha de estos leds.
Empezamos con el operador AND:

Figura 10.- Resultado operador


AND

21
Para el operador OR.

Figura 11.- Resultado operador OR

Para el operador XOR.

Figura 12.- Resultado operador XOR

22
Finalmente, el operador NOT.

Figura 13.- Resultado operador NOT

Conclusiones
Álvarez Gómez Julio Cesar: Con el control de cada pin digital es posible realizar
operaciones por registro con las bases numéricas propios de los dispositivos electrónicos. Sin
embargo, es posible traducir esto a nuestros términos a través de los lenguajes de
programación de alto nivel cuyo objetivo es el de simplificar el entendimiento de todas las
instrucciones que pretendemos utilizar.
Al ser leídas somos capaces de entender o al menos interpretar la secuencia de nuestro
programa sin necesidad de tener un aprendizaje profundo de ellas. Con el uso de datos
numéricos en binario y de condicionales, se le instruyó a la FPGA a través de un programa
el uso de operaciones aritméticas con resultado leíble para el humano.
Sin embargo, el procedimiento no ha sido tan intuitivo como parece por la diferencia de bases
numéricas entre máquinas y humanos, pues para lograr una calculadora científica (por
ejemplo) es necesario implementar numerosas líneas de código; diferente a la ‘ALU’ que
tiene un funcionamiento más bien adaptado a los dieciséis botones de nuestro teclado matriz.
Galván Escobar Adrián Raúl: Para elaborar una ALU es indispensable tener buen
conocimiento de la lógica que involucra el manejo de los operadores lógicos, la organización
del código y separación por módulos o componentes, así como de los distintos circuitos
combinacionales para su codificación, pues entre mayores sean los números que se desean
obtener sus operadores, mayor serán los recursos que empleara una FPGA para su
implementación. Al hacer uso del teclado matricial 4x4 comprendí la importancia de las
señales de barrido, ya que por medio de esta nos ahorramos estar conectando hardware
adicional, para este caso, solo fueron necesarias 8 resistencias para los conectores del teclado,

23
en lugar de 16 si hubiéramos usado dispositivos de entrada de datos simples, como switches
o push-buttons.
Gracias al desarrollo de esta práctica comprendí la importancia de los circuitos
combinacionales para una aplicación en la vida cotidiana (selección de operaciones para una
ALU, una calculadora) De igual manera comprendí que para el diseño de estos circuitos es
de vital importancia tomar en cuenta para que clase de usuarios buscamos satisfacer una
necesidad, pues para el caso de nuestra ALU, esta presenta ciertas limitaciones, como lo es
que el usuario tiene que conocer la codificación de los números 0 al 15 en binario para poder
ingresar estos datos a través del teclado matricial, lo cual no hace nuestra ALU tan intuitiva
para usuarios que no poseen un conocimiento determinado del sistema de numeración
binario.
Mata Prieto Varush: Es fundamental para el diseñador el conocer cómo funcionan los
circuitos combinacionales, así como dividir por módulos el programa principal que se quiere
llevar a la parte física ya que, de esta forma, se organizan mejor los datos y permite identificar
errores fácilmente. De igual manera, los circuitos combinacionales permiten hacer
estructuras que llevan un orden establecido al no cambiar su salida a menos que se le ingrese
la combinación que el programador haya diseñado, esto con el fin de mantener una función
intuitiva para el usuario.
Gracias a esta práctica aprendí la importancia de hacer los pasos para los circuitos
combinacionales de forma que la mayor parte de los usuarios sean capaces de utilizar el
sistema sin el mayor problema. También aprendí el uso del teclado matricial 4x4 y la forma
de interpretar la tecla presionada.
Varela Alpízar Benjamín: La implementación de los circuitos combinacionales para una
ALU de 4 bits mediante el uso del lenguaje VHDL fue exitosa. Esta ALU fue capaz de
realizar operaciones aritméticas básicas en números de 4 bits, incluyendo sumas, restas,
AND, OR, NOT y XOR.
El uso de VHDL facilito todo el proceso de diseño ya que permitió una descripción precisa
y detallada de los circuitos combinacionales. Además de que las herramientas de simulación
de dicho lenguaje permitieron probar la funcionalidad de la ALU antes de su implementación
en el hardware

Referencias bibliográficas:
[1] Jaramillo Gómez, Juan Antonio; Salmerón Guzmán, Mirna y El Filali, Brahim. (2017, 1 de
noviembre). Método de conversión de binario a BCD con VHDL. Boletín UPIITA.
https://www.boletin.upiita.ipn.mx/index.php/ciencia/735-cyt-numero-63/1434-metodo-de-
conversion-de-binario-a-bcd-con-vhdl

[2] MADE. (s.f.). Teclado Matricial 4x4. Mecatrónica, Automatización y Diseño


Electrónico. https://electronicamade.com/teclado-matricial-4x4/

24
[3] Jaramillo Gómez, Juan Antonio. (2023). Sumador-Restador-Multiplicador en VHDL con
diseño de alto nivel [Archivo PDF].
[4] Jaramillo Gómez, Jun Antonio. (2023). Operaciones Lógicas en VHDL con diseño de
alto nivel [Archivo PDF].
[5] INTESC. (2021, 30 julio). Librería Teclado Matricial. https://intesc.mx/libreria-teclado-
matricial/
[6] ARROW. (s.f.). ALUs. https://www.arrow.com/es-mx/categories/standard-and-specialty-
logic/specialty-logic/alu

25

También podría gustarte