Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> VHDL

Construindo seu Primeiro FPGA: Tutorial LED Blink (VHDL & Verilog)

Introdução

Bem-vindo a um guia prático que o leva a criar um simples piscador de LED em FPGA usando VHDL ou Verilog. O exemplo demonstra conceitos centrais de FPGA: processos concorrentes, síntese de frequência e lógica de multiplexador — todos impulsionados por um clock de 25 MHz.

Visão Geral do Projeto

Tabela Verdade de Seleção de Frequência

EnableChave 1Chave 2Frequência Drive LED
0--(desabilitado)
100100 Hz
10150 Hz
11010 Hz
1111 Hz

Definições de Sinais

Nome do SinalDireçãoDescrição
i_clockInputClock de sistema 25 MHz
i_enableInputChave enable LED (lógica 0 = off)
i_switch_1InputSeletor de frequência bit 1
i_switch_2InputSeletor de frequência bit 0
o_led_driveOutputSinal de drive para o LED

Filosofia de Design

Quatro processos de contador independentes rodam concorrentemente, cada um alternando um sinal local na frequência alvo. Mesmo quando uma frequência particular não é selecionada, seu contador continua rodando — esta é a marca da concorrência em FPGA.

As chaves implementam um multiplexador combinacional que roteia o sinal de alternância desejado para o driver do LED. A chave LED_EN atua como gate active-high, garantindo que o LED apague quando enable está baixo.

Diagrama de Blocos

Construindo seu Primeiro FPGA: Tutorial LED Blink (VHDL & Verilog)

Implementação VHDL

Abaixo está um módulo VHDL totalmente comentado que satisfaz a especificação. As constantes de contador são calculadas usando a fórmula:
count = (frequência clock / frequência alvo) × 0.5 para alcançar duty cycle de 50%.

 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 -- Frequency constants (half‑period counts) constant c_CNT_100HZ : natural := 125000; -- 25 MHz / 100 Hz × 0.5 constant c_CNT_50HZ : natural := 250000; -- 25 MHz / 50 Hz × 0.5 constant c_CNT_10HZ : natural := 1250000; -- 25 MHz / 10 Hz × 0.5 constant c_CNT_1HZ : natural := 12500000; -- 25 MHz / 1 Hz × 0.5 -- Counter signals 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; -- Toggle outputs 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'; -- Multiplexer selection signal w_LED_SELECT : std_logic; begin -- 100 Hz toggling process p_100_HZ : process (i_clock) is 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 p_100_HZ; -- 50 Hz toggling process p_50_HZ : process (i_clock) is begin if rising_edge(i_clock) then if r_CNT_50HZ = c_CNT_50HZ-1 then r_TOGGLE_50HZ <= not r_TOGGLE_50HZ; r_CNT_50HZ <= 0; else r_CNT_50HZ <= r_CNT_50HZ + 1; end if; end if; end process p_50_HZ; -- 10 Hz toggling process p_10_HZ : process (i_clock) is begin if rising_edge(i_clock) then if r_CNT_10HZ = c_CNT_10HZ-1 then r_TOGGLE_10HZ <= not r_TOGGLE_10HZ; r_CNT_10HZ <= 0; else r_CNT_10HZ <= r_CNT_10HZ + 1; end if; end if; end process p_10_HZ; -- 1 Hz toggling process p_1_HZ : process (i_clock) is begin if rising_edge(i_clock) then if r_CNT_1HZ = c_CNT_1HZ-1 then r_TOGGLE_1HZ <= not r_TOGGLE_1HZ; r_CNT_1HZ <= 0; else r_CNT_1HZ <= r_CNT_1HZ + 1; end if; end if; end process p_1_HZ; -- Multiplexer based on switch inputs 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; -- Gate the LED drive with the enable switch o_led_drive <= w_LED_SELECT and i_enable; end rtl; 

Implementação Verilog

Abaixo está um módulo Verilog equivalente. A filosofia de design é idêntica — quatro blocos always independentes, cada um alternando em frequência específica, e um multiplexador combinacional impulsionado pelas chaves.

 module tutorial_led_blink ( i_clock, i_enable, i_switch_1, i_switch_2, o_led_drive ); input i_clock; input i_enable; input i_switch_1; input i_switch_2; output o_led_drive; // Frequency parameters (half‑period counts) parameter c_CNT_100HZ = 125000; parameter c_CNT_50HZ = 250000; parameter c_CNT_10HZ = 1250000; parameter c_CNT_1HZ = 12500000; // Counter registers reg [31:0] r_CNT_100HZ = 0; reg [31:0] r_CNT_50HZ = 0; reg [31:0] r_CNT_10HZ = 0; reg [31:0] r_CNT_1HZ = 0; // Toggle registers reg r_TOGGLE_100HZ = 1'b0; reg r_TOGGLE_50HZ = 1'b0; reg r_TOGGLE_10HZ = 1'b0; reg r_TOGGLE_1HZ = 1'b0; // Multiplexer selection reg r_LED_SELECT; wire w_LED_SELECT; // 100 Hz toggle block 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; end // 50 Hz toggle block always @(posedge i_clock) begin 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; end // 10 Hz toggle block always @(posedge i_clock) begin 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; end // 1 Hz toggle block always @(posedge i_clock) begin 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 // Combinational multiplexer always @(*) begin case ({i_switch_1, i_switch_2}) 2'b11: r_LED_SELECT <= r_TOGGLE_1HZ; 2'b10: r_LED_SELECT <= r_TOGGLE_10HZ; 2'b01: r_LED_SELECT <= r_TOGGLE_50HZ; 2'b00: r_LED_SELECT <= r_TOGGLE_100HZ; endcase end // Drive LED with enable gating assign o_led_drive = r_LED_SELECT & i_enable; endmodule 

Simulação & Verificação

Antes de programar o FPGA, execute uma simulação comportamental (ex.: ModelSim, VCS, ou Vivado Simulator). Verifique se cada sinal de alternância corresponde ao período esperado e que o multiplexador roteia corretamente o sinal baseado na combinação das chaves. Simular cedo elimina depuração cara de hardware e confirma que o duty cycle de 50% é mantido.

Conclusão

Este tutorial demonstra como construir um piscador de LED compacto e reutilizável que pode ser adaptado a outras tarefas de temporização. O mesmo padrão de síntese de frequência baseada em contadores escala para máquinas de estado mais complexas, tornando-se uma habilidade fundamental para qualquer desenvolvedor FPGA.

VHDL

  1. C# Hello World – Criando Sua Primeira Aplicação C#
  2. Iniciando Desenvolvimento FPGA: Construindo um Somador de 4 Bits no Xilinx Artix-7
  3. Tecnologia Embedded FPGA (eFPGA): Revolucionando Design de ASIC e SoC
  4. Seu Primeiro Programa VHDL: Tutorial Passo a Passo Hello World
  5. Aprimore Seu Programa de Análise de Lubrificantes para Confiabilidade Máxima do Ativo
  6. Domine o Verilog: Tutorial Completo para Projeto de Circuitos Digitais
  7. Projetando um Programa de Manutenção Preventiva Eficaz para Equipamentos
  8. 10 Estratégias Comprovadas para Aprimorar seu Programa de Manutenção Preventiva
  9. Domine o Design de PCB Rapidamente com Ultiboard: Um Tutorial Abrangente
  10. Tutorial de Design de PCB com KiCAD: Dominando o Desenvolvimento Open-Source de PCI