Forum: FPGA, VHDL & Co. VHDL: Variable in Prozesse


von Holger (Gast)


Lesenswert?

Hallo,

einer Variablen wird innerhalb eines Prozesses ein Wert zugewiesen.
Bleibt der Wert der Variablen nach Beendigung des Prozesses bzw. bei
Wiedereintritt in den Prozes erhalten ?

von TobiFlex (Gast)


Lesenswert?

Wie? Prozess beenden? Du redest aber von VHDL?

In einer Programmiersprache kannst Du Prozeduren aufrufen und beenden.
In einem Hardwaredesign passiert alles gleichzeitig.
Bitte umdenken!
Da der Prozess ständig läuft sind auch die Variablen ständig gültig.
Viele Grüße
TobiFlex

von Holger (Gast)


Lesenswert?

OK, vielleicht schlecht ausgedrückt. Ich meine VHDL.

Ich habe einen getakteten Prozess. Innerhalb des Prozesses weise ich
einer Variablen einen Wert zu. Die Befehle innerhalb des Prozesses
werden sequentiell abgearbeitet bis zum Ende des Prozeses. Bei erneuter
positiver Taktflanke beginnt der Prozess von vorne (so funktionieren
Prozesse doch ???). Ist der Wert der Variablen nun noch vorhanden ????

von Unbekannter (Gast)


Lesenswert?

Ja ist er. Die Hardware, die durch die Variable generiert wird, wird ja
nicht resettet nur weil dein Process gerade inaktiv ist.
Was man aber beachten muss: Variablen sind immer nur im jeweiligen
Process gültig. Man kann also in zwei verschiedenen Processen nicht auf
die gleiche Variable zugreifen. Das geht nur über den Umweg eines
Signals zum Datenaustausch.

von TobiFlex (Gast)


Lesenswert?

Hier ein paar aufschlußreiche Links:
http://www.vhdl-online.de/tutorial/deutsch/t_105.htm#pgfId-1019766
http://www.vhdl-online.de/tutorial/deutsch/t_106.htm#pgfId-1019829
http://www.vhdl-online.de/tutorial/deutsch/t_108.htm#pgfId-1019956
http://www.vhdl-online.de/tutorial/deutsch/t_107.htm#pgfId-1019905

Im letzten steht:
"Variablen werden zur Ausführung von Algorithmen verwendet. Dabei
erhält eine Variable ihren Wert von einem Signal. mit der Variablen
wird dann der Algorithmus durchgeführt und anschließend das Ergebnis
wieder einem Signal zugewiesen. Variablen sind nur innerhalb ihres
Prozesses bekannt. Sie besitzen beim nächsten Prozeßaufruf ihren alten
Wert. Wird eine Variable gelesen, bevor ihr ein Wert zugewiesen wurde,
so muß diese Variabel speicherndes Verhalten zeigen, d.h. sie wird zu
einem Latch bzw. einem Flip-Flop synthetisiert."

Mich wundert etwas, daß hier auch vom "nächsten Prozeßaufruf"
gesprochen wird???  Müßte es nicht ander heißen???

Viele Grüße
TobiFlex

von Tom (Gast)


Lesenswert?

@TobiFlex:


Soweit ich die Prozess-Syntax verstanden habe, können mehrere Prozesse
gleichzeitig laufen (wie Du oben schon angemerkt hast, dass in der HW
alles gleichzeitig geschieht), aber ein Prozess selber wird entweder
durch Änderung eines Signals innerhalb der Prozess Senbsitivitätsliste
gestartet, oder wenn diese Liste nicht vorhanden ist, stetig
durchlaufen und mit der "wait for xys s" eine Auszeit generiert....

von Sven Johannes (Gast)


Lesenswert?

Moin...

Vorsicht mit Variablen! Da werden gant fix Latches eingebaut und bei
der Verifikation geht der Spass richtig los => fast unmöglich! Signale
können mit Constraints belegt werden, die Kontrolle geht schon bei der
Synthese los.

--
 Sven Johannes

von Tom (Gast)


Lesenswert?

@Sven

Ich habe verschiedene Algorithmen in VHDL programmiert und simuliert.
Die Synthese meckerte auf ein paar Latches nix besonderes an.

Die Latches kommen auch nur deshalb zustande, da ich bei den
Alogrithmen verschiedene Bitweiten von Datenframes brauche, einen
seriellen Datenstrom aber mit einer fixen Bitweite einlese....

