La siguiente entrada
es sobre la constituciĆ³n de unas de las notas esenciales del curos que estamos
en desarrollo para generar insumos que son Ćŗtiles para el proyecto final que
hablaremos en otra entrada en el blog. En este taller el objetivo es
familiarizarse con el desarrollo de interfaces de entrada y salida en VHDL para
la tarjeta Nexys 4.
FUNCIONALIDAD:
El propĆ³sito es
conectar un teclado matricial 4 X 4 (TM4) al puerto PMOD JA de la tarjeta Nexys 4. Cada
vez que se presione una tecla, su valor se mostrara en el display de siete
segmentos (D7S) numero 0, el ultimo
visto desde la derecha del conjunto de display.
A
continuaciĆ³n le mostraremos el funcionamiento del teclado matricial 4 X 4 que estĆ” constituido por una matriz de
pulsadores dispuestos en filas (A, B, C, D) y columnas (1, 2, 3, 4), con la
intensiĆ³n de reducir el nĆŗmero de pines necesarios para su conexiĆ³n.
TECLADO MATRICIAL
Su funcionamiento es
muy sencillo, cuando se presione una tecla, se conectan internamente la fila y
columna correspondiente; por ejemplo, al presionar la tecla “7” se conectan la
fila c y la columna 1, si no hay ninguna tecla presionada, las filas estarƔn
desconectadas de las columnas.
Cuando se presiona una tecla de corriente puede
fluir a travƩs del switch y el voltaje de los pines conectados a las filas del
teclado (5 V o nivel alto) aparece tambiƩn ahora uno de los pines RB0 a RB3
segĆŗn la columna en la que se encuentre la tecla oprimida. La siguiente imagen
ilustra lo que sucede al oprimir una tecla: al oprimir el botĆ³n 6 provocamos un
cambio en el pin RB2 que ahora recibe un 1 lĆ³gico o estado alto. Sabes entonces
que se ha pulsado un botĆ³n en la segunda columna y se muestra como un nivel
lĆ³gico alto aparece en los bits menos significativos del puerto B,
especĆficamente en RB2.
Diagrama de flujos del teclado matricial
Display 7 segmentos
Es un componente que se
utiliza para la representaciĆ³n de nĆŗmeros o letras en muchos dispositivos
electrĆ³nicos. La decodificaciĆ³n que se utiliza para pasar a un nĆŗmero de BCD a
7 segmentos tiene la siguiente combinaciĆ³n que va hacer ilustrada a
continuaciĆ³n:
A continuaciĆ³n les
mostramos el diagrama de bloques que representa la conexiĆ³n del teclado
matricial al display de 7 segmentos.
Le vamos a dejar la
pƔgina donde pueden entrar y leer todo sobre la FPGA Nexys 4 Artix
https://sites.google.com/site/logicaprogramable/calculadoras/fpga/nexys-4-artix-7-fpga-board
y asĆ familiarizarse mĆ”s a fondo sobre este dispositivo.
CODIGO EN VHDL PARA
IMPLEMENTAR EL PROBLEMA PLANTEADO:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL
entity teclado is
port (
ledfila,
ledcol : out unsigned(3 downto 0);
clk : in std_logic;
reset : in std_logic;
fila : in unsigned(3 downto 0);
col : out unsigned(2 downto 0);
display
: out std_logic_vector(7 downto 0);
seg7 : out std_logic_vector(6 downto 0)
);
end teclado;
En esta primera parte
del cĆ³digo se colocan las variables que son de salida o que son de entrada que
son el reloj (CLK), reset, fila, columna (col), display es el que me define que
display vamos a usar y 7 segmentos
(seg7) es el que dice el nĆŗmero a mostrar.
architecture teclado of
teclado is
type estado is (reposo, inicio, cuenta,
rotacion, deteccionFilaCol, deteccionTecla, mostrar);
signal estadoActual, estadoSiguiente :
estado;
signal scol
: unsigned(2 downto 0);
signal
scol4 : unsigned(3 downto 0);
signal nfila
: unsigned(3 downto 0);
signal tecla
: unsigned(3 downto 0);
signal multi
: unsigned(7 downto 0);
signal
contador : unsigned(21 downto 0);
constant U0L
: unsigned(21 downto 0) := to_unsigned(0,22)
constant U0
: unsigned(3 downto 0) := to_unsigned(0,4);
constant
U11: unsigned (3 downto 0) := to_unsigned (11,4);
constant U1
: unsigned(3 downto 0) := to_unsigned(1,4);
constant U2
: unsigned(3 downto 0) := to_unsigned(2,4);
constant U3
: unsigned(3 downto 0) := to_unsigned(3,4);
constant U4
: unsigned(3 downto 0) := to_unsigned(4,4);
constant U5
: unsigned(3 downto 0) := to_unsigned(5,4);
constant U6
: unsigned(3 downto 0) := to_unsigned(6,4);
constant U7
: unsigned(3 downto 0) := to_unsigned(7,4);
constant U8
: unsigned(3 downto 0) := to_unsigned(8,4);
constant U9
: unsigned(3 downto 0) := to_unsigned(9,4);
constant
U12: unsigned(3 downto 0) := to_unsigned (12,4);
constant
U10: unsigned (3 downto 0) := to_unsigned (10,4);
En esta parte del
programa ya viene la arquitectura, se habla sobre todos los estados que vienen
siendo reposo, inicio, cuenta, rotaciĆ³n, decodificaciĆ³n fila-columna, detenciĆ³n
tecla y mostrar. TambiƩn se encuentran las seƱales como seƱal de estado actual
y como seƱal de estado siguientes, donde se indican cada seƱal dependiendo de
lo que se quiera realizar, tenga en cuenta que en VHDL siempre se tiene que
manejar las variables del mismo tamaƱo.
begin
ledfila <= fila;
ledcol <= '1' & scol;
display
<= "11110110";
col <= scol;
multi <= U3*nfila;
-- camino de datos (datapath)
process(clk,
estadoActual,tecla,scol,fila)
begin
if
(clk'event and clk = '1') then
case
estadoActual is
when reposo =>
scol
<= "111"
contador <= U0L;
when inicio =>
scol
<= "011";
when cuenta =>
contador <= contador+1;
when rotacion =>
scol <= scol(1 downto 0) & scol(2);
contador <= U0L;
when deteccionFilaCol =>
case fila is
when "0111" => nfila <= U0;
when "1011" => nfila
<= U1;
when "1101" => nfila <= U2;
when "1110" => nfila <= U3;
when others => nfila <= U10;
end case;
case scol is
when "011" => scol4 <= U0;
when "101" => scol4 <=
U1;
when "110" => scol4 <= U2;
when others => scol4 <= U0;
end case;
when deteccionTecla =>
if fila(3)='0' then
tecla <= U0;
else
tecla <= scol4 + U1 + multi(3 downto 0);
end if;
when mostrar =>
case tecla is
when U11 => seg7 <= "1111001"; -- 1 working
when U8 => seg7 <= "0011001"; -- 4 working
when U5 => seg7 <= "0111000"; -- 7 working
when U12 => seg7 <=
"0110000"; -- 3
when U7 => seg7 <= "0010010"; -- 5 working
when U4 => seg7 <= "0000000"; -- 8 working
When U10 => seg7 <= "0100100"; -- 2 working
--When U3 => seg7 <=
"1110000"; -- no se
when U9 => seg7 <= "0000010"; -- 6 working
when U6 => seg7 <= "0011000"; -- 9 working
when others => seg7 <= "1000000"; -- *, #
end case;
end
case;
end if;
end process;
Seguimos con los
caminos de datos que es lo que se va a realizar dentro de un estado, es decir
que si en el estado de rotaciĆ³n se rota algĆŗn nĆŗmero eso es lo que se va a
operar en el estado.
-- registro de estado
process(clk, reset)
begin
if
(reset = '1') then
estadoActual <= reposo;
elsif
(clk'event and clk = '1') then
estadoActual
<= estadoSiguiente;
end if;
end process;
process (estadoActual,fila,contador) is
begin
Continuamos con el
registro de estado, en este estado lo que hace es guardar la variable y dƔndole
funcionalidad al reloj, es decir que de un esta actual cambia al siguiente y
que si se hace un reset vuelva a reposo
case estadoActual is
when reposo => estadoSiguiente <=
inicio;
when inicio => estadoSiguiente <=
cuenta;
when cuenta =>
if contador = "1111111111111111111111"
then
estadoSiguiente <= rotacion;
else
estadoSiguiente <= cuenta;
end if;
when rotacion =>
if (fila = "1111") then
estadoSiguiente <= cuenta;
else
estadoSiguiente <=
deteccionFilaCol;
end if;
when deteccionFilaCol =>
estadoSiguiente <=
deteccionTecla;
when deteccionTecla =>
estadoSiguiente <= mostrar;
when mostrar =>
estadoSiguiente <= inicio;
end
case;
end process;
end teclado;
Por Ćŗltimo se encuentra
el diagrama de estados donde se encuentra un process, donde son los procesos
que estƔn dentro de procesos que influirƔn sobre el mismo programa a
realizar
CONSTRAINT
set_property LOC E3 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -add -name sys_clk_pin -period 10.00 -waveform
{0 5} [get_ports clk]
# Mapear RESET a BTND
set_property LOC V10 [get_ports reset]
set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property PACKAGE_PIN B13 [get_ports {col[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[0]}]
set_property PACKAGE_PIN F14 [get_ports {col[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[1]}]
set_property PACKAGE_PIN D17 [get_ports {col[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[2]}]
set_property PACKAGE_PIN G13 [get_ports {fila[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fila[0]}]
set_property PACKAGE_PIN C17 [get_ports {fila[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fila[1]}]
set_property PACKAGE_PIN D18 [get_ports {fila[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fila[2]}]
set_property PACKAGE_PIN E18 [get_ports {fila[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fila[3]}]
set_property PACKAGE_PIN L3 [get_ports {seg7[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[0]}]
set_property PACKAGE_PIN N1 [get_ports {seg7[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[1]}]
set_property PACKAGE_PIN L5 [get_ports {seg7[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[2]}]
#set_property SEVERITY {warning} [get_drc_checks
NSTD-1]
#set_property SEVERITY {warning} [get_drc_checks
UCIO-1]
set_property PACKAGE_PIN L4 [get_ports {seg7[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[3]}]
set_property PACKAGE_PIN K3 [get_ports {seg7[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[4]}]
set_property PACKAGE_PIN M2 [get_ports {seg7[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[5]}]
set_property PACKAGE_PIN L6 [get_ports {seg7[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg7[6]}]
set_property PACKAGE_PIN N6 [get_ports {display[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{display[0]}]
set_property PACKAGE_PIN M6 [get_ports {display[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {display[1]}]
set_property PACKAGE_PIN M3 [get_ports {display[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{display[2]}]
set_property PACKAGE_PIN N5 [get_ports {display[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{display[3]}]
set_property PACKAGE_PIN N2 [get_ports {display[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{display[4]}]
set_property PACKAGE_PIN N4 [get_ports {display[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{display[5]}]
set_property PACKAGE_PIN L1 [get_ports {display[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{display[6]}]
set_property PACKAGE_PIN M1 [get_ports {display[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{display[7]}]
set_property PACKAGE_PIN T8 [get_ports {ledcol[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{ledcol[0]}]
set_property PACKAGE_PIN V9 [get_ports {ledcol[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{ledcol[1]}]
set_property PACKAGE_PIN R8 [get_ports {ledcol[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{ledcol[2]}]
set_property PACKAGE_PIN T6 [get_ports {ledcol[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{ledcol[3]}]
set_property PACKAGE_PIN P2 [get_ports {ledfila[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{ledfila[0]}]
set_property PACKAGE_PIN R2 [get_ports {ledfila[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{ledfila[1]}]
set_property PACKAGE_PIN U1 [get_ports {ledfila[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{ledfila[2]}]
set_property PACKAGE_PIN P5 [get_ports {ledfila[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports
{ledfila[3]}]
En el constraint es la
asignaciĆ³n de puerto de la FPGA, asignamos el puerto pmog que por donde
nosotros conectamos el teclado matricial.
A continuaciĆ³n le
ilustraremos la entidad del problema y
tambiƩn el diagrama de estados:
disculpa una pregunta cuando declaras " display : out std_logic_vector(7 downto 0) " , que quieres decir con eso? que salidas seran?
ResponderEliminar