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

So bauen Sie Ihren ersten FPGA-LED-Blinker:Eine Schritt-für-Schritt-Anleitung

Schritt-für-Schritt-Anleitung:Bauen Sie Ihren ersten FPGA-LED-Blinker

Teil 1:Entwerfen von VHDL oder Verilog

In diesem Tutorial erfahren Sie, wie Sie VHDL- und Verilog-Code erstellen, der eine LED mit einer benutzerdefinierten Frequenz ansteuert. Wählen Sie die Sprache, die am besten zu Ihrem Workflow passt.

Beim Schreiben von HDL müssen Sie sicherstellen, dass sich das Design wie beabsichtigt verhält. Fehler sind unvermeidlich, daher ist Simulation unverzichtbar. Dieses Tutorial ist in zwei kritische Phasen unterteilt:

  1. HDL-Design
  2. HDL-Simulation

Das Überspringen der Simulation kann zu kostspieligem Hardware-Debugging führen. Behandeln Sie die Simulation als obligatorischen Kontrollpunkt.

Projektanforderungen

Schreiben Sie HDL, das eine LED mit 100 Hz, 50 Hz, 10 Hz oder 1 Hz und einem Arbeitszyklus von 50 % blinken lässt. Zwei Schalter wählen die gewünschte Frequenz und ein zusätzlicher LED_EN Der Schalter muss hoch sein, um die LED zu aktivieren. Das FPGA läuft auf einem 25-MHz-Oszillator.

Wahrheitstabelle für den Frequenzselektor:

Aktivieren Schalter1 Schalter2 LED-Antriebsfrequenz
0 deaktiviert
1 0 0 100Hz
1 0 1 50Hz
1 1 0 10Hz
1 1 1 1Hz

Signalzusammenfassung:

Signalname Richtung Beschreibung
i_clock Eingabe 25-MHz-Takt
i_enable Eingabe Aktivierungsschalter (Logik0 =LED aus)
i_switch_1 Eingabe Frequenzwahlschalter1
i_switch_2 Eingabe Frequenzwahlschalter2
o_led_drive Ausgabe LED-Antriebssignal

Vier gleichzeitige Zählerprozesse überwachen den 25-MHz-Takt und erzeugen Umschaltungen für jede Zielfrequenz. Auch wenn eine bestimmte Frequenz nicht ausgewählt ist, läuft der Zähler weiter – ein Kernprinzip der Hardware-Parallelität.

Die Schalter bilden einen Multiplexer, der den gewählten Schalter an den LED-Ausgang weiterleitet. Multiplexer sind rein kombinatorische Logik, arbeiten also ohne Takt.

Unten finden Sie ein Blockdiagramm, das die Architektur veranschaulicht:

So bauen Sie Ihren ersten FPGA-LED-Blinker:Eine Schritt-für-Schritt-Anleitung

VHDL-Implementierung

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
 -- Constants to create the frequencies needed:
 -- Formula is: (25 MHz / 100 Hz * 50% duty cycle)
 -- So for 100 Hz: 25,000,000 / 100 * 0.5 = 125,000
 constant c_CNT_100HZ : natural := 125000;
 constant c_CNT_50HZ : natural := 250000;
 constant c_CNT_10HZ : natural := 1250000;
 constant c_CNT_1HZ : natural := 12500000;
 -- These signals will be the counters:
 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;
 
 -- These signals will toggle at the frequencies needed:
 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';
 -- One bit select wire.
 signal w_LED_SELECT : std_logic;
 
begin
 -- All processes toggle a specific signal at a different frequency.
 -- They all run continuously even if the switches are
 -- not selecting their particular output.
 
 p_100_HZ : process (i_clock) is
 begin
 if rising_edge(i_clock) then
 if r_CNT_100HZ = c_CNT_100HZ-1 then -- -1, since counter starts at 0
 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;
 p_50_HZ : process (i_clock) is
 begin
 if rising_edge(i_clock) then
 if r_CNT_50HZ = c_CNT_50HZ-1 then -- -1, since counter starts at 0
 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;
 
 p_10_HZ : process (i_clock) is
 begin
 if rising_edge(i_clock) then
 if r_CNT_10HZ = c_CNT_10HZ-1 then -- -1, since counter starts at 0
 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;
 
 p_1_HZ : process (i_clock) is
 begin
 if rising_edge(i_clock) then
 if r_CNT_1HZ = c_CNT_1HZ-1 then -- -1, since counter starts at 0
 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;
 
 -- Create a multiplexor 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;
 
 -- Only allow o_led_drive to drive when i_enable is high (and gate).
 o_led_drive <= w_LED_SELECT and i_enable;
