Número y tema del reporte de investigación:
Práctica 2. Contador digital en FPGA.
Nombre de los integrantes del equipo:
Huerta Alvarado Francisco Imanol
Palafox Amador Ángel Osiris
Abraham Daniel Martinez Gracia.
Nombre de la materia:
Dispositivos lógicos programables
Nombre del docente:
Eleazar Pacheco Reyes
Carrera:
Ingeniería Mecatrónica
Grupo:
2MM4
Fecha de elaboración:
Lunes 28 de octubre del 2024
Práctica 2.
Introducción:
El lenguaje de descripción de hardware VHDL, nos ayuda a representar
los circuitos lógicos de una manera más sencilla, por medio de
estructuras de comparación entre otro tipo de sintaxis. Por medio de la
presente práctica se desarrolló un multiplexor de 8 entradas, una
salida, así como un biestable tipo T.
Objetivo:
● En la presente práctica se busca que el alumno recupere
conocimientos previos a la materia de circuitos lógicos.
● En este caso elaborando un multiplexor y un biestable T, con el fin
de incorporar la información de cómo se elabora en VHDL, su
lógica detrás de ella y ver su comportamiento en el Test Bench y
en algunos casos representarlo de manera física en la placa
Basys3.
Marco teórico:
VHDL: El significado de las siglas VHDL es VHSIC (Very High Speed
Integrated Circuits) Hardware Description Language. Este no es un
lenguaje de programación, es más bien un lenguaje de descripción de
hardware, que permite describir circuitos síncronos y asíncronos. Este
tipo de programa es muy utilizado ya que se puede describir un circuito
de compuertas lógicas, la implementación de mapas de Karnaugh,
tablas de verdad, etc.
Biestable T: Es igual que el biestable J-K, de modo que estas dos
entradas están puenteadas y forman la entrada T, de forma que cuando
T toma el valor 0 la salida Qt+1=Qt, es decir no cambia.
Cuando la entrada T toma el valor 1, la salida cambia de estado.
En el caso de que se mantenga la entrada T permanente igual a 1, la
báscula T se comporta como un divisor de frecuencia de la señal de
reloj entre dos.
Multiplexor: Conocido como MUX o MPX es un dispositivo electrónico
que sirve para convertir datos de diferentes señales a una sola salida.
Es decir que, pueden entrar diferentes tipos de datos a través de sus
entradas, pero solo tiene una salida. Puede ser utilizada en diferentes
señales ya sea digitales o analógicas.
Tabla de verdad: Es una herramienta que con ayuda de ella, se dan a
conocer las condiciones necesarias para deducir si un enunciado es
verdadero, en el caso de circuitos lógicos, es un método gráfico en cual
se representan los posibles valores de verdad de una posición
compuesta.
Basys3: Es una placa de desarrollo de FPGA, por sus siglas en inglés
(Field Programmable Gate Array), la cual se utiliza para la programación
e implementación de circuitos digitales, esta como se mencionó
anteriormente está basada en la FPGA Artix-7
Desarrollo
Problema 1. Diseñar un circuito multiplexor de 1 bit con 8 entradas.
Implementar el sistema en Basys3.
Para ello se desarrolló una tabla de verdad, donde se contemplan los
posibles casos del multiplexor, tomando en cuenta que usa n=3, por lo
que son 8 entradas E0-E7, 3 condicionales C0-C2 y un bit de Enable.
Como se muestra enseguida.
El código en VHDL, es el siguiente:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity DO21 is
Port ( en : in STD_LOGIC;
E : in STD_LOGIC_VECTOR (7 downto 0);
C : in STD_LOGIC_VECTOR (2 downto 0);
S : out STD_LOGIC_VECTOR (1 downto 0));
end DO21;
architecture Behavioral of DO21 is
begin
process(E,en,C)
begin
if en = '0' then
if C= "000" then
S(1) <= E(0);
S(0) <= NOT E(0);
elsif C= "001" then
S(1) <= E(1);
S(0) <= NOT E(1);
elsif C= "010" then
S(1) <= E(2);
S(0) <= NOT E(2);
elsif C= "011" then
S(1) <= E(3);
S(0) <= NOT E(3);
elsif C= "100" then
S(1) <= E(4);
S(0) <= NOT E(4);
elsif C= "101" then
S(1) <= E(5);
S(0) <= NOT E(5);
elsif C= "110" then
S(1) <= E(6);
S(0) <= NOT E(6);
elsif C= "111" then
S(1) <= E(7);
S(0) <= NOT E(7);
else
S(1) <= '0';
S(0) <= '1';
end if;
else
S(1) <= '0';
S(0) <= '1';
end if;
end process;
end Behavioral;
El código del UCF:
NET "E(7)" LOC = "N3"; # Bank = 3, Signal name = SW7
NET "E(6)" LOC = "E2"; # Bank = 3, Signal name = SW6
NET "E(5)" LOC = "F3"; # Bank = 3, Signal name = SW5
NET "E(4)" LOC = "G3"; # Bank = 2, Signal name = SW4
NET "E(3)" LOC = "B4"; # Bank = 3, Signal name = SW3
NET "E(2)" LOC = "K3"; # Bank = 3, Signal name = SW2
NET "E(1)" LOC = "L3"; # Bank = 3, Signal name = SW1
NET "E(0)" LOC = "P11"; # Bank = 2, Signal name = SW0
NET "C(2)" LOC = "A7"; # Bank = 3, Signal name = SW7
NET "C(1)" LOC = "M4"; # Bank = 3, Signal name = SW6
NET "C(0)" LOC = "C11"; # Bank = 3, Signal name = SW5
NET "EN" LOC = "G12"; # Bank = 3, Signal name = SW5
NET "S(1)" LOC = "M11"; # Bank = 3, Signal name = SW7
NET "S(0)" LOC = "M5"; # Bank = 3, Signal name = SW6
Problema 2. Realizar el programa en VHDL con el funcionamiento del
biestable tipo T.
Se elaboró como es el comportamiento del biestable T que es de la
siguiente forma, con ayuda de los apuntes de circuitos logicos:
Mostrado lo anterior se pensó contar con un auxiliar el cual guarde el
valor Q anterior con el fin de cuando hace el cambio de estado se refleje
al auxiliar y lo pase acabando la secuencia al valor de Q de la salida.
Dicho lo anterior, con un process, if-then-else se hizo la señal de reloj a
nivel alto y que tenga un inicializador es decir un clear (síncrono) a nivel
alto.
Código en VHDL:
ibrary IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity D022VM is
Port ( T : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (1 downto 0);
clk : in STD_LOGIC;
clear : in STD_LOGIC);
end D022VM;
architecture Behavioral of D022VM is
signal aux: STD_LOGIC:='0';
begin
process(clk)
begin
if rising_edge(clk) then
if(clear='1') then
aux<='0';
elsif (T='1') then
aux<= NOT aux;
end if;
end if;
end process;
Q(0)<=aux;
Q(1)<=NOT aux;
end Behavioral;
Código de Test Bench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY D022TB IS
END D022TB;
ARCHITECTURE behavior OF D022TB IS
COMPONENT D022VM
PORT(
T : IN std_logic;
Q : OUT std_logic_vector(1 downto 0);
clk : IN std_logic;
clear : IN std_logic
);
END COMPONENT;
--Inputs
signal T : std_logic := '0';
signal clk : std_logic := '0';
signal clear : std_logic := '0';
--Outputs
signal Q : std_logic_vector(1 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: D022VM PORT MAP (
T => T,
Q => Q,
clk => clk,
clear => clear
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
T<= '1';
wait for clk_period;
T<='0';
wait for clk_period;
T<='1';
wait for clk_period*2;
T<='0';
wait for clk_period*2;
clear<='1';
T<= '1';
wait for clk_period;
T<='0';
wait for clk_period;
T<='1';
wait for clk_period*2;
T<='0';
wait for clk_period*2;
clear<='0';
T<= '1';
wait for clk_period*3;
T<='0';
wait for clk_period*3;
T<='1';
wait for clk_period/2;
T<='0';
wait for clk_period/2;
clear<='1';
T<= '1';
wait for clk_period*3;
T<='0';
wait for clk_period*3;
T<='1';
wait for clk_period/2;
T<='0';
wait for clk_period/2;
clear<='0';
T<= '1';
wait for clk_period;
T<='0';
wait for clk_period*2;
T<='1';
wait for clk_period;
T<='0';
wait for clk_period/2;
clear<='1';
T<= '1';
wait for clk_period;
T<='0';
wait for clk_period*2;
T<='1';
wait for clk_period;
T<='0';
wait for clk_period/2;
clear<='0';
T<= '1';
wait for clk_period*4;
T<='0';
wait for clk_period*2;
T<='1';
wait for clk_period*3;
wait;
end process;
END;
Programa 3: Realizar un contador ascendente y descendente que por
medio de un botón se pueda seleccionar el modo de direccionamiento,
contando de 0 99 o de 99 a 0.
Para ello se realizó un contador ascendente y descendente, el cual por
medio de un botón de reset y un botón que direcciona el conteo, se
contaba desde 0 99, como se muestra enseguida.
Código de VHDL Module:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Contador is
Port (
clk : in STD_LOGIC;
reset : in STD_LOGIC;
btn_up : in STD_LOGIC;
btn_down : in STD_LOGIC;
display : out STD_LOGIC_VECTOR(0 to 7);
anodes : out STD_LOGIC_VECTOR(0 to 3)
);
end Contador;
architecture Behavioral of Contador is
signal count : integer range 0 to 99 := 0;
signal up_down : STD_LOGIC := '1'; -- '1' para ascendente, '0'
para descendente
signal clk_div : integer := 0;
signal decenas : integer := 0;
signal count_en : boolean := false;
-- frequencia
constant clk_freq : integer := 50000000; -- 50 MHz for example
constant freq_div : integer := 1000000; -- 1 Hz for 1 second
constant decenas_div : integer := 10; -- 1 Hz for 1 second
begin
-- Frequency divider process
process(clk, reset)
begin
if reset = '1' then
clk_div <= 0;
count_en <= false;
elsif rising_edge(clk) then
if clk_div < clk_freq / freq_div - 1 then
clk_div <= clk_div + 1;
else
clk_div <= 0;
count_en <= true;
end if;
end if;
end process;
-- contador
process(clk, reset)
begin
if reset = '1' then
count <= 0;
elsif rising_edge(clk) and count_en then
if btn_up = '1' then
up_down <= '1';
elsif btn_down = '1' then
up_down <= '0';
end if;
if up_down = '1' then
if count < 99 then
count <= count + 1;
else
count <= 0;
end if;
elsif up_down = '0' then
if count > 0 then
count <= count - 1;
else
count <= 99;
end if;
end if;
end if;
end process;
-- Display
process(count)
begin
case count is
when 0 => display <= "00000011";
when 1 => display <= "10011111";
when 2 => display <= "00100101";
when 3 => display <= "00001101";
when 4 => display <= "10011001"; --a,b,c,d,e,f,g
when 5 => display <= "01001001";
when 6 => display <= "01000001";
when 7 => display <= "00011111";
when 8 => display <= "00000001";
when 9 => display <= "00011001";
-- Add cases for all numbers up to 99
when others => display <= "11111111";
--when others => decenas <= count / 10;
end case;
end process;
anodes <= "1100";
end Behavioral;
Código UCF:
net btn_up loc = g12;
net btn_down loc = c11;
net reset loc = m4;
net display<0> loc = l14;
net display<1> loc = h12;
net display<2> loc = n14;
net display<3> loc = n11;
net display<4> loc = p12;
net display<5> loc = l13;
net display<6> loc = m12;
net display<7> loc = n13;
net anodes<0> loc = k14;
net anodes<1> loc = m13;
net anodes<2> loc = j12;
net anodes<3> loc = f12;
Código Test Bench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY prac2_bTB IS
END prac2_bTB;
ARCHITECTURE behavior OF prac2_bTB IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT prac2_2
PORT(
t : IN std_logic;
clk : IN std_logic;
q : OUT std_logic;
clear : IN std_logic
);
END COMPONENT;
--Inputs
signal t : std_logic := '0';
signal clk : std_logic := '0';
signal clear : std_logic := '0';
--Outputs
signal q : std_logic;
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: prac2_2 PORT MAP (
t => t,
clk => clk,
q => q,
clear => clear
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
clear <= '1';
wait for clk_period;
clear <= '0';
wait for clk_period;
-- insert stimulus here
t <= '0';
--clear <= '0';
wait for clk_period;
t <= '1';
--clear <= '1';
wait for clk_period*2;
t <= '0';
--clear <= '0';
wait for clk_period;
t <= '1';
--clear <= '1';
wait;
end process;
END;
Resultados
Para el ejercicio 1, se implementó en la Basys3 el código mostrado con
anterioridad y demostrando cómo funciona de manera correcta y como
se pidió desde un principio, en el problema propuesto.
Para el ejercicio 2, se realizó una simulación del Test Bench, donde se
da a conocer el mapa de estado, acorde a los casos propuestos.
Para el ejercicio 3, se implemento de manera física en la basys 3 y por
medio de los display de 7 segmentos se mostraron un display para las
unidades contando de 0 a 9 y otro las centenas contando de 0 a 9 como
se muestra enseguida.
Conclusiones
Ángel Osiris Palafox Amador: En la presente práctica se elaboró
circuitos vistos en la materia de circuitos eléctricos, sin embargo desde
un principio no sabia de que se trataba de dichos circuitos hasta que
con el pasar del tiempo y retomar mis notas me di cuenta de cómo se
elaboraban como en el caso del multiplexor que es controlado por un
enable que hace que se encienda el circuito, por condiciones para
determinar la salida por medio de las entradas y por otra parte el
biestable T que varía dependiendo de la señal anterior o negado.
Francisco Imanol Huerta Alvarado:
Por medio de la presente práctica se realizaron varias descripciones de
hardware, como lo fue un demultiplexor de 8 entradas una salida, donde
se puede observar que el botón de enable determina si es 0 o 1 la salida
y por medio de las condicionales, se determina si la salida es alguna de
las entradas, de igual manera también se desarrolló un biestable T que
nos indica el estadio anterior o el negado del mismo, así como un
contador ascendente o descendente, donde se presentaron algunas
dificultades para el divisor de frecuencias, ya que este no se puede
simular de manera correcta en el Test Bench, a su vez se concluye que
el uso de la programación VHDL es de gran ayuda ya que nos permite
desarrollar una lógica de programación más alta asi como desarrollar
proyectos mejores.
Abraham Daniel Martinez Garcia:
En esta práctica se logró implementar un contador de 0 a 99 en la FPGA
Basys 3 utilizando VHDL. La práctica permitió integrar los
conocimientos sobre circuitos digitales, manejo de displays de 7
segmentos y la programación en VHDL. Se verificó que el diseño
cumple con las especificaciones de contar de 0 a 99 y que responde
correctamente a los botones de control, que permiten reiniciar la cuenta
y cambiar la dirección (ascendente o descendente).
La experiencia con VHDL y la FPGA permitió comprender mejor el flujo
de diseño digital, desde la descripción del hardware hasta la simulación
y síntesis en una FPGA real. También se destacaron aspectos
importantes, como la sincronización de los dígitos del display y el
manejo de los botones de entrada. Como resultado, se concluye que la
Basys 3 es una plataforma versátil para prototipos de circuitos digitales
y que el lenguaje VHDL ofrece una herramienta poderosa para la
especificación y control de circuitos en tiempo real.
Este proyecto refuerza el conocimiento sobre diseño digital y abre la
puerta a proyectos más complejos y detallados.
Referencias:
Mecafenix, I. (2023, 22 noviembre). Que es un Demultiplexor, como funciona y
que tipos existen. Ingeniería Mecafenix.
https://www.ingmecafenix.com/electronica/componentes/que-es-un-dem
ultiplexor/
Mecafenix, I. (2023a, noviembre 29). Que es un multiplexor, como funciona y
que tipos existen. Ingeniería Mecafenix.
https://www.ingmecafenix.com/electronica/componentes/multiplexor/#Q
ue-es
Cec. (s. f.). 1.4. Biestable T (Trigger=disparo) | Tema 4: Circuitos secuenciales.
https://www.iesnestoralmendros.es/departam/tecnologia/2bach_ti2/libro
digital/Unidad%202%20Electronica%20Digital/Tema%204/14_biestable_t
_triggerdisparo.html