Schleifen in Zustandsmaschinen

Gast #1116263
Lesenswert?
• ▲
▼
Wie sieht korrekterweise eine For, While oder Repeat-Schleife in einem 
Zustandsautomat aus ?
Benutze ich in nachfolgenden Ausschnitt die Variable n, ist der Ablauf 
korrekt. Versuche ich es jedoch ohne Variable und verwende die 
Anweisungen
die ich unten auskommentiert habe, dann wird die If-Abfrage im Zustand 
"one" nie ausgeführt.
Benötige ich einen zusätzlichen Zustand für die If-Abfrage ?

  -- Initialisierung
  address_key <= (others => '0');
  -- Inkrementierung
  address_key <= 
std_logic_vector(to_unsigned(to_integer(unsigned(address_key)) + 1,8));
  -- If-Abfrage
  if to_integer(unsigned(address_key)) = 255



case load_key_state is
  when zero => -- Vorgang nicht abgeschlossen
        done <= '0';
        -- Schreiberlaubnis erteilen
        write_enable_key <= '1';
        -- n initialisieren
        n := 0;
        -- Adresse und Daten zuweisen
        -- address_key <= (others => '0');
        address_key <= std_logic_vector(to_unsigned(n,8));
        data_in_key <= key_in;
        load_key_state <= one;

  when one =>  -- Adresse inkrementieren
        n := n + 1;
        address_key <= std_logic_vector(to_unsigned(n,8));
        -- address_key <= 
std_logic_vector(to_unsigned(to_integer(unsigned(address_key)) + 1,8));
        -- Daten zuweisen
        data_in_key <= key_in;
        -- if to_integer(unsigned(address_key)) = 255
        if n = 255
        then
    -- Schreiberlaubnis entziehen
    write_enable_key <= '0';
           -- Vorgang abgeschlossen
    done <= '1';
    -- Ende
    load_key_state <= two;
        end if;

  when two =>  null;
end case;
Moderator (Firma: Titel) Persönliche Seite #1116296
Lesenswert?
• ▲
▼
> Wie sieht eine For, While ... -Schleife in einem Zustandsautomat aus ?
Einfach so, dass der Zustand nicht weitergeschaltet wird, solange noch 
zu warten ist. So wie du es beschrieben hast, stimmt es grundlegend. 
allerdings kommst du nicht mehr aus deinem Zustand two heraus.

Du hast keine Angst, den Überblick zu verlieren?
1
  -- Initialisierung
2
  address_key <= (others => '0');
3
  -- Inkrementierung
4
  address_key <= std_logic_vector(to_unsigned(to_integer(unsigned(address_key)) + 1,8));
5
  -- If-Abfrage
6
  if to_integer(unsigned(address_key)) = 255
Lass doch die dauernde Rumcasterei, und schreib:
1
  -- Initialisierung
2
  address_key <= (others => '0');
3
  -- Inkrementierung
4
  address_key <= address_key + 1;
5
  -- If-Abfrage
6
  if address_key = x"FF" ...


Falls das
1
  -- Initialisierung
2
  address_key <= (others => '0');
3
  -- Inkrementierung
4
  address_key <= address_key + 1;
5
  -- If-Abfrage
6
  if address_key = x"FF" ...
Teil eines getakteten Prozesses ist, dann ist die Zeile
1
  -- Initialisierung
2
  address_key <= (others => '0');
unnötig. Denn in eimen Prozess gilt die letzte Signalzuweisung.

BTW:
mit den Tags [/vhdl] und [vhdl] wird hier im Forum VHDL formatiert
Gast #1116324
Lesenswert?
• ▲
▼
Einen std_logic_vector kann ich doch nicht einfach inkrementieren !? 
Rechnen geht nur mit Bitvektoren oder Integern sei es signed oder 
unsigned.
address_key <= address_key + 1;
Wenn ich eine Adresse inkrementiere muß ich sie doch zuvor auf einen 
Startwert (hier 0) setzen.
Was hat jetzt die letzte Signalzuweisung mit der ersten bzw. der 
Initialisierung zu tun ?
"Denn in eimen Prozess gilt die letzte Signalzuweisung."
Das ein Signal seinen Wert nicht von selbst verändert und daher die 
letzte Signalzuweisung gilt, ist wohl logisch. Die gleiche Weisheit gilt 
aber auch für Variablen. Die Verändern auch nicht selbstständig ihren 
Wert.
Gast #1116389
Lesenswert?
• ▲
▼
Siehe "Rechnen in VHDL"

Die von vielen Synthesetools unterstützten, aber nicht 
IEEE-standardisierten Packages std_logic_unsigned und std_logic_signed 
erlauben es, direkt mit std_logic_vector zu rechnen. Je nachdem ob das 
signed oder unsigned-Package eingebunden wird werden alle (!) 
Berechnungen als signed oder unsigned interpretiert - das ist natürlich 
unsauber. Trotzdem werden diese Packages noch häufig verwendet, obwohl 
es mit numeric_std gar nicht mehr nötig ist.

[bearbeiten] Besser: Rechnen mit numeric_std
Das Package numeric_std definiert zwei neue Typen signed und unsigned 
als Array von std_logic, und definiert für diese Typen alle 
gebräuchlichen Rechenoperatoren, auch zusammen mit Integern (x + 1):

Siehe vorherigen Absatz "Array von std_logic" nicht std_logic_vector.
Das sind zwei paar Schuhe.
Gast #1116735
Lesenswert?
• ▲
▼
Wie sieht denn dann ein kleiner-gleich Vergleich aus ?

Vielleicht so:     ... address_key <= 255 ...
oder so:           ... address_key <= "255" ...
oder so:           ... address_key <= 10#255 ...
oder so:           ... address_key <= "10#255" ...
Moderator (Firma: Titel) Persönliche Seite #1116899
Lesenswert?
• ▲
▼
Also ich sehe schon, dein address_key ist std_logic_vector, oder?
Machs mit der numeric_std so, dass nur die Schnittstellen-Signale der 
Entity als std_logic_vector definiert sind. Alle lokalen Signale dagenen 
als unsigned() oder signed(), dann gehts (einfacher).

Mit std_logic_vector mußt du es so machen:
cast nach unsigned,
dann Addition von 1,
dann zurückcasten auf std_logic_vector
1
address_key <= std_logic_vector(unsigned(address_key) + 1));

Du solltest dich mit den drei (bzw. 4) Vektor-tapen der numeric_std 
nochmal genauer beschäftigen:
std_logic_vector, unsigned, signed und integer
Gast #1117109
Lesenswert?
• ▲
▼
[cite]
Eine Zuweisung von 120 auf 8-Bit unsigned passiert z.B. so:
> address_key <= to_unsigned(120,8);
[/cite]

welche Bits von den 120 werden auf die 8 zugewiesen? MSB, LSB oder 
sonstiges? Aus der FAQ comp.lang.vhdl habe ich mal so eben schnell auch 
keine Antwort gefunden.

Grüße
Olaf

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren