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 ?
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
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 ????
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.
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
@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....
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
@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...?!?
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
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
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
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.
@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
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
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.
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
Hallo FPGA-User, vielen Dank Deiner Tipps.... Werde mal über meinen Code gehen und etwas umstricken müssen.... Gruß Tom
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
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
...fehlt noch der Rücksprung in einen Folgezustand oder in den Ausgangszustand...
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
Wird der oben gezeigte Zustand eigentlich nur einmal durchlaufen mit der anst.Clock, wenn hinter der Countanweisung der Folgezustand kommt?
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
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
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.