www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Schleifen in Zustandsmaschinen


Autor: Hans-Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?
  -- 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
Lass doch die dauernde Rumcasterei, und schreib:
  -- Initialisierung
  address_key <= (others => '0');
  -- Inkrementierung
  address_key <= address_key + 1;
  -- If-Abfrage
  if address_key = x"FF" ...


Falls das
  -- Initialisierung
  address_key <= (others => '0');
  -- Inkrementierung
  address_key <= address_key + 1;
  -- If-Abfrage
  if address_key = x"FF" ...
Teil eines getakteten Prozesses ist, dann ist die Zeile
  -- Initialisierung
  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

Autor: Hans-Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Nephilim (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jan M. (mueschel)
Datum:

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

Autor: Hans-Werner (Gast)
Datum:

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

Autor: Jan M. (mueschel)
Datum:

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

Autor: Hans-Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
   address_key <= address_key + '1';

Autor: Hans-Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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" ...

Autor: Hans-Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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);

Autor: Hans-Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, erst mal danke.
Ich glaube das hat was gebracht.

Happy Programming

Autor: ope (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: ope (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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#intege...

Grüße
Olaf

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.