Professional Documents
Culture Documents
Este CPLD pertenece a la familia de MAX II de Altera, cuenta con 240 elementos lógicos
(LEs) y se pueden llegar a utilizar hasta 80 pines de entrada/salida. Tiene un retardo típico
de 4.7ns de pin a pin en el peor de los casos, pudiendo llegar a trabajar a la frecuencia de
300MHz.
Los voltajes de alimentación del dispositivo (core) puede ir de 3.3v /2.5v o 1.8v. Los pines
de entrada/salida (I/O) soporta una variedad de voltajes: 3.3v, 2.5v, 1.8v y 1.5v
En resumen, este CPLD de Altera es de bajo costo y bajo consumo de energía dando
soluciones programables tales como circuitos digitales de baja a mediana complejidad,
puentes de buses, puertos de expansión de I/O, circuitos controladores de secuencias, etc.
Ejemplo No1: Activar los leds 6,4,2,0 y apagar los leds 7,5,3,1, también apagar el
buzzer(bell).
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity LEDS is
port(Y: out std_logic_vector(7 downto 0);
bell: out std_logic);
end LEDS;
Y <= "10101010";
bell <= '1';
end SOLUCION;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity LEDS is
port(SW: in std_logic_vector(7 downto 0);
Y: out std_logic_vector(7 downto 0);
bell: out std_logic);
end LEDS;
architecture SOLUCION of LEDS is
begin
Y <= SW;
bell <= '1';
end SOLUCION;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity LEDS is
port(BUTTONS: in std_logic_vector(4 downto 0);
Y: out std_logic_vector(4 downto 0);
bell: out std_logic);
end LEDS;
architecture SOLUCION of LEDS is
begin
end SOLUCION;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity LEDS is
port(FILA: out std_logic_vector(7 downto 0);
COLUMNA: out std_logic_vector(7 downto 0);
CLK: in std_logic;
bell: out std_logic);
end LEDS;
process(clk)
begin
if rising_edge(clk) then
CUENTA <= CUENTA+1;
if CUENTA = 250000 then
CUENTA <= (others=>'0');
ESTADO <= ESTADO+1;
end if;
end if;
end process;
process(ESTADO)
begin
case ESTADO is
when "000"=> FILA <= "11111110"; COLUMNA <= "11111110";
when "001"=> FILA <= "11111101"; COLUMNA <= "11111101";
when "010"=> FILA <= "11111011"; COLUMNA <= "11111011";
when "011"=> FILA <= "11110111"; COLUMNA <= "11110111";
when "100"=> FILA <= "11101111"; COLUMNA <= "11101111";
when "101"=> FILA <= "11011111"; COLUMNA <= "11011111";
when "110"=> FILA <= "10111111"; COLUMNA <= "10111111";
when others=> FILA <= "01111111"; COLUMNA <= "01111111";
end case;
end process;
end SOLUCION;
En primer lugar implementamos los puentes en el CPLD. La señal ENA_D del gráfico es el
habilitador del display que tiene el módulo. Esta señal será reemplazada por la señal
ENABLE_DIS de 8 bits, donde se habilitará sólo al display 1 y los otros estarán apagados.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity PUENTES1 is
port( reset_in,updn_in,enable_in: in std_logic;
reset_out,updn_out,enable_out: out std_logic;
display_out: out std_logic_vector(7 downto 0);
display_in: in std_logic_vector(7 downto 0);
enable_dis: out std_ulogic_vector(7 downto 0);
bell: out std_logic);
end PUENTES1;
architecture SOLUCION of PUENTES1 is
begin
bell <= '1';
reset_out <= reset_in;
updn_out <= updn_in;
enable_out <= enable_in;
display_out <= display_in;
enable_dis <= "11111110";
end SOLUCION;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity CONTADOR is
port(reset, enable, updn, clk: in std_logic;
display: out std_logic_vector(7 downto 0));
end CONTADOR;
process(clk)
begin
if rising_edge(clk) then
CUENTA <= CUENTA+1;
if CUENTA = 25000000 then
X <= not X;
CUENTA <= (others=>'0');
end if;
end if;
end process;
--pgfedcba
with CUENTA_BIN select display <= "11000000" when "0000",
"11111001" when "0001",
"10100100" when "0010",
"10110000" when "0011",
"10011001" when "0100",
"10010010" when "0101",
"10000010" when "0110",
"11111000" when "0111",
"10000000" when "1000",
"10011000" when "1001",
"10001000" when "1010",
"10000011" when "1011",
"11000110" when "1100",
"10100001" when "1101",
"10000110" when "1110",
"10001110" when others;
end SOLUCION;
● Horas.
● Minutos
● Segundos
● Centésimas de segundos
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity DISPLAY8 is
port(DATA: in std_logic_vector(3 downto 0);
IN_DEC3A8: in std_logic_vector(2 downto 0);
DISPLAY: out std_logic_vector(7 downto 0);
ENABLE_DISP: out std_logic_vector(7 downto 0);
bell: out std_logic);
end DISPLAY8;
end SOLUCION;
Ahora procederemos a implementar el código VHDL del reloj, así como los temporizadores
y el multiplexor, estos circuitos se implEmentaran en el FPGA.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity RELOJ is
port(clk: in std_logic;
data_out: out std_logic_vector(3 downto 0);
out_deco3a8: buffer std_logic_vector(2 downto 0));
end RELOJ;
process(X)
begin
if rising_edge(X) then
UC <= UC+1;
if UC = 9 then
DC <= DC+1;
UC <= "0000";
if DC=9 then
US <= US+1;
DC <= "0000";
if US=9 then
DS <= DS+1;
US <= "0000";
if DS = 5 then
UM <= UM+1;
DS <= "0000";
if UM = 9 then
DM <= DM+1;
UM <= "0000";
if DM = 5 then
UH <= UH+1;
DM <= "0000";
if UH = 9 then
DH <= DH+1;
UH <= "0000";
elsif UH = 3 then
if (DH = 2) then
DH <= "0000";
UH <= "0000";
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end process;
end SOLUCION;
Además, el CPLD realizará la decodificación a 7 segmentos del valor binario recibido por el
puerto DATA y será mostrado en el puerto DISPLAY para mostrar el número codificado en
el display a 7 segmento habilitado.
Finalmente, tendrá implementado cuatro puentes para dejar pasar las señales de los 4
botones: RESET, START_STOP, MIN y SEG al FPGA.
Además, debemos implementar 02 contadores (uno para los minutos y otro para los
segundos) que en un momento funcionen de forma independiente cada uno con su propio
reloj, uno para contar los pulsos que provienen del botón de minutos (MIN) y el otro para
contar los pulsos que provienen del botón de segundos (SEG). Pero cuando se inicie el
conteo, ambos contadores deben trabajar de forma unida realizando un conteo descendente
desde el valor en minutos y segundos ingresado previamente..
También debemos implementar una máquina de estado para controlar el funcionamiento del
cronómetro, desde que se pulsa RESET, luego cuando se realiza el incremento de los
minutos y segundos, y finalmente controlar el arranque (START) y parada del conteo
descendente (STOP).
También debemos implementar un circuito para atenuar y/o eliminar los posibles rebotes o
señales aleatorias que se generen de los botones MIN y SEG.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity VISOR_CPLD is
port( RESET_IN,START_STOP_IN,MIN_IN,SEG_IN: in std_logic;
DATA: in std_logic_vector(3 downto 0);
IN_DEC3A8: in std_logic_vector(2 downto 0);
end SOLUCION;
Hay que tener en cuenta la ocurrencia de los rebotes cuando se presione los pulsadores.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity DIV_1HZ is
port(clk: in std_logic;
X: buffer std_logic);
end DIV_1HZ;
process (clk)
begin
if rising_edge(clk) then
CUENTA <= CUENTA+1;
if CUENTA=25000000 then
CUENTA<=(others=>'0');
X <= not X;
end if;
end if;
end process;
end SOLUCION;
Donde:
➔ CLK: es la señal de 1Hz.
➔ Y es una señal para iniciar (START) o detener (STOP) la cuenta del
cronómetro (cuando Z = 1).
➔ SEG es la señal que proviene de un pulsador y servirá como entrada de reloj
para los segundos (cuando Z = 0)
➔ MIN es la señal que proviene de un pulsador y servirá como entrada de reloj
para los minutos (cuando Z = 0)
➔ US y DS son señales que contienen la cuenta en BCD de los segundos
(00-59).
➔ UM y DM son señales que contienen la cuenta en BCD de los minutos
(00-59).
➔ CLK3 es la señal de reloj que incrementará los minutos cuando haya ocurrido
un desbordamiento en el contador de los segundos (cuando Z=1).
➔ RESET es la señal que fuerza a que los contadores de minutos y segundos
inicien en 00:00
➔ X es una señal de control de cuenta ascendente (cuando X=0) o
descendente (cuando X=1),.
library ieee;
use ieee.std_logic_1164.all;
entity contadores_MS is
port(clk,min,seg,x,y,z,reset: in std_logic;
US,DS,UM,DM: buffer std_logic_vector(3 downto
0));
end contadores_MS;
process(CLK2,reset)
begin
if reset='1' then
US <= "0000";
DS <= "0000";
elsif rising_edge(CLK2) then
if x='0' then
US <= US+1;
if US = 9 then
US <= "0000";
DS <= DS+1;
if DS=5 then
DS <= "0000";
end if;
end if;
else
US <= US-1;
if US = 0 then
US <= "1001";
DS <= DS - 1;
if DS=0 then
DS <= "0101";
clk3 <='1';
else
clk3 <='0';
end if;
end if;
end if;
end if;
end process;
end solucion;
library ieee;
use ieee.std_logic_1164.all;
entity mef_crono is
port(clk,reset,ss: in std_logic;
x,y,z: out std_logic);
end mef_crono;
process(clk,reset)
begin
if reset='1' then
ep <= S0;
elsif rising_edge(clk) then
ep <= es;
end if;
end process;
process(ep,ss)
begin
es <= ep;
case ep is
when S0=> x <= '0'; y <='0'; z <='0';
if ss='1' then es<=S1;
else es <= S0; end if;
end solucion;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity anti_rebote is
process(clk)
begin
if rising_edge(clk) then
contador <= contador+1;
end if;
end process;
process(clk_2)
begin
if rising_edge(clk_2) then
case EA is
when S0=> salida <= '0';
if entrada='0' then EA <= S0;
else EA <= S1; end if;
when S1=> salida <= '0';
if entrada='0' then EA <= S0;
else EA <= S2; end if;
when S2=> salida <= '1';
if entrada='0' then EA <= S3;
else EA <= S2; end if;
when S3=> salida <= '1';
if entrada='0' then EA <= S0;
else EA <= S2; end if;
end case;
end if;
end process;
end solucion;
● Implementación del circuito visor: Este circuito permite multiplexar las señales de los
contadores: US,DS,UM,DM y enviarlos al CPLD, para que éste a su vez los muestre
en los display a 7 segmentos.
entity VISOR_FPGA is
port(clk: in std_logic;
A,B,C,D,E,F,G,H: in std_logic_vector(3 downto 0);
data_out: out std_logic_vector(3 downto 0);
out_deco3a8: buffer std_logic_vector(2 downto 0));
end VISOR_FPGA;
end SOLUCION;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity cronometro is
port(clk,reset,min,seg,start_stop: in std_logic;
data_out: out std_logic_vector(3 downto 0);
out_deco3a8: out std_logic_vector(2 downto 0));
end cronometro;
component mef_crono
port(clk,reset,ss: in std_logic;
x,y,z: out std_logic);
end component;
component contadores_MS
port(clk,min,seg,x,y,z,reset: in std_logic;
US,DS,UM,DM: buffer std_logic_vector(3 downto 0));
end component;
component VISOR_FPGA
port(clk: in std_logic;
A,B,C,D,E,F,G,H: in std_logic_vector(3 downto 0);
data_out: out std_logic_vector(3 downto 0);
out_deco3a8: buffer std_logic_vector(2 downto 0));
end component;
component anti_rebote
port(clk,entrada: in std_logic;
salida: out std_logic);
end component;
E <= "0000";
U0: DIV_1HZ port map (CLK,CLK_1);
U1: mef_crono port map (CLK_1,reset,start_stop,x,y,z);
U2: contadores_MS port map(CLK_1,MIN_AR,SEG_AR,x,y,
z,reset,A,B,C,D);
U3: VISOR_FPGA port map(CLK,A,B,C,D,E,E,E,E,data_out,
out_deco3a8);
U4: anti_rebote port map(CLK,min,min_AR);
U5: anti_rebote port map(CLK,seg,seg_AR);
end SOLUCION;