Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> VHDL

Ihr erstes FPGA bauen: LED Blink Tutorial (VHDL & Verilog)

Einführung

Willkommen zu einem praxisnahen Guide, der Sie durch die Erstellung eines einfachen LED-Blinkers auf einem FPGA führt – wahlweise in VHDL oder Verilog. Das Beispiel demonstriert Kernkonzepte: konkurrierende Prozesse, Frequenzsynthese und Multiplexer-Logik – alles getrieben von einem 25 MHz Clock.

Projektübersicht

Frequenzauswahl Wahrheitstabelle

EnableSwitch 1Switch 2LED Drive Frequenz
0--(deaktiviert)
100100 Hz
10150 Hz
11010 Hz
1111 Hz

Signaldefinitionen

Signal NameRichtungBeschreibung
i_clockInput25 MHz Systemclock
i_enableInputLED Enable Switch (Logik 0 = aus)
i_switch_1InputFrequenzselektor Bit 1
i_switch_2InputFrequenzselektor Bit 0
o_led_driveOutputDrive-Signal für LED

Design-Philosophie

Vier unabhängige Zählerprozesse laufen konkurrierend, jeder toggelt ein lokales Signal an seiner Zielfrequenz. Selbst wenn eine Frequenz nicht selektiert ist, läuft ihr Zähler weiter – das ist das Markenzeichen von FPGA-Konkurrenz.

Die Switches implementieren einen kombinatorischen Multiplexer, der das gewünschte Toggle-Signal zum LED-Driver routet. Der LED_EN Switch fungiert als active-high Gate, das die LED ausschaltet, wenn Enable low ist.

Blockdiagramm

Ihr erstes FPGA bauen: LED Blink Tutorial (VHDL & Verilog)

VHDL Implementation

Unten ein vollständig kommentiertes VHDL-Modul, das die Spezifikation erfüllt. Die Zählerkonstanten werden berechnet mit der Formel:
count = (Clockfrequenz / Zielfrequenz) × 0.5 für 50 % Duty Cycle.

 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 -- Frequenzkonstanten (Halbperioden-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 -- Zählersignale 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-Ausgänge 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-Selektion signal w_LED_SELECT : std_logic; begin -- 100 Hz Toggling Prozess 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 Prozess 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 Prozess 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 Prozess 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 basierend auf 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; -- LED Drive mit Enable-Switch gaten o_led_drive <= w_LED_SELECT and i_enable; end rtl; 

Verilog Implementation

Unten ein äquivalentes Verilog-Modul. Die Design-Philosophie ist identisch – vier unabhängige always Blöcke, jeder toggelt an einer spezifischen Frequenz, und ein kombinatorischer Multiplexer getrieben von den Switches.

 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; // Frequenzparameter (Halbperioden-Counts) parameter c_CNT_100HZ = 125000; parameter c_CNT_50HZ = 250000; parameter c_CNT_10HZ = 1250000; parameter c_CNT_1HZ = 12500000; // Zählerregister 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-Register 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-Selektion 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 // Kombinatorischer 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 // LED Drive mit Enable Gating assign o_led_drive = r_LED_SELECT & i_enable; endmodule 

Simulation & Verifikation

Vor dem Programmieren des FPGA führen Sie eine Verhaltenssimulation durch (z. B. mit ModelSim, VCS oder Vivado Simulator). Verifizieren Sie, dass jedes Toggle-Signal der erwarteten Periode entspricht und der Multiplexer basierend auf der Switch-Kombination korrekt routet. Frühes Simulieren eliminiert kostspieliges Hardware-Debugging und bestätigt, dass der 50 % Duty Cycle eingehalten wird.

Fazit

Dieses Tutorial zeigt, wie man einen kompakten, wiederverwendbaren LED-Blinker baut, der für andere Timing-Aufgaben adaptierbar ist. Das gleiche Zähler-basierte Frequenzsynthese-Pattern skaliert zu komplexeren Zustandsmaschinen und ist eine fundamentale Skill für jeden FPGA-Entwickler.

VHDL

  1. C# Hello World – Ihre erste C#-Anwendung erstellen
  2. Einstieg in FPGA-Entwicklung: 4-Bit-Adder auf Xilinx Artix-7 bauen
  3. Embedded FPGA (eFPGA) Technologie: Revolution im ASIC- und SoC-Design
  4. Ihr erstes VHDL-Programm: Schritt-für-Schritt Hello World Tutorial
  5. Schmierstoffanalyse-Programm optimieren für maximale Anlagenverlässlichkeit
  6. Verilog meistern: Komplettes Tutorial für digitales Schaltungsdesign
  7. Effektives Instandhaltungsprogramm (Preventive Maintenance) für Anlagen aufbauen
  8. 10 bewährte Strategien zur Verbesserung Ihres vorbeugenden Wartungsprogramms
  9. PCB-Design meistern mit Ultiboard: Umfassendes Tutorial
  10. KiCad PCB-Design Tutorial: Open-Source PCB-Entwicklung meistern