end rtl;

Verilog-Implementierung

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;
 
 // Constants (parameters) to create the frequencies needed:
 // Input clock is 25 kHz, chosen arbitrarily.
 // Formula is: (25 kHz / 100 Hz * 50% duty cycle)
 // So for 100 Hz: 25,000 / 100 * 0.5 = 125
 parameter c_CNT_100HZ = 125;
 parameter c_CNT_50HZ = 250;
 parameter c_CNT_10HZ = 1250;
 parameter c_CNT_1HZ = 12500;
 // These signals will be the counters:
 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;
 
 // These signals will toggle at the frequencies needed:
 reg r_TOGGLE_100HZ = 1'b0;
 reg r_TOGGLE_50HZ = 1'b0;
 reg r_TOGGLE_10HZ = 1'b0;
 reg r_TOGGLE_1HZ = 1'b0;
 
 // One bit select
 reg r_LED_SELECT;
 wire w_LED_SELECT;
 

begin
 // All always blocks toggle a specific signal at a different frequency.
 // They all run continuously even if the switches are
 // not selecting their particular output.
 always @ (posedge i_clock)
 begin
 if (r_CNT_100HZ == c_CNT_100HZ-1) // -1, since counter starts at 0
 begin 
 r_TOGGLE_100HZ <= !r_TOGGLE_100HZ;
 r_CNT_100HZ <= 0;
 end
 else
 r_CNT_100HZ <= r_CNT_100HZ + 1;
 end
 
 always @ (posedge i_clock)
 begin
 if (r_CNT_50HZ == c_CNT_50HZ-1) // -1, since counter starts at 0
 begin 
 r_TOGGLE_50HZ <= !r_TOGGLE_50HZ;
 r_CNT_50HZ <= 0;
 end
 else
 r_CNT_50HZ <= r_CNT_50HZ + 1;
 end
 always @ (posedge i_clock)
 begin
 if (r_CNT_10HZ == c_CNT_10HZ-1) // -1, since counter starts at 0
 begin 
 r_TOGGLE_10HZ <= !r_TOGGLE_10HZ;
 r_CNT_10HZ <= 0;
 end
 else
 r_CNT_10HZ <= r_CNT_10HZ + 1;
 end
 
 always @ (posedge i_clock)
 begin
 if (r_CNT_1HZ == c_CNT_1HZ-1) // -1, since counter starts at 0
 begin 
 r_TOGGLE_1HZ <= !r_TOGGLE_1HZ;
 r_CNT_1HZ <= 0;
 end
 else
 r_CNT_1HZ <= r_CNT_1HZ + 1;
 end
 // Create a multiplexer based on switch inputs
 always @ (*)
 begin
 case () // Concatenation Operator 
 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
 assign o_led_drive = r_LED_SELECT & i_enable;
 // Alternative way to design multiplexer (same as above):
 // More compact, but harder to read, especially to those new to Verilog
 // assign w_LED_SELECT = i_switch_1 ? (i_switch_2 ? r_TOGGLE_1HZ : r_TOGGLE_10HZ) : 
 //(i_switch_2 ? r_TOGGLE_50HZ : r_TOGGLE_100HZ);
 // assign o_led_drive = w_LED_SELECT & i_enable;
 

end 

endmodule

Nächster Schritt:Simulieren Sie dieses Design in VHDL oder Verilog, um das korrekte Verhalten vor der Bereitstellung zu bestätigen.

VHDL

  1. Grundlegendes VHDL-Quiz – Teil 1
  2. Beispiele für VHDL-Konvertierungen
  3. So verknüpfen Sie Quartus Prime IP-Bibliotheken mit VUnit
  4. Einsteigerleitfaden zur Verwendung von Modelsim für die FPGA- und ASIC-Simulation
  5. Erste Schritte mit VUnit
  6. Variablen – VHDL-Beispiel
  7. So bauen Sie Ihren ersten FPGA-LED-Blinker:Eine Schritt-für-Schritt-Anleitung
  8. So verwenden Sie die Port Map-Instanziierung in VHDL
  9. So erstellen Sie einen getakteten Prozess in VHDL
  10. So erstellen Sie einen PWM-Controller in VHDL