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

Cómo crear tu primer parpadeo de LED en FPGA: Tutorial paso a paso

Guía paso a paso: Diseño del parpadeo de LED en FPGA

Fase 1: Diseño HDL (VHDL / Verilog)

Objetivo: Hacer parpadear un LED a 100 Hz, 50 Hz, 10 Hz u 1 Hz (ciclo de trabajo 50%) mediante dos interruptores selectores y una entrada de habilitación (LED_EN). El FPGA funciona con un oscilador de 25 MHz.

Tabla de verdad del selector de frecuencia

EnableSwitch 1Switch 2Frecuencia LED
0––Deshabilitado
100100 Hz
10150 Hz
11010 Hz
1111 Hz

Resumen de señales

SeñalDirecciónDescripción
i_clockEntradaReloj 25 MHz
i_enableEntradaHabilitación (0 = LED apagado)
i_switch_1EntradaSelector frecuencia bit 1
i_switch_2EntradaSelector frecuencia bit 2
o_led_driveSalidaSeñal de drive del LED

Arquitectura: cuatro contadores concurrentes (uno por frecuencia objetivo) que generan señales de toggle. Un multiplexor combinacional selecciona la señal según los switches. La habilitación aplica una compuerta AND.

Implementación en VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tutorial_led_blink is
    port (
        i_clock      : in  std_logic;
        i_enable     : in  std_logic;
        i_switch_1   : in  std_logic;
        i_switch_2   : in  std_logic;
        o_led_drive  : out std_logic
    );
end tutorial_led_blink;
architecture rtl of tutorial_led_blink is
    constant c_CNT_100HZ : natural := 125000;  -- 25MHz / (100Hz * 2)
    constant c_CNT_50HZ  : natural := 250000;
    constant c_CNT_10HZ  : natural := 1250000;
    constant c_CNT_1HZ   : natural := 12500000;
    signal r_CNT_100HZ : natural range 0 to c_CNT_100HZ;
    signal r_CNT_50HZ  : natural range 0 to c_CNT_50HZ;
    signal r_CNT_10HZ  : natural range 0 to c_CNT_10HZ;
    signal r_CNT_1HZ   : natural range 0 to c_CNT_1HZ;
    signal r_TOGGLE_100HZ : std_logic := '0';
    signal r_TOGGLE_50HZ  : std_logic := '0';
    signal r_TOGGLE_10HZ  : std_logic := '0';
    signal r_TOGGLE_1HZ   : std_logic := '0';
    signal w_LED_SELECT   : std_logic;
begin
    -- Contador 100 Hz
    p_100_HZ: process(i_clock)
    begin
        if rising_edge(i_clock) then
            if r_CNT_100HZ = c_CNT_100HZ - 1 then
                r_TOGGLE_100HZ <= not r_TOGGLE_100HZ;
                r_CNT_100HZ <= 0;
            else
                r_CNT_100HZ <= r_CNT_100HZ + 1;
            end if;
        end if;
    end process;
    -- Contadores 50 Hz, 10 Hz, 1 Hz (análogos) ...
    -- Multiplexor
    w_LED_SELECT <= r_TOGGLE_100HZ when (i_switch_1 = '0' and i_switch_2 = '0') else
                    r_TOGGLE_50HZ  when (i_switch_1 = '0' and i_switch_2 = '1') else
                    r_TOGGLE_10HZ  when (i_switch_1 = '1' and i_switch_2 = '0') else
                    r_TOGGLE_1HZ;
    o_led_drive <= w_LED_SELECT and i_enable;
end rtl;

Implementación en Verilog

module tutorial_led_blink (
    input  i_clock,
    input  i_enable,
    input  i_switch_1,
    input  i_switch_2,
    output o_led_drive
);
    parameter c_CNT_100HZ = 125;   // para simulación con reloj 25 kHz
    parameter c_CNT_50HZ  = 250;
    parameter c_CNT_10HZ  = 1250;
    parameter c_CNT_1HZ   = 12500;
    reg [31:0] r_CNT_100HZ = 0, r_CNT_50HZ = 0, r_CNT_10HZ = 0, r_CNT_1HZ = 0;
    reg r_TOGGLE_100HZ = 0, r_TOGGLE_50HZ = 0, r_TOGGLE_10HZ = 0, r_TOGGLE_1HZ = 0;
    reg r_LED_SELECT;
    always @(posedge i_clock) begin
        if (r_CNT_100HZ == c_CNT_100HZ-1) begin r_TOGGLE_100HZ <= ~r_TOGGLE_100HZ; r_CNT_100HZ <= 0; end else r_CNT_100HZ <= r_CNT_100HZ + 1;
        if (r_CNT_50HZ  == c_CNT_50HZ-1)  begin r_TOGGLE_50HZ  <= ~r_TOGGLE_50HZ;  r_CNT_50HZ  <= 0; end else r_CNT_50HZ  <= r_CNT_50HZ  + 1;
        if (r_CNT_10HZ  == c_CNT_10HZ-1)  begin r_TOGGLE_10HZ  <= ~r_TOGGLE_10HZ;  r_CNT_10HZ  <= 0; end else r_CNT_10HZ  <= r_CNT_10HZ  + 1;
        if (r_CNT_1HZ   == c_CNT_1HZ-1)   begin r_TOGGLE_1HZ   <= ~r_TOGGLE_1HZ;   r_CNT_1HZ   <= 0; end else r_CNT_1HZ   <= r_CNT_1HZ   + 1;
    end
    always @(*) begin
        case ({i_switch_1, i_switch_2})
            2'b00: r_LED_SELECT = r_TOGGLE_100HZ;
            2'b01: r_LED_SELECT = r_TOGGLE_50HZ;
            2'b10: r_LED_SELECT = r_TOGGLE_10HZ;
            2'b11: r_LED_SELECT = r_TOGGLE_1HZ;
        endcase
    end
    assign o_led_drive = r_LED_SELECT & i_enable;
endmodule

Próximo paso: Simulación

Simular el diseño en VHDL o Verilog para verificar el comportamiento antes de la implementación en hardware. La simulación es un punto de control obligatorio para evitar depuración costosa en placa.

VHDL

  1. Testea tus conocimientos VHDL – Quiz interactivo Parte 1
  2. Mejora la verificación de hardware con un testbench interactivo basado en Tcl
  3. Generación de números aleatorios en VHDL: De uniforme a OSVVM
  4. Creación de un testbench dirigido por Tcl para un módulo VHDL de cerradura por código
  5. Lectura de imágenes BMP en testbenches VHDL con TEXTIO
  6. Creación de un efecto LED respiratorio usando una onda senoidal desde RAM de bloques
  7. Aprovechando records VHDL para interfaces FIFO limpias y reutilizables
  8. Domine la verificación aleatoria restringida con OSVVM
  9. Dominando la sentencia Case-When en VHDL: Diseño eficiente de multiplexores
  10. Dominando std_logic_vector: Creando vectores de señal en VHDL
  11. Diseño de máquina de estados finitos en VHDL: Ejemplo práctico de semáforo