Da ich irgendwo gelesen habe, dass Variablen eben schneller und besser
für einen Algorithmus zur Berechnung von irgendwas eingesetzt werden,
macht mich Deine Aussage respektive Variablen nun stutzig...?!?

von Tom (Gast)


Lesenswert?

Hallo zusammen,

ich habe in meinem Design für Berechnungen von bestimmten Algorithmen
Varablen eingesetzt, die ich später wieder Signalen zuweise (im selben
State).

Nach der Synthese und der Verifikation auf dem Board kommen leider
Bitfehler. Ich habe irgendwo anders hier gelesen, das Variablen nach
der Synthese ans Ende des aufgeführten Codeschnipsels gesetzt werden.

Ist das generell nach der Synthese so?!?

Wenn ja, dann muss ich leider mein Design umstricken.... würg

Gruß
Tom

von ope (Gast)


Lesenswert?

die Erfahrung, das Simu und Synthese vollkommen andere Ergebnisse
liefern, bin ich auch gerade dabei zu machen ;-)

Hier aber die für Dich interessante Antwort:
http://www.mikrocontroller.net/forum/read-9-289356.html#289461

Viele Grüße
Olaf

von Tom (Gast)


Lesenswert?

Hallo Olaf,

jepp, genau diesen Beitrag vom FPGA-User meinte ich.
Ich habe Kompression-Algorithmen mit Variablen geschrieben.
D.h., in einem State werden die Variablen mit den entsprechenden
Signale initialisiert, der Algorithmus mit den Variablen ausgeführt,
und danach die Variablen wieder Signalen zugewiesen.
Da ich gelesen habe, dass Variablen zur Algo-Berechnung sehr tauglich
sind, habe ich nun aber nach der Synthese das Problem, dass ich
Bitfehler generiert bekomme....

Nun ist die Frage, ob die Aussgae vom FPGA-User generell nach der
Synthese respektive der Variablen zutrifft. Denn dann müßte ich das
design komplett umstricken.... :-((

Gruß
Tom

von FPGAküchle (Gast)


Lesenswert?

Da ich irgendwo gelesen habe, dass Variablen eben schneller und besser
für einen Algorithmus zur Berechnung von irgendwas eingesetzt werden,
macht mich Deine Aussage respektive Variablen nun stutzig...?!?

Variablen sind in der -Simulation- schneller, aber nicht in der
Hardware.

von Tom (Gast)


Lesenswert?

@FPGAküchle:

wie war das nochmal (in einem anderen Beitrag) mit den
Lichtblicken...?!? ;-)

Groschen ist gefallen, Design muss umgestrickt werden, HW bleibt eben
HW.... :-))

Gruß
Tom

von Klaus F. (kfalser)


Lesenswert?

Variablen erzeugen bei Synthese keine unterschiedlichen Ergebnisse als
bei der Simulation !!!!

Variablen verhalten sich nur anders als Signale. Sie ähneln den
Variablen einer "normalen" Programmiersprache und sie eignen sich
besser für Berechnungen als Signale.

Bei Variablen zählen alle Zuweisungen:

count := count + 2;
count := count + 1;

erhöht die Variable count um 3.

Bei Signalen zählt nur die LETZTE Zuweisung for dem wait, außerdem wird
immer mit dem ALTEN Wert des Signals gerechnet.

count <= count + 2;
count <= count + 1;

erhöht count nur um 1.
Die Erhöhung von count um 2 wird überschrieben, und bei der Berechnung
von "count + 1" wird noch der alte (aktuelle) Wert von count
verwendet.

Klaus

von FPGA-User (Gast)


Lesenswert?

Hallo Tom,

damit da nichts total durcheinanderkommt :
Variablen in VHDL sind nichts schlimmes, man muss nur
ein paar Dinge beachten :

- wenn ich den Wert der Variablen abfrage, bevor ich ihr
einen Wert zuweise (bezüglich der Reihenfolge, in der
ich die Codezeilen in meinem Editor schreibe), dann wird
ein zusätzliches Register eingefügt

- weise ich zuerst einen Wert zu und frage dann ab, dann
kommt nur Kombinatorik dabei raus, also z.B. ein Addierer

- die Position wo Variablen-Zuweisungen stehen können die
Implementierung beeinflussen. In meinem Bsp. (s. Link oben)
war zwischen Register und Ausgang einmal ein Addierer und
ein Komparator in Reihe, beim anderen mal nur der Komparator.

