Você está na página 1de 5

Para explicar bien intentar escribir como hablara para dar lo que hace este cdigo.

Iremos paso por paso para que no quede nada sin cubrir.

1. Las libreras necesarias


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.NUMERIC_STD.ALL;

2. La entidad. Qu es esta seccin? Donde se escriben los puertos de entrada y salida del circuito. En
este caso necesito como entradas el reloj (porque es un circuito secuencial), el reset, un botn que al
presionarlo va a aumentar el contador. Y como salidas estn los displays (7 segmentos cada uno y el
punto) y sus habilitadores (si no comprenden bien qu son, no se hagan muchas bolas porque no lo
necesitan ahorita pero simplemente son la base de transistores que dicen si un display se enciende o
no).
entity TOP is
PORT(
clk, rst, btn : in std_logic; -- un bit cada uno
e : out std_logic_vector(2 downto 0); -- 3 bits porque hay tres habilitadores
seg : out std_logic_vector(7 downto 0) 8 bits
);
end TOP;

3. Empieza la arquitectura
architecture Behavioral of TOP is

4. Cuando creamos las memorias donde guardan valores de las seales que estn replicando dijimos que
una ventaja de vhdl es que podemos crear tipos de variables, como ya existen el entero (nmeros +, - y
0), natural (+ y 0), stdl_logic (1, 0, h, l, u, x, z, w, -) y otros. En este caso entonces queremos crear un tipo
de mquina de estado y lo llamaremos FSM por finite state machine, que va a tener la caracterstica de
ser ESPERA para cuando, valga la redundancia, estemos esperando a que el botn se presione, HOLD
para cuando el botn haya sido presionado y esperemos a que se suelte y DELAY para esperar una
fraccin de tiempo antes de volver al inicio. As, puedo tener una variable que se llame a, papa, taza,
actual, State (o como yo quiera) que ser del tipo FSM.

type FSM is (ESPERA, HOLD, DELAY);


signal State : FSM;

5. Declaro contadores
signal cnt : natural range 0 to 9; -- contador para sacar en displays
signal cnt_del : natural range 0 to 1200000; -- contador para delay
begin

6. Hay que considerar ahora que el objetivo de una mquina de estados para evitar rebotes es que no se
den lecturas errneas del valor de botn porque cualquier roce, falso contacto o fallo de hardware
puede hacer que se reciba un 1 cuando realmente no se presion el botn o que se reciban veinte 1s
seguidos y entonces veramos el contador ir a loco entre nmeros porque cambia muy rpido cuando
slo presionamos una vez.
Entonces la magia est en decir que slo vamos a permitir al fpga recibir un 1 cuando hayamos
asegurado que ese es su estado y de igual forma el 0, en caso de estar usando lgica negada.
As va lo siguiente:
Inicio un proceso porque es un circuito sincronizado y este va a depender en mi caso del reloj de la
tarjeta pero puede depender de la frecuencia que ustedes necesitan. Tambin depende del reset
asncrono y le especifico que cuando el botn rst se presione, reinicie el contador.

process(clk, rst)
begin
if(rst='0')then
cnt<=0;

7. Ahora, la mquina de estados depende de los flancos de subida del reloj que le puse.
elsif(rising_edge(clk))then
-- conteo sin rebote

8. Y la sintaxis de una FSM siempre va a estar dada por un case. Este case va a ser la lectura del valor que
tenga la seal que cre al inicio de la arquitectura y los valores que puede tomar son los estados que le
asign a la mquina.
case State is

9. El primer estado lo que hace es mantener a la tarjeta como en modo de escucha con otro case que
depende del botn. Su comportamiento resulta ser que mientras el botn no se presione, vamos a
seguir esperando y cuando s se haya presionado entonces hacemos algo.
when ESPERA =>

