Hallo zusammen, ich mache aktuell das Xilinx Tutorial HDL Design using Vivado. Ich bin bei Lab10 "Finite State Machines" angekommen. Jedoch scheitere ich schon an der Aufgabe 1-1. Ich soll eine Mealy State machine mit 3 processen machen. Allerdings bekomme ich das angezeigte Timing Diagramm nicht hin, sondern bin immer um eine Clock Periode verzögert. Ohne State Machine bekomme ich das ohne Probleme gelöst. Hat jemand einen Vorschlag wie ich meine Code verändern könnte damit das klappt. Außerdem weiß ich auch nicht was ich in den 3. Process reinschreiben soll. Danke und Gruß Daniel
Das ist ja mal eine lustige FSM. Du zählst zwar die Zustände S0..S2 durch. Aber dein Ausgangssignal hängt überhaupt nicht von der FSM ab - das wird alleine über Count erzeugt. Du musst dich entscheiden, was deine FSM sein soll und was deinen aktuellen Zustand festlegt (state oder count). Daniel P. schrieb: > Allerdings bekomme ich das angezeigte Timing Diagramm nicht hin, sondern > bin immer um eine Clock Periode verzögert. Weil du die Zuweisung des Ausgangssignals LED0 innerhalb des getakteten Prozesses machst. Dann brauchst du einen Takt um count zu erhöhen. Und im folgenden Taktzyklus wird LED0 in Abhängigkeit vom neuen Wert von count gesetzt. Daniel P. schrieb: > Außerdem weiß ich auch nicht was ich in den 3. Process > reinschreiben soll. Die Ausgangslogik. Die sollte laut Tutorial kombinatorisch arbeiten (also ohne Takt), und aus dem aktuellen Zustand und den momentanen Werten des Eingangs die Ausgangssignale erzeugen. Da dieser Prozess ohne Takt läuft, werden die Ausgänge "sofort" auf den neuen Wert gehen, nicht erst einen Takt später. Ich kann übrigens nicht erkennen, wie dein Code zu dem in Aufgabe 1-1 gefragten Sequence detector passen soll. Vielleicht fängst du zum Entwurf lieber mal mit einem Zustandsfolgediagramm an, ehe du den VHDL-Code schreibst.
Daniel P. schrieb: > ich mache aktuell das Xilinx Tutorial HDL Design using Vivado.
1 | use ieee.numeric_std.all; |
2 | use IEEE.std_logic_unsigned.all; |
Never ever both together! Die numeric_std hat alles, was du brauchst, um dir später mal ein gutes Einkommen zu sichern. Siehe dazu den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete" und darin den Beitrag "Re: IEEE.STD_LOGIC_ARITH.ALL obsolete" samt der darin befindlichen Links einfach mal ganz genau und ausführlich an. > Ohne State Machine bekomme ich das ohne Probleme gelöst. In deinem Code ist ein Zähler. Ein einfacher Zähler ist bereits eine der einfachsten Formen einer FSM. Ein vor sich hintoggelndes Bit wäre biologisch gesehen die "Einzellervariante" einer FSM. > Allerdings bekomme ich das angezeigte Timing Diagramm nicht hin, sondern > bin immer um eine Clock Periode verzögert. Weil du mit deinem Zähler keinen Mealy-Automaten gemacht hast. Was du hier gerade lernst, ist ein wichtiges Kapitel beim Design von synchronen Schaltwerken und nennt sich "Latency": scheinbar reagiert alles um 1 Takt "verspätet". Achim S. schrieb: > Vielleicht fängst du zum Entwurf lieber mal mit einem > Zustandsfolgediagramm an, ehe du den VHDL-Code schreibst. Und wenn du dann den Code mal durch den Synthesizer durchbekommst, dann siehst du dir mal den RTL-Schaltplan an, ob der Synthesizer deine Beschreibung der gewünschten Hardware so verstanden hat, wie du es meinstest.
Hallo zusammen, danke für die Antworten, ich werde das ausprobieren. Gruß Daniel
Hallo zusammen, nun habe ich eine Lösung gefunden, die das gewünschte Verhalten zeigt. Jedoch habe ich jetzt 15 Zustände was mir sehr viel vorkommt. Anbei auch noch der RTL Schaltplan. Nochmals vielen Dank für die Hilfe. Gruß Daniel
Daniel P. schrieb: > Jedoch habe ich jetzt 15 Zustände was mir sehr viel vorkommt. mir auch. ich verstehe die Aufgabe so, dass du 3 Zustände brauchst. s0,wenn die Zahl der einsen 3*n ist, s1 wenn die Zahl 3*n+1 ist, s2 wenn die Zahl 3*n+2 ist. immer wenn eine neue 1 ankommt gehst du einen Zustand weiter.
Achim S. schrieb: > Daniel P. schrieb: >> Jedoch habe ich jetzt 15 Zustände was mir sehr viel vorkommt. > > mir auch. ich verstehe die Aufgabe so, dass du 3 Zustände brauchst. > s0,wenn die Zahl der einsen 3*n ist, s1 wenn die Zahl 3*n+1 ist, s2 wenn > die Zahl 3*n+2 ist. immer wenn eine neue 1 ankommt gehst du einen > Zustand weiter. Hallo, das mit den 3 Zuständen ist eine gute Idee, allerdings bekomme ich es einfach nicht hin. Ich verstehe einfach nicht, wie und in welchem process ich den counter hochzählen soll. Der counter soll ja nur hochzählen wenn der Eingang ain = '1' ist. Ich habe jetzt eine Version, die folgende Fehler hat: - wenn ain von 0 auf 1 wechselt, zählt der counter einmal zusätzlich nach oben - wenn der counter auf seinem maximalwert (15) ist der Ausgang 1, beim nächsten Wert von 0 müsste der Ausgang wieder 1 sein, dies ist jedoch nicht der Fall. Hierzu müsste zweimal hintereinander der Zustand S0 aktiv sein. Dies ist die erste Aufgabe von diesem Blatt und ich scheitere bereits kläglich. Hat noch jemand einen Tipp. Danke und Gruß Daniel
Daniel P. schrieb: > Ich verstehe einfach nicht, wie und in welchem process ich den counter > hochzählen soll. > Der counter soll ja nur hochzählen wenn der Eingang ain = '1' ist. Er soll hochzählen, wenn eine Taktflanke kommt und der Eingang ain='1' ist. Genau so, wie dein State um eins weitergehen soll, wenn eine Taktflanke kommt und der Eingang ain='1' ist. Beides (FSM und counter) sollen sich also gleich verhalten. Von daher kannst du es auch in deinen Prozessen gleich handhaben. So etwas wie "count_int <= count_int;" darst du nicht in einen kombinatorischen Prozess packen. Es würde dazu führen, dass count_int ständig weiter hochzählt, so schnell wie die Schaltung im FPGA es hergibt (eine sog. kombinatorische Schleife). Und es würde nicht nur viel zu schnell zählen, sondern auch mit Sicherheit falsch zählen. Die Simulation zeigt dir das nicht an, weil count_int nicht in der Sensitivitätsliste steht (obwohl es innerhalb des Prozesses abgefragt wird). Aber spätestens bei der Synthese dürfte dir das aufstoßen. Eine solche Anweisung darfst du entweder innerhalb eines getakteten Prozesses verwenden - also mit Abfrage der Taktflanke. Dann zählt count_int immer mit der Taktflanke hoch. Oder du bleibst bei deiner Aufteilung der Prozesse und schreibst im synch_process (taktflankengesteuert): count <= count_next; und im next_state_decode Prozess (kombinatorisch): count_next <= count +1; Daniel P. schrieb: > Hierzu müsste zweimal hintereinander der Zustand S0 > aktiv sein. Du hast 4 States genutzt, nicht 3. Lass das idle weg, starte gleich mit S0 und mach Gebrauch davon, dass du auch bei Null Einsen schon den Wert 1 ausgeben darfst. Daniel P. schrieb: > Dies ist die erste Aufgabe von diesem Blatt und ich scheitere bereits > kläglich. > Hat noch jemand einen Tipp. Aller Anfang ist schwer, lass dich einfach nicht zu schnell entmutigen. Und: im Tutorial geht es speziell um einen Mealy-Automat mit drei Prozessen. Es ist sicher nicht verkehrt, das einmal grundsätzlich durchzugehen. Im normalen Alltag verwende ich persönlich lieber die Ein-Prozess Schreibweise. Dort muss zwar erst mal der Groschen fallen, dass man denselben Signalname für Ausgang wie für Eingang des Flip-Flops verwendet (beim Abfragen und beim Zuweisen). Dafür wird aber nach meinem persönlichen Geschmack die Beschreibung innerhalb eines einzelnen Prozesses übersichtlicher als mit drei Prozessen. (Andere sehen das anders und arbeiten lieber mit mehreren Prozessen zur Beschreibung einer FSM. Kennenlernen sollte man alle Varianten einmal...)
Achim S. schrieb: > So etwas wie > "count_int <= count_int;" > darst du nicht in einen kombinatorischen Prozess packen. Es würde dazu > führen, dass count_int ständig weiter hochzählt, so schnell wie die > Schaltung im FPGA es hergibt (eine sog. kombinatorische Schleife). Und > es würde nicht nur viel zu schnell zählen, sondern auch mit Sicherheit > falsch zählen. Die Simulation zeigt dir das nicht an, weil count_int > nicht in der Sensitivitätsliste steht (obwohl es innerhalb des Prozesses > abgefragt wird). Aber spätestens bei der Synthese dürfte dir das > aufstoßen. Sehr interessant. Ich dachte immer ein Prozess wird nur ausgeführt, wenn ein Signal aus der Sensitivitätsliste seinen Zustand ändert? Abgesehen davon das "count_int <= count_int;" nicht sehr clever und nützlich ist, würde das wirklich hochzählen, es wird doch der selbe wert zugewiesen? > Aller Anfang ist schwer, lass dich einfach nicht zu schnell entmutigen. Danke, ich denke jetzt habe ich es verstanden. Ich habe die Aufgabe mit Ein-Prozess, Zwei-Prozess und drei-Prozess Schreibweise gemacht. In der Zwei und drei Prozess Schreibweise musste ich aber das signal "count_int" in die Sensitivitätsliste stecken um beim Zählerstand 15 zu erreichen, das erneut der state S0 aufgerufen wird. Ist das so guter Stil, oder sollten in die Sensitivitätsliste nur Eingangssignale? Muss nach dem Zählerstand 15, der Zählerstand 0 zugewiesen werden, wenn das Signal std_logic_vector(3 downto 0) ist? In der Simulation klappt das Wunderbar ohne Zuweisung, aber wie verhält sich das in Hardware? > Und: im Tutorial geht es speziell um einen Mealy-Automat mit drei > Prozessen. Es ist sicher nicht verkehrt, das einmal grundsätzlich > durchzugehen. Im normalen Alltag verwende ich persönlich lieber die > Ein-Prozess Schreibweise. Dort muss zwar erst mal der Groschen fallen, > dass man denselben Signalname für Ausgang wie für Eingang des Flip-Flops > verwendet (beim Abfragen und beim Zuweisen). Dafür wird aber nach meinem > persönlichen Geschmack die Beschreibung innerhalb eines einzelnen > Prozesses übersichtlicher als mit drei Prozessen. (Andere sehen das > anders und arbeiten lieber mit mehreren Prozessen zur Beschreibung einer > FSM. Kennenlernen sollte man alle Varianten einmal...) Bei der Ein-Prozess Schreibweise habe ich das Problem das dass Ausgangssignal immer um einen Takt verzögert ausgegeben wird, im gegensatz zu den anderen beiden Schreibweisen. So wie ich das verstehe, geht das aber nicht anders, da bei dieser Schreibweise nur der clk entscheidend und kein kombinatorischer Prozess vorhanden ist. Ich habe versucht statt mit einem Signal mit einer Variable zu arbeiten, aber dadurch kann ich das Ausgangssignal nur um einen halben Takt verschieben. Sind meine Gedanken korrekt oder bekomme ich auch mit der Ein Prozess Schreibweise das selbe Ergebnis, wie mit den anderen beiden? Mit freundlichen Grüßen Daniel
Daniel P. schrieb: > Sehr interessant. Ich dachte immer ein Prozess wird nur ausgeführt, wenn > ein Signal aus der Sensitivitätsliste seinen Zustand ändert? Im Simulator ist das der Fall. Aber in der Synthese (wenn die Logikschaltung wirklich in eine FPGA gepackt werden soll) gibt das eine kombinatorische Schleife. Viele Synthesetools ignorieren die Sensitivitätsliste ganz. Daniel P. schrieb: > Abgesehen davon das "count_int <= count_int;" nicht sehr clever und > nützlich ist, würde das wirklich hochzählen, es wird doch der selbe wert > zugewiesen? Tschuldingung, war mein Fehler. Ich hatte die falsche Stelle zitiert. count_int <= count_int; kannst du problemlos zuweisen. Aber du hattest in deinem Code auch count_int <= count_int + 1; Und das gibt die kombinatorische Schleife. Daniel P. schrieb: > Ist das so guter Stil, oder sollten in die Sensitivitätsliste nur > Eingangssignale? In die Sensitivätsliste müssen alle Signale rein, deren Änderung zu einer Signaländerung im Prozess führen kann. Ein Signal zu viel in der Sensititätsliste zu haben, kann keinen Schaden anrichten. Wenn ein Signal fehlt kann das dagegen kritisch sein. Daniel P. schrieb: > Bei der Ein-Prozess Schreibweise habe ich das Problem das dass > Ausgangssignal immer um einen Takt verzögert ausgegeben wird, im > gegensatz zu den anderen beiden Schreibweisen. So wie ich das verstehe, > geht das aber nicht anders, da bei dieser Schreibweise nur der clk > entscheidend und kein kombinatorischer Prozess vorhanden ist. Das ist richtig: wenn alles innerhalb des getakteten Prozesses steht, dann wird tatsächlich die Zuweisung des Ausgangs erst mit der nächsten Taktflanke wirksam. Bei dem kombinatorischen Prozess für die Ausgabefunktion musst du dagegen nicht auf die Taktflanke warten, bis der Ausgang den neuen Wert annimmt. Daniel P. schrieb: > Sind meine Gedanken korrekt oder bekomme ich auch mit der Ein Prozess > Schreibweise das selbe Ergebnis, wie mit den anderen beiden? Na ja, du könnste die Ausgabefunktion auch ohne Prozess schreiben (einfach als nebenläufige Zuweisung). Das ist aber kein wesentlicher Unterschied dazu, die Ausgabefunktion in einen eigenen kombinatorischen Prozess zu verpacken - womit es dann wieder keine Ein-Prozess-Schreibweise wäre.
Hallo Achim, vielen Dank für deine Hilfe. Ich denke ich habe jetzt die FSM grundsätzlich verstanden. Gruß Daniel
Hallo, eigentlich dachte ich, ich hätte die FSM verstanden. Doch bei der Aufgabe 2.1 von Übung 10, gibt es schon die nächsten Probleme. Hier soll ich einen sequence detector mit einer Moore state machine bauen. Der Ausgang soll zu Beginn 0 sein und dann konstant bleiben, bis eine bestimmte Eingangssequenz auftaucht. Simulation: In der Simulation bekomme ich das richtige Ergebnis, wenn ich das Signal "yout_int" aus der Sensitivtiätsliste von output_decode entferne. Wenn das Signal "yout_int" in der Sensitivtiätsliste ist, dann erscheint die Fehlermeldung "FATAL_ERROR: Iteration limit 10000 is reached. Possible zero delay oscillation detected where simulation time can not advance. Please check your source code. Note that the iteration limit can be changed using switch -maxdeltaid. Time: 65 ns Iteration: 10000" Der Fehler erscheint genau dann wenn das Signal "yout_int" das erste mal '1' werden würde. Synthese: Der Test mit dem FPGA Board ist leider fehlgeschlagen. Der Ausgang reagiert zwar richtig auf die Eingangssequenz, bleibt jedoch nicht konstant bis die nächste Eingangssequenz kommt. Gruß Daniel
Daniel P. schrieb: > Wenn das Signal "yout_int" in der Sensitivtiätsliste ist, dann erscheint > die Fehlermeldung "FATAL_ERROR: Iteration limit 10000 is reached. > Possible zero delay oscillation detected where simulation time can not > advance. Please check your source code. du hast halt schon wieder eine kombinatorische Schleife: yout_int <= not yout_int;
Achim S. schrieb: > Daniel P. schrieb: >> Wenn das Signal "yout_int" in der Sensitivtiätsliste ist, dann erscheint >> die Fehlermeldung "FATAL_ERROR: Iteration limit 10000 is reached. >> Possible zero delay oscillation detected where simulation time can not >> advance. Please check your source code. > > du hast halt schon wieder eine kombinatorische Schleife: > > yout_int <= not yout_int; Ok, verstanden. Dann ist "count_int <= count_int" keine kombinatorische Schleife weil das Signal nicht verändert wird, oder? Ich habe jetzt einen anderen Ansatz gewählt, der sowohl in der Simulation wie auch im FPGA funktioniert, jedoch habe ich die Vermutung das ich eine Mealy Automaten verwendet habe. Könntest du mir bitte einen Tipp geben, wie ich diese Aufgabe mit Moore Automaten mit 3 Prozessen lösen kann? Vor allem das toggeln des Ausgangs und das speichern des Ausgangs bis zur nächsten Eingangssequenz bereiten mir Probleme. Danke und Gruß Daniel
Daniel P. schrieb: > Könntest du mir bitte einen Tipp geben, wie ich diese Aufgabe mit Moore > Automaten mit 3 Prozessen lösen kann? ich zeig dir stattdessen mal, wie ich die geforderte Sequence-detection wahrscheinlich machen würde:
1 | psequence: process(clk) |
2 | begin
|
3 | if rising_edge(clk) then |
4 | ainold<=ain; |
5 | if (ainold&ain)="0100" then yout_int <= '0'; end if; |
6 | if (ainold&ain)="1100" then yout_int <= '1'; end if; |
7 | if (ainold&ain)="1000" then yout_int <= not yout_int; end if; |
8 | end if; |
9 | |
10 | end process; |
11 | |
12 | yout <= yout_int; |
Ich denke, das sollte das geforderte Ergebnis bringen. Ist natürlich leider kein Moore-Automat mit drei Prozessen. Um es gemäß Tutoriums-Vorgabe zu beschreiben, müsste ich mich etwas mehr Zeit investieren.
Hmm: die Einrückung im if rising_edge(clk) then ... end if ist etwas hässlich geworden. Aber ich hoffe, man erkennt trotzdem, wie es gemeint ist.
Achim S. schrieb: > Hmm: die Einrückung im if rising_edge(clk) then ... end if ist etwas > hässlich geworden. Aber ich hoffe, man erkennt trotzdem, wie es gemeint > ist. Ja danke, man erkennt wunderbar was gemeint ist. Das ist mit Sicherheit eine elegantere Lösung und auch sehr viel einfacher.
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.