Implementación de una máquina de estados finitos en VHDL
1. M�quinas de estado finito en VHDL
Las m�quinasde estadofinito,m�sconocidasporsuacr�nimoeningl�sFSM(FiniteState Machine),
se utilizan ampliamente en el dise�o de circuitos digitales (adem�s de en otros �mbitos de la
ingenier�a,comola programaci�n),para describirel comportamientode unsistemaseg�nel valor
de sus entradasyde c�mo vancambiandoenel tiempo. �staesunadefinici�nparcial peroque nos
permite hacernos una primera idea intuitiva. Desde el punto de vista de las FSM, un sistema est�
compuestode estados porlosque vapasandoel sistema,de se�alesdeentrada que modificanesos
estadosyde se�alesde salida que puedenutilizarse paraconocerel estadodel sistemayactuaren
consecuencia. Un ejemplo muy visual podr�a ser un sem�foro, el cu�l dispone de tres estados
diferentes, uno para cada color. Las entradas del sistema las podr�a generar un temporizador que
activa una se�al cada cierto tiempo, indicando que hay que pasar al siguiente estado.Por �ltimo,
las salidas del sistema podr�an ser tres se�ales que indiquenqu� l�mpara, de las tres disponibles,
tiene que encenderse.Para representar una m�quina de estados se utilizan diagramasde estados
como el siguiente.
2. Cada c�rculo representaunestado.En este caso tenemoscuatroestadosque se llamanS1, S2, S3 y
S4. El estadoS1 tiene unaflechaque indicaque esel estadoel inicial,al que se entra tras un reset
del sistema.El S4tiene undoble c�rculo,que indicaque esunestadofinal.Losestadosest�nunidos
por unasflechasllamadastransiciones,queindicanc�moevolucionael sistemade unestadoaotro
seg�nse activanlas se�alesde entrada.Eneste casoconcretohay tresse�alesde entrada(a,b,c y
d). Si estandoenel estadoS1 se activa la se�al a, el sistemaevolucionar�al estadoS2. Del mismo
modo,si estandoenel estadoS2se activalase�al b,el sistemaevolucionar�de nuevoal estadoS1.
En este caso no hay se�ales de salida. Si las hay pueden ponerse dentro del c�rculo o, para no
sobrecargar el diagrama,se puedendefinir fuerade �ste,porejemploenunatabla.Vamosa crear
una FSM muy b�sica y a implementarla en VHDL, para poder llevarla a una FPGA. La m�quina que
vamos a implementar es la mostrada en el siguiente diagrama de estados.
Tenemos cuatro estados (S0, S1, S2 y S3) y dos se�ales de entrada (A y B). No hemos puesto en el
diagrama las se�ales de salida, pero las definimos en la siguiente tabla:
S0 -> Y0
S1 -> Y1
3. S2 -> Y2
S3 -> Y3
Por lo tanto, tenemos cuatro se�ales de salida. La se�al Y0 se activa cuando el sistema est� en el
estado S0, La Y1 cuando el sistema est� en el estado S1 y as� sucesivamente. Como se puede
observar,lasalidadel sistemadependeexclusivamentedelestadoenelquese encuentraelsistema.
Cuando ocurre esto decimos que se trata de una m�quina de estados de tipo Moore. Si la salida
depende del estadoy adem�s de las entradasactuales del sistema, se tratar�a de una m�quina de
estados de tipo Mealy. Se puede demostrar que ambos modelos son equivalentes, as� que aqu�
vamos a quedarnos con el primer tipo que es m�s sencillo.
A nivel f�sico, una de las formas m�s efectivas de implementar una FSM es seg�n el siguiente
esquema.
Obviamente necesitamosalg�nelementode memoriaparaalmacenarel estadoactual del sistema.
Nosotros usaremos un registro de biestablesde tipo D (es por lo tanto un bloque secuencial). Los
otros dos bloques son puramente combinacionales. El primero se encarga de generar el estado
siguienteapartirdel estadoactual yde lasentradasdel sistema.Adem�s,necesitamosotrocircuito
para generar las se�ales de salida a partir del estado actual (recordemos que es una m�quina de
tipo Moore).
Voy a llevar a la pr�ctica el circuito usando una FPGA. En concreto usar� la placa BASYS 3 con una
FPGA Artix 7 de Xilinx.Voyautilizarel bot�n0comose�al de resetylosbotones4y 2 comose�ales
A y B respectivamente. Las salidas Y0 a Y3 las voy a asociar a los LEDs 0 a 3. Para evitar utilizar
circuitos antirebote para los pulsadores,he dise�ado el diagrama de forma que dos pulsaciones
seguidas del mismo bot�n no hagan evolucionar el sistema a otro estado.
Como tenemoscuatroestados,podr�amosusar dos bitpara codificarlosestados.Por ejemplo:S0-
>00, S1->01, S2->10 y S3->11. Sinembargo,lo m�s habitual esdejarque el sintetizadorlohagapor
nosotros definiendo un tipo para los estados tal y como se ve en la siguiente definici�n. As�, si
a�adimos nuevos estados, no tenemos que andar redimensionando el registro de estados.
-- declaraciones modelo FSM
type STATES is (S0, S1, S2, S3);
signal state_reg, state_next: STATES;
4. Veamosc�mose implementaenVHDL cada uno de estostres bloques.Empecemosporel registro
de estados.
-- registro de estados
process(CLK)
begin
if CLK'event and CLK='1' then
if RST='1' then
state_reg <= s0;
else
state_reg <= state_next;
end if;
end if;
end process;
El registrode estadostiene unase�al de resets�ncronaque llevaal sistemaal estadoS0.Si la l�gica
de codificaci�n del estado siguiente genera un nuevo estado, este se almacenar� en el registro,si
no,la salidadel registrose mantiene.Veamosc�moesel circuito que genera el estado siguiente.
-- L�gica de estado siguiente (circuito combinacional)
process (state_reg, A, B)
begin
state_next <= state_reg;
case state_reg is
when S0 =>
if A='1' then
state_next <= S1;
end if;
when S1 =>
if B='1' then
state_next <= S2;
end if;
when S2 =>
5. if A='1' then
state_next <= S3;
end if;
when S3 =>
state_next <= S3;
end case;
end process;
El estadosiguientese generaapartir del estadoactual y de las entradasA y B, por lo que ponemos
estastresse�alesenlalistade sensibilidaddelproceso.Paraevitarque el sintetizadorgenere alg�n
latchoelementode memoria,asignamospordefectoel estadoactual alase�al de estadosiguiente.
El c�digoVHDLdescribe losestadosy lastransicionesasociadasalasentradasseg�nel diagramade
estados que definimos m�s arriba, de forma que, de ser necesario, asigna el valor del estado
siguiente ala variable state_nextcuandohayun cambio en lasentradas o en el estado.Por �ltimo
echamos un vistazo al circuito de decodificaci�n para las salidas.
-- salida tipo Moore
process (state_reg)
begin
-- estableciendo la salida por defecto
-- nos aseguramos de crear un circuito
-- combinacional sin latches.
Y0 <= '0';
Y1 <= '0';
Y2 <= '0';
Y3 <= '0';
case state_reg is
when S0 => Y0 <= '1';
when S1 => Y1 <= '1';
when S2 => Y2 <= '1';
when S3 => Y3 <= '1';
end case;
end process;
6. De nuevo, para evitar que el sintetizador cree elementos de memoria, asignamos un valor por
defecto a las salidas (en este caso 0), y seg�n el estado actual, se activa la salida correspondiente
seg�n definimos en la tabla de arriba.
El c�digo VHDL completo de nuestra FSM es el siguiente.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity FSM is
Port ( CLK : in STD_LOGIC;
BTN : in STD_LOGIC_VECTOR (4 downto 0);
LED : out STD_LOGIC_VECTOR (15 downto 0));
end FSM;
architecture Behavioral of FSM is
-- alias
alias RST : STD_LOGIC is BTN(0);
alias A : STD_LOGIC is BTN(4);
alias B : STD_LOGIC is BTN(2);
alias Y0 : STD_LOGIC is LED(0);
alias Y1 : STD_LOGIC is LED(1);
alias Y2 : STD_LOGIC is LED(2);
alias Y3 : STD_LOGIC is LED(3);
-- declaraciones modelo FSM
type STATES is (S0, S1, S2, S3);
signal state_reg, state_next: STATES;
begin
-- registro de estados
process(CLK)
begin
if CLK'event and CLK='1' then
if RST='1' then
state_reg <= s0;
7. else
state_reg <= state_next;
end if;
end if;
end process;
-- L�gica de estado siguiente (circuito combinacional)
process (state_reg, A, B)
begin
state_next <= state_reg;
case state_reg is
when S0 =>
if A='1' then
state_next <= S1;
end if;
when S1 =>
if B='1' then
state_next <= S2;
end if;
when S2 =>
if A='1' then
state_next <= S3;
end if;
when S3 =>
state_next <= S3;
end case;
end process;
-- salida tipo Moore
process (state_reg)
begin
-- estableciendo la salida por defecto
8. -- nos aseguramos de crear un circuito
-- combinacional sin latches.
Y0 <= '0';
Y1 <= '0';
Y2 <= '0';
Y3 <= '0';
case state_reg is
when S0 => Y0 <= '1';
when S1 => Y1 <= '1';
when S2 => Y2 <= '1';
when S3 => Y3 <= '1';
end case;
end process;
end Behavioral;
Os dejoel archivode restriccionesparalaplacaBASYS 3 que he usadopara este ejemplo,dondese
definenlospuertosde lospulsadores,losLEDsy el reloj del sistema.
## LEDs
set_property PACKAGE_PIN U16 [get_ports {LED[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[0]}]
set_property PACKAGE_PIN E19 [get_ports {LED[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[1]}]
set_property PACKAGE_PIN U19 [get_ports {LED[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[2]}]
set_property PACKAGE_PIN V19 [get_ports {LED[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[3]}]
set_property PACKAGE_PIN W18 [get_ports {LED[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[4]}]
set_property PACKAGE_PIN U15 [get_ports {LED[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[5]}]
set_property PACKAGE_PIN U14 [get_ports {LED[6]}]