Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> VHDL

Diseño de máquina de estados finitos en VHDL: Ejemplo práctico de semáforo

Una máquina de estados finitos (FSM) es un modelo lógico determinista cuya salida depende no solo de la entrada actual sino también de la secuencia de entradas y salidas pasadas. En diseño FPGA y algoritmos VHDL dependientes del tiempo, una FSM es la abstracción de referencia para capturar comportamiento con estado.

Las FSM en VHDL se implementan típicamente como procesos con reloj que usan una señal state para recordar la última configuración. La señal de estado actúa como un registro interno, permitiendo que el diseño reaccione a eventos que abarcan múltiples ciclos de reloj.

Tutoriales Básicos de VHDL – Parte 3

Semáforos como FSM

Considere una intersección de cuatro vías controlada por semáforos. Las luces ciclan a través de un conjunto finito de estados visibles —por ejemplo, Norte/Sur rojo, Norte/Sur verde, Oeste/Este rojo, etc. La temporización de cada estado (5 s para rojo o amarillo, 60 s para verde) es impulsada por ciclos de reloj transcurridos.

Diseño de máquina de estados finitos en VHDL: Ejemplo práctico de semáforo

Modelamos estos comportamientos definiendo un tipo enumerado que lista todos los estados posibles:

type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest);

Luego declaramos una señal de ese tipo para mantener el estado actual:

signal State : t_State;

Con la señal de estado en su lugar, la lógica FSM vive dentro de un solo proceso con reloj que usa una sentencia case. Cada rama when corresponde a un estado distinto y contiene las asignaciones de salida para ese estado. Un contador rastrea el tiempo transcurrido e impulsa la transición al siguiente estado cuando su valor alcanza un umbral predefinido.

Plantilla FSM de un proceso

process(Clk) is
begin
  if rising_edge(Clk) then
    if nRst = '0' then
      State  <= ;
      Counter<= 0;
    else
      case State is
        when  =>
          
          if  then
            State <= ;
          end if;
        ...
      end case;
    end if;
  end if;
end process;

Nota: Puede implementar FSMs usando estilos de uno, dos o tres procesos. Ver Estilos FSM Explicados.

Ejercicio práctico

A continuación se muestra un ejemplo completo y sintetizable que implementa un controlador de semáforo. El diseño usa un reloj de 100 Hz para simplificar la simulación mientras demuestra temporización realista.

Testbench

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T20_FiniteStateMachineTb is
end entity;

architecture sim of T20_FiniteStateMachineTb is
  constant ClockFrequencyHz : integer := 100; -- 100 Hz
  constant ClockPeriod : time := 1000 ms / ClockFrequencyHz;
  signal Clk : std_logic := '1';
  signal nRst : std_logic := '0';
  signal NorthRed : std_logic;
  signal NorthYellow : std_logic;
  signal NorthGreen : std_logic;
  signal WestRed : std_logic;
  signal WestYellow : std_logic;
  signal WestGreen : std_logic;
begin
  i_TrafficLights : entity work.T20_TrafficLights(rtl)
    generic map(ClockFrequencyHz => ClockFrequencyHz)
    port map(
      Clk        => Clk,
      nRst       => nRst,
      NorthRed   => NorthRed,
      NorthYellow=> NorthYellow,
      NorthGreen => NorthGreen,
      WestRed    => WestRed,
      WestYellow => WestYellow,
      WestGreen  => WestGreen
    );
  Clk <= not Clk after ClockPeriod / 2;
  process is
  begin
    wait until rising_edge(Clk);
    wait until rising_edge(Clk);
    nRst <= '1';
    wait;
  end process;
end architecture;

Módulo Máquina de Estados

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T20_TrafficLights is
  generic(ClockFrequencyHz : integer);
  port(
    Clk        : in  std_logic;
    nRst       : in  std_logic; -- Reset activo bajo
    NorthRed   : out std_logic;
    NorthYellow: out std_logic;
    NorthGreen : out std_logic;
    WestRed    : out std_logic;
    WestYellow : out std_logic;
    WestGreen  : out std_logic
  );