10. Entonces este case est dentro del estado ESPERA y dice si estoy en espera y el botn es 0, significa que
se presion y lo que interesa en este caso es sumar 1 al contador y pasar al siguiente estado (HOLD). Si,
por otro lado, estoy en espera y el botn es 1, significa que no ha sido presionado y lo que debo hacer es
seguir esperando lo ltimo est contemplado en el when others.
Realmente para su proyecto, aqu es donde les interesara poner la accin de replicar la seal slo que
de esta forma se evitan precisamente que por un mal contacto de las teclas, el valor vaya de 0 a 1
cuando no quieren. La diferencia est realmente en quizs no pondran slo un case para btn, sino para
sw.
case btn is
when '0' => State<=HOLD;
case cnt is
when 9 => cnt<=0;
when others => cnt<=cnt+1;
end case;
when others => State<=ESPERA;
end case;

11. Digamos que s presion el botn y la seccin anterior hizo entonces que State<=HOLD, esto hace que
entremos a la siguiente opcin del case principal.
when HOLD =>
12. Aqu tambin tengo entonces un case anidado que depende del botn porque presion el botn pero
digamos que todo es tan rpido dentro del fpga que realmente no lo he soltado. La valuacin dice Si el
botn sigue presionado, estoy en HOLD. Si estoy en hold y el botn es 1, significa que lo soltaron
entonces puedo hacer algo y pasar al siguiente estado que es DELAY. Si, por otro lado, estoy en hold y el
botn es 0 es que siguen presionndolo y como interesa slo realizar una vez por cada vez que se
presiona, entonces debo seguir esperando a que lo suelten igualmente la segunda opcin la ven en el
when others.
case btn is
when '1' => State<=DELAY;
when others => State<=HOLD;
end case;

13. Y por ultimo tenemos el estado DELAY, que est contemplado tambin en un when others porque es la
nica otra opcin que puede darse como valor de la mquina de estados. Algunas veces s se incluye
este entre los casos y se agrega un ltimo estado que haga un reset de variables si es que se usan
frescas pero eso ya depende del diseo. Esta parte nicamente lo que hace es contar una fraccin de
segundo y al terminar, vuelve al estado ESPERA.
when others =>
if(cnt_del=1200000)then
cnt_del<=0;
State<=ESPERA;
else
cnt_del<=cnt_del+1;
end if;
end case;

14. Este ultimo pedazo nicamente lo que hace es poner el nmero del contador en el display.
-- escritura en displays
case cnt is
when 0 => seg<=x"03";
when 1 => seg<=x"9F";
when 2 => seg<=x"25";
when 3 => seg<=x"0D";
when 4 => seg<=x"99";
when 5 => seg<=x"49";
when 6 => seg<=x"41";
when 7 => seg<=x"1F";
when 8 => seg<=x"01";
when 9 => seg<=x"09";
when others => seg<=x"FD";
end case;
end if;
end process;

e<=o"6";

end Behavioral;
Aqu est el cdigo complete por si no se entiende bien por separado.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.NUMERIC_STD.ALL;

entity TOP is
PORT(
clk, rst, btn : in std_logic;
e : out std_logic_vector(2 downto 0);
seg : out std_logic_vector(7 downto 0)
);
end TOP;

architecture Behavioral of TOP is


type FSM is (ESPERA, HOLD, DELAY);
signal State : FSM;
signal cnt : natural range 0 to 9;
signal cnt_del : natural range 0 to 1200000;
begin

process(clk, rst)
begin
if(rst='0')then
cnt<=0;
elsif(rising_edge(clk))then
-- conteo sin rebote
case State is
when ESPERA =>
case btn is
when '0' => State<=HOLD;
case cnt is
when 9 => cnt<=0;
when others => cnt<=cnt+1;
end case;
when others => State<=ESPERA;
end case;
when HOLD =>
case btn is
when '1' => State<=DELAY;
when others => State<=HOLD;
end case;
when others =>
if(cnt_del=1200000)then
cnt_del<=0;
State<=ESPERA;
else
cnt_del<=cnt_del+1;
end if;
end case;

-- escritura en displays
case cnt is
when 0 => seg<=x"03";
when 1 => seg<=x"9F";
when 2 => seg<=x"25";
when 3 => seg<=x"0D";
when 4 => seg<=x"99";
when 5 => seg<=x"49";
when 6 => seg<=x"41";
when 7 => seg<=x"1F";
when 8 => seg<=x"01";
when 9 => seg<=x"09";
when others => seg<=x"FD";
end case;
end if;
end process;

e<=o"6";

end Behavioral;

Você também pode gostar