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

In-Prozess-Prozeduren für saubere VHDL-FSM-Entwürfe nutzen

In VHDL kann eine Prozedur externe Signale treiben, solange diese in ihrem Gültigkeitsbereich liegen. Eine im Architekturkörper deklarierte Prozedur hat keinen Zugriff auf externe Signale (zur Compile-Zeit nicht sichtbar), aber eine innerhalb eines Prozesses definierte Prozedur kann alle Signale lesen und schreiben, die der Prozess sieht.

In-Prozess-Prozeduren eignen sich hervorragend, um wiederkehrende Logik in Zustandsautomaten oder komplexen Protokollen zu kapseln. Durch Einkapselung gemeinsamer Aktionen – z. B. eines zeitgesteuerten Zustandsübergangs – reduzieren Sie Boilerplate-Code, verbessern Lesbarkeit und machen die Absicht jedes Schritts deutlich.

Beispiel: In einem Ampelsteuerung-Controller wird ChangeState(ToState, Minutes, Seconds) aufgerufen – der Leser erkennt sofort die Aktion, ohne Variablenzuweisungen zu analysieren.

Praxisbeispiel

In einem früheren Tutorial nutzten wir eine impure function, um einen Counter zu steuern und Zustandswechsel zu bestimmen. Die State-Zuweisung konnte nicht in die Funktion verlagert werden, da Funktionen immer einen Rückgabewert benötigen. Eine Prozedur – ohne Rückgabewert – passt perfekt.

Unten folgt der vollständige Testbench und das Modul für eine Ampel-FSM, getrieben von einer In-Prozess-Prozedur.

Testbench

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T23_ProcedureInProcessTb is
end entity;

architecture sim of T23_ProcedureInProcessTb is
  constant ClockFrequencyHz : integer := 100; -- 100 Hz
  constant ClockPeriod : time := 1000 ms / ClockFrequencyHz;
  signal Clk : std_logic := '1';
  signal nRst : std_logic := '0';
  signal NorthRed : std_logic;
  signal NorthYellow : std_logic;
  signal NorthGreen : std_logic;
  signal WestRed : std_logic;
  signal WestYellow : std_logic;
  signal WestGreen : std_logic;
begin
  i_TrafficLights : entity work.T23_TrafficLights(rtl)
    generic map(ClockFrequencyHz => ClockFrequencyHz)
    port map (
      Clk => Clk, nRst => nRst,
      NorthRed => NorthRed, NorthYellow => NorthYellow, NorthGreen => NorthGreen,
      WestRed => WestRed, WestYellow => WestYellow, WestGreen => WestGreen
    );

  Clk <= not Clk after ClockPeriod / 2;

  process is
  begin
    wait until rising_edge(Clk);
    wait until rising_edge(Clk);
    nRst <= '1';
    wait;
  end process;
end architecture;

Ampel-Modul

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T23_TrafficLights is
  generic(ClockFrequencyHz : integer);
  port(
    Clk : in std_logic;
    nRst : in std_logic;
    NorthRed : out std_logic;
    NorthYellow : out std_logic;
    NorthGreen : out std_logic;
    WestRed : out std_logic;
    WestYellow : out std_logic;
    WestGreen : out std_logic
  );
end entity;

architecture rtl of T23_TrafficLights is
  type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest);
  signal State : t_State;
  signal Counter : integer range 0 to ClockFrequencyHz * 60;

  process(Clk) is
    procedure ChangeState(ToState : t_State; Minutes : integer := 0; Seconds : integer := 0) is
      variable TotalSeconds : integer;
      variable ClockCycles : integer;
    begin
      TotalSeconds := Seconds + Minutes * 60;
      ClockCycles := TotalSeconds * ClockFrequencyHz - 1;
      if Counter = ClockCycles then
        Counter <= 0;
        State <= ToState;
      end if;
    end procedure;
  begin
    if rising_edge(Clk) then
      if nRst = '0' then
        State <= NorthNext;
        Counter <= 0;
        NorthRed <= '1'; NorthYellow <= '0'; NorthGreen <= '0';
        WestRed <= '1'; WestYellow <= '0'; WestGreen <= '0';
      else
        NorthRed <= '0'; NorthYellow <= '0'; NorthGreen <= '0';
        WestRed <= '0'; WestYellow <= '0'; WestGreen <= '0';
        Counter <= Counter + 1;
        case State is
          when NorthNext =>
            NorthRed <= '1'; WestRed <= '1';
            ChangeState(StartNorth, Seconds => 5);
          when StartNorth =>
            NorthRed <= '1'; NorthYellow <= '1'; WestRed <= '1';
            ChangeState(North, Seconds => 5);
          when North =>
            NorthGreen <= '1'; WestRed <= '1';
            ChangeState(StopNorth, Minutes => 1);
          when StopNorth =>
            NorthYellow <= '1'; WestRed <= '1';
            ChangeState(WestNext, Seconds => 5);
          when WestNext =>
            NorthRed <= '1'; WestRed <= '1';
            ChangeState(StartWest, Seconds => 5);
          when StartWest =>
            NorthRed <= '1'; WestRed <= '1'; WestYellow <= '1';
            ChangeState(West, Seconds => 5);
          when West =>
            NorthRed <= '1'; WestGreen <= '1';
            ChangeState(StopWest, Minutes => 1);
          when StopWest =>
            NorthRed <= '1'; WestYellow <= '1';
            ChangeState(NorthNext, Seconds => 5);
        end case;
      end if;
    end if;
  end process;
end architecture;

Wellenform

Die Simulation verhält sich identisch zum ursprünglichen FSM – nur der Code ist wartbarer und verständlicher.

Analyse

Durch Auslagern der Timing- und Zustandswechsel-Logik in eine einzige Prozedur bleibt das Verhalten erhalten, während die Lesbarkeit drastisch steigt. Die Prozedur garantiert konsistente Implementierung an allen Aufrufstellen.

Kernpunkte

VHDL

  1. Einführung in VHDL: Ihr erstes AND-Gate bauen
  2. VHDL Procedure Beispiel: Inkrementieren eines Standard Logic Vectors
  3. Wie Molybdän die moderne Industrie formt: Nutzung, Vorteile und Versorgungsdynamik
  4. String-Listen in VHDL erstellen: Best Practices & Beispiel
  5. Impure Functions in VHDL nutzen: FSM-Lesbarkeit und Wartbarkeit steigern
  6. VHDL-Funktionen meistern: Praktischer Leitfaden für effizientes Design
  7. Prozeduren in VHDL: Wiederverwendbaren Code für einfachere Designs
  8. Zuverlässigen Timer in VHDL bauen: Taktzyklen bis Stunden zählen
  9. Getakteten Prozess in VHDL erstellen: Praktischer Leitfaden
  10. Schleiftechniken für Werkzeugschleifmaschinen meistern: Praktischer Leitfaden