Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> VHDL

Construire votre premier FPGA : tutoriel LED clignotante (VHDL & Verilog)

Introduction

Bienvenue dans ce guide pratique qui vous accompagne dans la création d'un simple clignotement de LED sur FPGA en VHDL ou Verilog. L'exemple démontre les concepts fondamentaux FPGA : processus concurrents, synthèse de fréquence, et logique multiplexeur — le tout piloté par une horloge 25 MHz.

Vue d'ensemble du projet

Table de vérité de sélection de fréquence

EnableSwitch 1Switch 2Fréquence pilotage LED
0--(désactivé)
100100 Hz
10150 Hz
11010 Hz
1111 Hz

Définitions des signaux

Nom du signalDirectionDescription
i_clockEntréeHorloge système 25 MHz
i_enableEntréeCommutateur activation LED (logique 0 = éteint)
i_switch_1EntréeSélecteur fréquence bit 1
i_switch_2EntréeSélecteur fréquence bit 0
o_led_driveSortieSignal de pilotage pour la LED

Philosophie de conception

Quatre processus de compteur indépendants s'exécutent en parallèle, chacun basculant un signal local à sa fréquence cible. Même quand une fréquence particulière n'est pas sélectionnée, son compteur continue de tourner — c'est la marque de la concurrence FPGA.

Les commutateurs implémentent un multiplexeur combinatoire qui route le signal de basculement désiré vers le pilote LED. Le commutateur LED_EN agit comme une porte active-haute, assurant que la LED s'éteint quand l'activation est basse.

Diagramme de blocs

Construire votre premier FPGA : tutoriel LED clignotante (VHDL & Verilog)

Implémentation VHDL

Ci-dessous un module VHDL entièrement commenté satisfaisant la spécification. Les constantes de compteur sont calculées avec la formule :
count = (fréquence horloge / fréquence cible) × 0.5 pour obtenir un cycle de travail 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 -- Constantes de fréquence (comptages demi-période) 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 -- Signaux compteurs 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; -- Sorties de basculement 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'; -- Sélection multiplexeur signal w_LED_SELECT : std_logic; begin -- Processus basculement 100 Hz 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; -- Processus basculement 50 Hz 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; -- Processus basculement 10 Hz 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; -- Processus basculement 1 Hz 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; -- Multiplexeur basé sur les entrées commutateurs 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; -- Pilotage LED avec porte d'activation o_led_drive <= w_LED_SELECT and i_enable; end rtl; 

Implémentation Verilog

Ci-dessous un module Verilog équivalent. La philosophie de conception est identique — quatre blocs always indépendants, chacun basculant à une fréquence spécifique, et un multiplexeur combinatoire piloté par les commutateurs.

 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; // Paramètres de fréquence (comptages demi-période) parameter c_CNT_100HZ = 125000; parameter c_CNT_50HZ = 250000; parameter c_CNT_10HZ = 1250000; parameter c_CNT_1HZ = 12500000; // Registres compteurs 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; // Registres basculement reg r_TOGGLE_100HZ = 1'b0; reg r_TOGGLE_50HZ = 1'b0; reg r_TOGGLE_10HZ = 1'b0; reg r_TOGGLE_1HZ = 1'b0; // Sélection multiplexeur reg r_LED_SELECT; wire w_LED_SELECT; // Bloc basculement 100 Hz 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 // Bloc basculement 50 Hz 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 // Bloc basculement 10 Hz 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 // Bloc basculement 1 Hz 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 // Multiplexeur combinatoire 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 // Pilotage LED avec porte d'activation assign o_led_drive = r_LED_SELECT & i_enable; endmodule 

Simulation et vérification

Avant de programmer le FPGA, lancez une simulation comportementale (ex: ModelSim, VCS, ou Vivado Simulator). Vérifiez que chaque signal de basculement correspond à la période attendue et que le multiplexeur route correctement le signal selon la combinaison des commutateurs. La simulation précoce élimine le débogage matériel coûteux et confirme que le cycle de travail de 50 % est maintenu.

Conclusion

Ce tutoriel montre comment construire un clignoteur LED compact et réutilisable adaptable à d'autres tâches de temporisation. Le même motif de synthèse de fréquence basé sur compteurs s'étend à des machines d'état plus complexes, en faisant une compétence fondamentale pour tout développeur FPGA.

VHDL

  1. C# Hello World — Construire votre première application C#
  2. Démarrer avec le développement FPGA : Construction d'un additionneur 4 bits sur Xilinx Artix‑7
  3. La technologie eFPGA : révolutionner la conception ASIC et SoC
  4. Optimisez votre programme d'analyse de lubrifiants pour une fiabilité maximale des actifs
  5. Maîtriser Verilog : Tutoriel complet pour la conception de circuits numériques
  6. Concevoir un Programme de Maintenance Préventive Efficace pour l'Équipement
  7. 10 Stratégies Prouvées pour Améliorer Votre Programme de Maintenance Préventive
  8. Maîtriser rapidement la conception PCB avec Ultiboard : Tutoriel complet
  9. Tutoriel KiCad PCB : Maîtriser le développement PCB open-source