Wenn Simulation und Hardware nicht dasselbe Ergebnis liefern,
dann liegt es meist an Timing-Problemen oder daran, dass man
in der Hardware andere Bedingungen hat als in der Simulation
(z.B. fehlerhafte oder nicht simulierte Input-Signale usw.)

Obwohl ich seit einigen Jahren VHDL schreibe, verwende ich fast
nur folgende Variante (Bsp.:), die ich auch jedem VHDL-Anfänger
bzw. Nicht-Profi empfehlen würde:

process(clk)
   variable flag : boolean;
begin
   if rising_edge(clk) then
      flag := false; -- hier gleich als erste Zeile einen Wert zuw.
      ...
      if counter = 0 then
         flag := true;
         ...

Damit ist immer sichergestellt, dass "flag" rein kombinatorisch aus
dem Signal "counter" abgeleitet wird. Alles, wo nach der Synthese
Register draus werden sollen sind bei mir generell Signale.
Das ist nur ein Tip von mir, kein MUSS, aber ich bin damit immer
gut gefahren und hatte bisher nie Probleme mit Variablen.

von Tom (Gast)


Lesenswert?

Hallo Klaus,

Deine Aussage "Variablen erzeugen bei Synthese keine unterschiedlichen
Ergebnisse als
bei der Simulation !!!!" habe ich auch für bare Münze genommen..

In meinem Algorithmus werden bei ansteigender Taktflanke in einem State
Signalfragmente mehreren Variablen zugeordnet, die imselben State und
mit derselben ansteigenden Taktflanke Berechnungen vornehmen sollen. In
der Simu sahs sehr gut aus (ist ja auch klar, da Signale erst nach dem
"Durchlauf" des States die jeweiligen Zuweisungen erhalten), nur kann
es in HW doch nicht funktionieren, denn schliesslich Frage ich bei ein
und demselben Takt ein Register ab, das aber gerade just imselben
Moment zugewiesen wird...

Kann eigentlich nicht funktioníeren...

Gruß
Tom

von Tom (Gast)


Lesenswert?

Hallo FPGA-User,

vielen Dank Deiner Tipps....

Werde mal über meinen Code gehen und etwas umstricken müssen....

Gruß
Tom

von Klaus F. (kfalser)


Lesenswert?

Hallo Tom,
ich weiss nicht, ob ich dich richtig verstanden habe, aber ein Signal
zu lesen und es gleichzeitig zuzuweisen, ist absolut korrekt und
erzeugt keine Probleme.
Sonst würde ja ein Zähler auch nicht funktionieren
1
process(clk)
2
begin 
3
   if rising_edge(clk) then 
4
       count <= count + 1;
5
    end if;
6
end process;

Du darfst also ohne weiteres auch schreiben (count ist ein Signal vom
Typ integer, Overflow-Behandlung dazudenken)
1
process(clk)
2
   variable v : integer; 
3
begin 
4
   if rising_edge(clk) then 
5
       v := count;
6
       v := v + 1;
7
       count <= v;
8
    end if;
9
end process;

Klaus

von Tom (Gast)


Lesenswert?

Hallo Klaus,

hmm, wie sieht mit folgenden Zeilen aus:

.
.
process(clk)
 variable Temp_Data : std_logic;
 variable Temp_Reg : std_logic_vector(3 downto 0);
 variable X : integer range 0 to 3 := '0';
begin

 when State_2 =>
 if rising_edge(clk) then
  X := '0';
  Temp_Reg := Data_input(3 downto 0);
  for I in 3 downto 0 loop
   if Temp_Reg(I) = '1' then
    X := X+1
    exit;
   end if;
  end loop;
  Count_out <= X;
 end case SM;

Ich weise Temp_Data das Register Data_Input zu, und frage direkt im
Anschluss in der For-Schleife nach den '1'sen ab, um diesen Wert dann
einen Ausgangscounter zuzuweisen. Ist dieses also so möglich?!?

Gruß
Tom

von Tom (Gast)


Lesenswert?

...fehlt noch der Rücksprung in einen Folgezustand oder in den
Ausgangszustand...

von Klaus F. (kfalser)


Lesenswert?

