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;
> 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?
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.
"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.
Wieso erhalte ich dann bei sowas wie:
std_logic_vector <= std_logic_vector + 1;
... folgende Fehlermeldung:
0 definitions of operator "+" match here.
???
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.
> 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:
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" ...
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
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);
[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
> 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
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