end entity;

architecture rtl of T20_TrafficLights is
  type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest);
  signal State : t_State;
  signal Counter : integer range 0 to ClockFrequencyHz * 60;
begin
  process(Clk) is
  begin
    if rising_edge(Clk) then
      if nRst = '0' then
        State       <= NorthNext;
        Counter     <= 0;
        NorthRed    <= '1';
        NorthYellow <= '0';
        NorthGreen  <= '0';
        WestRed     <= '1';
        WestYellow  <= '0';
        WestGreen   <= '0';
      else
        -- Salidas por defecto
        NorthRed    <= '0';
        NorthYellow <= '0';
        NorthGreen  <= '0';
        WestRed     <= '0';
        WestYellow  <= '0';
        WestGreen   <= '0';
        Counter     <= Counter + 1;
        
        case State is
          when NorthNext =>
            NorthRed <= '1';
            WestRed  <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0;
              State   <= StartNorth;
            end if;
          when StartNorth =>
            NorthRed   <= '1';
            NorthYellow<= '1';
            WestRed    <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0;
              State   <= North;
            end if;
          when North =>
            NorthGreen <= '1';
            WestRed    <= '1';
            if Counter = ClockFrequencyHz * 60 - 1 then
              Counter <= 0;
              State   <= StopNorth;
            end if;
          when StopNorth =>
            NorthYellow<= '1';
            WestRed    <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0;
              State   <= WestNext;
            end if;
          when WestNext =>
            NorthRed <= '1';
            WestRed  <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0;
              State   <= StartWest;
            end if;
          when StartWest =>
            NorthRed   <= '1';
            WestRed    <= '1';
            WestYellow <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0;
              State   <= West;
            end if;
          when West =>
            NorthRed  <= '1';
            WestGreen <= '1';
            if Counter = ClockFrequencyHz * 60 - 1 then
              Counter <= 0;
              State   <= StopWest;
            end if;
          when StopWest =>
            NorthRed   <= '1';
            WestYellow <= '1';
            if Counter = ClockFrequencyHz * 5 - 1 then
              Counter <= 0;
              State   <= NorthNext;
            end if;
        end case;
      end if;
    end if;
  end process;
end architecture;

Ejecutar la simulación durante cinco minutos produce una forma de onda que muestra la FSM ciclando a través de sus ocho estados, con fases verdes durando un minuto cada una.

Diseño de máquina de estados finitos en VHDL: Ejemplo práctico de semáforo

Análisis

Conclusiones clave del código:

La forma de onda resultante confirma que la FSM avanza correctamente: la señal State alterna a través de los ocho estados definidos, y cada fase verde persiste durante un minuto.

Conclusión

Proceda al siguiente tutorial para técnicas avanzadas de FSM.

VHDL

  1. Máquina de Estados Finitos: Aprovechando Realimentación para Construir Controladores de Secuencia Programables
  2. Cómo la máquina láser CNC OMNI crea regalos de Navidad personalizados
  3. Maximizando rendimiento de máquinas de estado Qt
  4. Creación de listas de cadenas en VHDL: Buenas prácticas y ejemplo
  5. Creación de un testbench dirigido por Tcl para un módulo VHDL de cerradura por código
  6. Finalizar elegantemente una simulación de testbench VHDL
  7. Implementación de un controlador PWM en VHDL: Diseño, simulación y demo en FPGA
  8. Generación de números aleatorios en VHDL: De uniforme a OSVVM
  9. Diseño de un búfer circular FIFO robusto en VHDL usando RAM de bloques
  10. Cómo construir un testbench de auto-comprobación en VHDL: Guía práctica
  11. Implementación de lista enlazada dinámica en VHDL con tipos protegidos y punteros de acceso