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
| Enable | Switch 1 | Switch 2 | Frecuencia LED |
|---|---|---|---|
| 0 | – | – | Deshabilitado |
| 1 | 0 | 0 | 100 Hz |
| 1 | 0 | 1 | 50 Hz |
| 1 | 1 | 0 | 10 Hz |
| 1 | 1 | 1 | 1 Hz |
Resumen de señales
| Señal | Dirección | Descripción |
|---|---|---|
| i_clock | Entrada | Reloj 25 MHz |
| i_enable | Entrada | Habilitación (0 = LED apagado) |
| i_switch_1 | Entrada | Selector frecuencia bit 1 |
| i_switch_2 | Entrada | Selector frecuencia bit 2 |
| o_led_drive | Salida | Señ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
- Testea tus conocimientos VHDL – Quiz interactivo Parte 1
- Mejora la verificación de hardware con un testbench interactivo basado en Tcl
- Generación de números aleatorios en VHDL: De uniforme a OSVVM
- Creación de un testbench dirigido por Tcl para un módulo VHDL de cerradura por código
- Lectura de imágenes BMP en testbenches VHDL con TEXTIO
- Creación de un efecto LED respiratorio usando una onda senoidal desde RAM de bloques
- Aprovechando records VHDL para interfaces FIFO limpias y reutilizables
- Domine la verificación aleatoria restringida con OSVVM
- Dominando la sentencia Case-When en VHDL: Diseño eficiente de multiplexores
- Dominando std_logic_vector: Creando vectores de señal en VHDL
- Diseño de máquina de estados finitos en VHDL: Ejemplo práctico de semáforo