Forum: FPGA, VHDL & Co. Schleifen in Zustandsmaschinen


von Hans-Werner (Gast)


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;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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

von Hans-Werner (Gast)


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.

von Nephilim (Gast)


Lesenswert?

"Rechnen geht nur mit Bitvektoren oder Integern sei es signed oder
unsigned."

wo hastn das aufgegabelt ? natürlich kannst mit nem std_logic_vector 
rechnen.

von Jan M. (mueschel)


Lesenswert?

Hier steht alles, was man zu dem Thema wissen muss: Rechnen in VHDL 
- Es geht, aber man sollte es nicht tun.

von Hans-Werner (Gast)


Lesenswert?

Wieso erhalte ich dann bei sowas wie:
std_logic_vector <= std_logic_vector + 1;
... folgende Fehlermeldung:
0 definitions of operator "+" match here.
???

von Jan M. (mueschel)


Lesenswert?

Das kommt auf die benutzten Libraries an - schau mal in den Artikel im 
Wiki, da steht das erklaert.

von Hans-Werner (Gast)


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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> std_logic_vector(to_unsigned(to_integer(unsigned(address_key)) + 1,8));
Das sieht mir schon sehr nach numeric_std aus.

> ... folgende Fehlermeldung:
> 0 definitions of operator "+" match here.
Dann eben so:
1
   address_key <= address_key + '1';

von Hans-Werner (Gast)


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" ...

von Hans-Werner (Gast)


Lesenswert?

Nein, so auch nicht: address_key <= address_key + '1';
Vielleicht irgendwie, aber nicht mit numeric_std.

+ can not have such operands in this context.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mit unsigned als Typ ginge der Vergleich so:
> if (address_key <= 255) then...

Mit std_logic_vector mußt du wieder erst casten...:
> if (unsigned(address_key) <= 255) then...


Eine Zuweisung von 120 auf 8-Bit unsigned passiert z.B. so:
> address_key <= to_unsigned(120,8);

von Hans-Werner (Gast)


Lesenswert?

Ok, erst mal danke.
Ich glaube das hat was gebracht.

Happy Programming

von ope (Gast)


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> welche Bits von den 120 werden auf die 8 zugewiesen?
Einfach alle?
120 ist ein Integer, der wird in eine unsigend-Binärzahl umgewandelt und 
die unteren 8 Bits verwendet.

120 dez = 01111000 bin

von ope (Gast)


Lesenswert?

klaro, nach nochmaligen Grübeln - die Frage war quatsch, da ja keine 
variable übergeben wurde bzw. 120 diese repräsentiert (diese hatte ich 
fälschlicherweise erwartet/gelesen).

BTW: siehe auch
http://www.eda.org/comp.lang.vhdl/FAQ1.html#integer_bit_vector

Grüße
Olaf

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.