Ich sehe da 2 Probleme.
Erstens sollte die if rising_egde() schleife die äußerste Schleife
sein, die State Machine kommt nach innen. Mich wundert, daß der
Compiler für die Synthese das überhaupt akzeptiert hat.
Zweitens muß der Compiler bei der Synthese deinen Loop aufrollen und
wird 4 2-Bit Adder hintereinander schalten.
Dies ergibt sicher eine langsame Hardware, aber umsetzen kann der
Compiler es korrekt.
Du solltest eine case Anweisung mit 16 Möglichkeiten verwenden

case Data_input(3 downto 0) is
when "0000" => Count_out <= 0;
when "0001" => Count_out <= 1;
...
end case

Grüße
Klaus

von Steff (Gast)


Lesenswert?

Wird der oben gezeigte Zustand eigentlich nur einmal durchlaufen mit der
anst.Clock, wenn hinter der Countanweisung der Folgezustand kommt?

von Tom (Gast)


Lesenswert?

Hallo Klaus,

in meinen Algorithmen scanne ich einen Datenvektor nach der ersten
logischen '1' ab. Dieses kann ich nicht über Tables machen, denn es
werden noch weitere Fragmente des Datenvektors verarbeitet.
Was macht denn die Synthese aus einem Datenvektor, dessen ersten 8
Bitstellen nach einer '1' abgescannt wird?!?

Gruß
Tom

von Thommy (Gast)


Lesenswert?

Hallo,

ich hab noch ne Frage zu speichernden Elementen, wie kann ich große
Datenmengen am besten speichern (angenommen ich habe genug Platz auf
dem FPGA d.h. viele Register)?
Ist es am besten einen Array zu verwenden oder kann ich es auch mit
Signalen realisiert?

Hintergrund:
Es sollen Daten von einem langsamen EEPROM in einen FPGA übernommen
verarbeitet und schnell an einen Video-DAC ausgegeben werden.

Danke fürn nen Tipp!
Einen guten Abend,
Thommy

von Klaus F. (kfalser)


Lesenswert?

Hallo Leute,
ich glaube, an diesem Punkt kann ich nur mehr sagen:

BITTE, BITTE, BITTE, lest doch einmal ein Buch über digitale Hardware,
damit ihr wisst, was die Grundelemente der Hardware sind (damit ihr
wisst, wovon ihr redet).

Dann gibt bei Xilinx (sucht nach XST) und sicher auch bei Altera
Tutorials, wie man den Compiler für das FPGA dazu bringt, bestimmte
Elemente aus VHDL beschreibungen zu generieren. Besorgt euch
meinetwegen Xilinx Webpack, damit könnt ihr euch sogar darstellen
lassen, was der Compiler generiert.

@Tom
Dein Kode scannt nicht den Datenvektor nach Einsen ab, sondern zählt
diese. So wie Du den Kode geschrieben hast, hast Du 4 Stufen, und bei
jeder Stufe hast Du einen Addieren X+1.
Der Compiler setzt Deinen Kode genau um, aber ein FPGA ist kein
Microcontroller, er kennt keine Schleifen, sondern muß eine Kette von
Hardware-Addieren bilden, und am Ende kommt das Ergebnis raus.
Deshalb kannst Du die Anzahl der Durchläufe der Schleife auch nicht
variable halten, der Compiler muß schließlich wissen, wieviele Addierer
er hintereinander zu schalten hat.
Ist der Datenvektor 8 Bit lang, sind's eben 8 Addierer.
Ist der Datenvektor 256 Bit lang, sind's 256 Addierer und dann wirds
richtig langsam und du braucht viele Resourcen des FPGA's.
Bis zu 8 Bits ist es viel besser, wenn Du eine Tabelle erstellst, und
der Eingangsvektor das vorgerechnete Ergebnis selektierst. Dazu nochmal
das Beispiel mit Länge 3. Die Hardware kann dies besser umsetzten, siehe
nochmals den Beginn dieser Antwort.
1
case Data_input(2 downto 0) is 
2
when "000" => Count_out <= 0;
3
when "001" => Count_out <= 1;
4
when "010" => Count_out <= 1;
5
when "011" => Count_out <= 2;
6
when "100" => Count_out <= 1;
7
when "101" => Count_out <= 2;
8
when "110" => Count_out <= 2;
9
when "111" => Count_out <= 3;
10
end case

Das Argument, daß der Vektor effektiv länger ist, und Du noch andere
Teile des Vektors zu verarbeiten hast, ist ein Blödsinn. Schließlich
arbeitet das Ganze in Hardware, und die Logik, welche die weiteren Bits
verarbeitet, arbeitet parallel.

