www.mikrocontroller.net

Forum: FPGA, VHDL & Co. State_Machine


Autor: VHDL-Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte in VHDL eine Finite-State-Machine programmieren.
Ich habe 4 Zustände, die die SM annehmen kann. Allerdings ist mir das
Prinzip noch nicht klar, wie man in VHDL gewährleistet, dass die FSM ab
Start im Zustand_1(z0) beginnt und nicht irgendwo anders.

Danke im Voraus!

library IEEE;
use IEEE.std_logic_1164.all;

ENTITY fsm_tst IS
    PORT( clk, Sin : IN std_logic;
          Zustand  : BUFFER std_logic_vector(1 downto 0);
          Sout     : OUT std_logic);
END fsm_tst;

ARCHITECTURE arch_fsm_tst OF fsm_tst IS
    CONSTANT z0 : std_logic_vector(1 downto 0) := "00";
    CONSTANT z1 : std_logic_vector(1 downto 0) := "01";
    CONSTANT z2 : std_logic_vector(1 downto 0) := "10";
BEGIN
    Zustandsfolge : PROCESS( clk )
    BEGIN
      IF( clk'EVENT AND clk = '1' ) then
        CASE Zustand IS
          WHEN z0 =>
            IF Sin = '1' THEN
              Zustand <= z1;
            ELSE
              Zustand <= z0;
            END IF;
          WHEN z1 =>
            Zustand <= z2;
          WHEN z2 =>
            Zustand <= z0;
          WHEN OTHERS =>       -- Dummy-Zustand
            Zustand <= z0;
        END CASE;
      END IF;
    END PROCESS;

    Ausgaenge : PROCESS( Zustand, Sin )
    BEGIN
        CASE Zustand IS
          WHEN z0 =>
            Sout <= '0';
          WHEN z1 =>
            Sout <= '1';
          WHEN z2 =>
            Sout <= Sin;
          WHEN OTHERS =>
            Sout <= '0';
        END CASE;
    END PROCESS;
END arch_fsm_tst;

Autor: Klaus Falser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dazu gibt's mehrere Möglichkeiten.
- Du verwendest ein RESET Signal welches den Zustand z0 erzwingt.
Dies funktioniert immer und Simulation und HW stimmen garantiert
überein.
- Du verwendest einen Initialisierungswert.
Dazu ist es besser, wenn Dein Zustandsvektor ein internes Signal ist,
und nicht ein BUFFER-Signal deiner Entity.
ENTITY fsm_tst IS
    PORT( clk, Sin : IN std_logic;
          Zustand  : OUT std_logic_vector(1 downto 0);
          Sout     : OUT std_logic);
END fsm_tst;

ARCHITECTURE arch_fsm_tst OF fsm_tst IS
    CONSTANT z0 : std_logic_vector(1 downto 0) := "00";
    CONSTANT z1 : std_logic_vector(1 downto 0) := "01";
    CONSTANT z2 : std_logic_vector(1 downto 0) := "10";

    signal   Z  : std_logic_vector(1 downto 0) := z0;

BEGIN
    Zustandsfolge : PROCESS( clk )
    BEGIN
      IF rising_edge(clk) then
        CASE Zustand IS
...
    END PROCESS;

    Zustand <= Z;
END 

Das Problem dabei ist, daß ältere Compiler nicht imstande sind, den
Initialisierungswert in HW umzusetzen.
Wenn Du aber z.B. Xilinx Webpack/ISE ab Version 7.1 verwendest, dann
sollte es klappen.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine schöne Methode für die Zustandsdeklaration.
architecture beh1 of fsm is
 type state_type is (s1,s2,s3,s4);
 signal state: state_type;
begin
process1: process (clk, reset)
begin
 if (reset =&#8217;1&#8217;) then
    state <= s1;
 elsif (clk=&#8217;1&#8217; and clk&#8217;Event) then
    case state is
     when s1 =>
       if x1=&#8217;1&#8217; then
       state <= s2;
       else .....

und nie das when others vergessen....

Sebastian

Autor: VHDL-Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Klaus Felser

-ARCHITECTURE arch_fsm_tst OF fsm_tst IS
-CONSTANT z0 : std_logic_vector(1 downto 0) := "00";
-CONSTANT z1 : std_logic_vector(1 downto 0) := "01";
-CONSTANT z2 : std_logic_vector(1 downto 0) := "10";
-signal   Z  : std_logic_vector(1 downto 0) := z0;

-BEGIN
-Zustandsfolge : PROCESS( clk )

1:
Das Signal Z wird in Architekture initialisiert. Bedeutet dies, dass
VHDL diesen Teil des Moduls nur 1x durchläuft, und nicht unendlich oft,
wie es bei anderen Teilen des Programmes der Fall ist?
Als Bsp: Jeder Prozess wird so oft gestartet, so oft der Prozess
aufgerufen wird.

2:

-Das Problem dabei ist, daß ältere Compiler nicht imstande sind, den
-Initialisierungswert in HW umzusetzen.
-Wenn Du aber z.B. Xilinx Webpack/ISE ab Version 7.1 verwendest, dann
-sollte es klappen.

Kann ich mit Quartus 5.1 sicher sein, dass der Initialisierunswert in
HW umgesetzt wird?

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1) Im Prinzip ja. Z wird mit 1 x mit z0 initialisiert.
2) Weiss ich leider nicht, ich habe mit Altera noch nie gearbeitet.
Vielleicht weiss es jemand anderer.
Man kann zwar z0 als "00" wählen, wie Du es gemacht hast und sich
drauf verlassen, daß alle FF mit '0' aufwachen.
Falls aber der Compiler oder Fitter deine Gleichungen optimiert und ein
Bit deines Zustandsvektors invertiert, weil es günstiger zum
Implementieren ist, dann wacht deine FSM mit dem falschen Startwert
auf.
Dies ist zwar unwahrscheinlich, könnte aber passieren.

Autor: VHDL-Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für diese Infos!

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Kann ich mit Quartus 5.1 sicher sein, dass der Initialisierunswert in
>HW umgesetzt wird?

Kurz und knapp: Ja

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

die oben gezeigte Zwei-Prozess Dartsellung einer FSM läßt sich auch in
eine Ein-Prozess-Darstellung vereinfachen, zudem läßt sich über die
Typendeklaration eine FSM (Typ Moore) inklu Zuständen deklarieren.
Desweiteren wird das Eingangssignal auf den Systemtakt "clk"
eingesampelt (Synchronisierung)
ENTITY FSM_example IS
   PORT ( clk    : std_logic;
          reset  : std_logic;
          input  : std_logic_vector(1 DOWNTO 0);
          output : std_logic_vector(3 DOWNTO 0);
        );
END FSM_example;


ARCHITECTURE FSM_beh OF FSM_example IS

TYPE FSM_1 IS (State_1, State_2, State_3);
SIGNAL State_FSM : FSM_1 := State_1;
.
SIGNAL input_q   : std_logic;
.

One_Procss_Discription : PROCESS(clk,reset)
 IF reset = '1' THEN
   input_q           <= '0';             -- Reset-Initialisierung
   output            <= (OTHERS => '0'); --           "
   State_FSM         <= State_1;         --           " ,
Startzustand
 ELSIF rising_edge(clk) THEN
   input_q           <= input;           -- Einsampeln des
Eingangssignal auf Systemtakt "clk"
   CASE FSM_1 IS
     WHEN State_1 =>
       IF input_q = '1' THEN    -- Startwert der FSM vom Typ Moore
          output     <= "1000"; 
          State_FSM  <= State_2;
       END IF;
   
     WHEN State_2 =>
       output       <= "0110";
       State_FSM    <= State_3;

     WHEN State_3 =>
       output       <= "1111";
       State_FSM    <= State_1;

     WHEN OTHERS =>                     -- alle irregulären Zustände
       output       <= "0000";          -- werden mit mit
Reset-Values
       State_FSM    <= State_1;         -- initialisiert, d.h.
"Aufhängen" der FSM wird vermieden
 
   END CASE FSM_1; 
  END IF;
 END PROCESS;
END FSM_beh;


Habe die FSM mal auf die Schnelle eingehackt....hoffe, es haben sich
keine Fehler eingeschlichen.

Die Ein-Prozess-Darstellung erreicht die beste Simulationseffizienz und
da die Übergangs- und Ausgangsschaltnetze in dem getakteten Prozess
integriert sind, werden für alle im Prozess verwendeten Signale D-FF
durch das Synthesetool D-FF generiert.

Gruß
Tom

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry,

Zeilen 23,26,44,46 gehören zu den vorherigen Kommentaren....

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch ein Fehler gefunden....
So ist richtig
ENTITY FSM_example IS
    PORT ( clk    : IN std_logic;
           reset  : IN std_logic;
           input  : IN std_logic_vector(1 DOWNTO 0);
           output : OUT std_logic_vector(3 DOWNTO 0);
         );
END FSM_example;


Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.