Klaus

von FPGA-User (Gast)


Lesenswert?

Hallo an alle,

muss auch noch meinen Senf dazugeben, heute ist zwar Freitag, aber
ich hoffe es kommt noch was sinnvolles raus.

@Klaus:
Zustimmung :-), aber vielleicht hast Du das EXIT übersehen ?
M.E. wird bei der ersten gefundenen '1' die Schleife verlassen.
Das ganze resultiert dann in einem OR-Gatter mit 4 Eingängen
dessen Ausgang auf den D-Eingang eines FF führt- mehr nicht.
Weiss nicht, ob das so gedacht war, evt. fehlt da noch Code.

Und wie schon im Beitrag "Einsen zählen im Vektor" zu lesen ist,
man muss dem Compiler nicht alles vorkauen! Ein paar Loops sind
schon OK, die Abstraktion darf ruhig etwas höher sein.
Das wurde von einem Teilnehmer und mir in exzessiven Versuchen
bewiesen (Testsoftware war Quartus II ALTERA).
Die Erleuchtung kommt natürlich erst, wenn man verstanden hat,
dass so eine Loop wie im Bsp. oben parallel umgesetzt wird.

Ansonsten : Lesen, Lesen, Lesen - es gibt super Material da draussen
im www - es liegt an jedem selbst, was er daraus macht

von Tom (Gast)


Lesenswert?

Hallo Klaus,

erstmal einen Dank für Deine Tipps und Mühen. Sicherlich ist es von
Vorteil, wenn man genau weiß, was aus einem VHDL Quellcode für Hardware
generiert wird, doch wird dieses gerade bei größerem Design etwas
unübersichtlich und ist mir dann nicht immer bewußt...

Mein o.g. Algorithmus scannt natürlich keinen Datenvektor nach '1'sen
ab, denn dieser sollte lediglich als Beispiel dienen.
Mein derzeitig entwickelter (und nicht hier eingestellter) Algorithmus
scannt einen Datenvektor (hinter dem MSB) nach der ersten logischen
'1' ab und wandelt die Position der ersten '1' (Wert der
Laufvariable) in einen Binärwert X um .

Weiterhin wird innerhalb der For-Schleife der oben abgescannte
Datenvektor um die X Position nach rechts verschoben und die
niederwertigsten 4 Bits in einer Variablen gespeichert. Somit habe ich
einen Coder-Algorithmus für die nichtlineare Quantisierungen von PCM
umgesetzt. Im Grunde stellt dieser Algo einen 8-3 Multiplexer dar.

Den Decoder habe ich mit einem Case-Konstrukt realisiert. In der Simu
sieht alles sehr gut aus.

Nach Synthese und FPGA-Programming habe ich wohl Timing-Probleme, da
ich nach dem Decoder Bitfehler bekomme. Habe mir nochmals die
Timing-Infos der Synthese angeschaut und werde wohl die Codierung doch
in einem Table (case Konstrukt) erstellen, denn dadurch erhoffe ich mir
doch immense Gatter-Laufzeitverbesserungen.

Gruß
Tom

von Klaus F. (kfalser)


Lesenswert?

Oh, stimmt, das "exit" habe ich übersehen, es wird nur die Position
des ersten gesetzen Bits zurückgegeben.
Ob der Compiler intelligent genug ist, dies als eine Funktion von 4
Bits umzurechnen, weiss ich nicht, kann sein.
Ob man sich darauf verlassen sollte, daß er intelligent genug ist,
weiss ich auch nicht. Ich würde es nicht tun. Bei meiner Arbeit achte
ich immer darauf, eine Vorstellung von der generierten Hardware zu
haben und die Schaltung dann auch in dieser Hinsicht zu beschreiben.

Klaus

von Tom (Gast)


Lesenswert?

Hallo Klaus,

>Bei meiner Arbeit achte
>ich immer darauf, eine Vorstellung von der generierten Hardware zu
>haben und die Schaltung dann auch in dieser Hinsicht zu beschreiben.

Deshalb werde ich am WE ein neues Design erstellen, indem ich die
Codierung etwaig in einem case Konstrukt realisiere (Codierungstabelle)
und dann das Ergebnis am Montag auf HW mit meinem derzeitigen Design
vergleiche.

Gruß
Tom

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.