Ich habe in einem Projekt eine State-Machine beschrieben. Datei ist
angehängt. Auch einen Stimulus habe ich angehängt.
Es treten dabei in der Timing-Simulation verschiedene Merkwürdigkeiten
auf. (In der funktionalen ist (wie üblich) alles bestens).
Ich verwende Quartus II Version 9. SP 2 und zwar aus dem Grund, das dies
die letzte Version ist, die FLEX6000 unterstützt. (Das ist erstmal für
einen Prototypen nicht zu ändern. Politik halt.)
1. Bei einem Reset wird die Statemachine nicht entsprechend des
VHDL-Codes in den gewünschten Zustand gesetzt. Ich habe auch schon eine
bessere Reset-Logik mit einem rückgekoppelten INIT_DONE implementiert,
aber das Resultat ist das selbe.
2. Das Encoding ist nicht One-Hot. Der Startzustand wird mit mehreren
Einsen kodiert. Auch wenn ich ausdrücklich ein One-Hot-Coding der
Statemachine anfordere ist der On-State so kodiert, das viele Flip-Flops
gesetzt sind. Nicht aber ein einzelnes, wie ich es bei One-Hot erwarten
würde. Im übrigen tritt Punkt 1. davon unabhängig auf.
3. Die Statemachine nimmt aufgrund eines Inputs (Signal e wird high)
sozusagen zwei Zustände gleichzeitig ein. In der Realität (also dieses
File in den Baustein programmiert) tritt sporadisch der Fall auf, das
keine Reaktion mehr auf die Input-Änderungen geschieht. Die Häufigkeit
variiert aber.
4. Bei Signal g wird bei den Zustandübergangen mal kurz eine 1
ausgegeben, obwohl der Folgezustand garkeine Änderung an dem Signal
vorsieht.
Nun, zumindest das letzte könnte ich mir noch erklären, wenn die These
richtig ist, das die Logik für das errechnen des Folgezustandes in dem
switch/when konkurierend arbeitet. Anderseits widerspräche das der
Regel, das nur ein Zweig durchlaufen werden sollte.
Ich mache wahrscheinlich einen Denkfehler, bin aber nach Tagen
verschiedener Versuche völlig ratlos.
Nochschlimmernoch asyncrone Resets ;-)
http://www.lothar-miller.de/s9y/archives/70-Asynchroner-Reset.html
Deine Waveform ist aus einer timingssimulation nehme
ich mal an, da sind nanosekundenlange Glitches
aus Kombinatorischer Logik nichts ungewöhnliches.
Wenn der Glitch hier stört, dann mach noch ein Flipflop
dran .
Timingsimulationen sehe ich mir gar nicht an. Das ist vergeudete Zeit...
Synchrones Design, eingetaktete Eingänge und wenn möglich keinen Reset,
dann reicht die funktionelle Simulation.
Hmm schrieb:> Nun, zumindest das letzte könnte ich mir noch erklären, wenn die These> richtig ist, das die Logik für das errechnen des Folgezustandes in dem> switch/when konkurierend arbeitet. Anderseits widerspräche das der> Regel, das nur ein Zweig durchlaufen werden sollte.
Einen Vorrang gibt es nur bei if elsif jedoch nicht beim case.
Synchronisiere das Reset, gleich nach dem es im FPGA ist und verwende es
danach nur noch im getakteten Teil deines Prozesses, einen ungetakteten
Teil gibt es dann nicht mehr. In der Sensitiv-Liste steht dann nur noch
der Takt.
Tom
Hmm schrieb:> 2. Das Encoding ist nicht One-Hot. Der Startzustand wird mit mehreren> Einsen kodiert. Auch wenn ich ausdrücklich ein One-Hot-Coding der> Statemachine anfordere ist der On-State so kodiert, das viele Flip-Flops> gesetzt sind. Nicht aber ein einzelnes, wie ich es bei One-Hot erwarten> würde. Im übrigen tritt Punkt 1. davon unabhängig auf.
hi,
du musst zusätzlich das attribute "fsm_encoding" (o.ä.) für das signal
"state" auf "user" setzen, sonst nutzt das enum-encoding nichts.
wie schon erwähnt, sind Glitche in der timing-Simulation (und Praxis)
normal und werden auch in der "one-hot" auftreten (kombinatorisch
erzeugte Signale aus mehreren FF, welche unterschiedlich lange Wege zur
LUT haben)
Ein Hinweis zur teilweise zwanghaften Synchronisation des Resets:
IMHO: wenn sichergestellt ist, dass wie in diesem Beispiel die
state-machine nicht sofort nach dem Reset los läuft, sondern ein anderes
Signal benötigt, welches erst deutlich nach dem Reset kommt, ist eine
Synchronisation des Resets unnötig.
Jedoch ist im Diagramm das Signal a vermutlich zu knapp vor dem Takt
(nicht synchonisiert, obwohl hier wichtig). Ich kenne den FLEX6000
nicht, daher kann ich zur benötigten Setup-Zeit und Routing-Delays
nichts sagen.
Daniel M. schrieb:> du musst zusätzlich das attribute "fsm_encoding" (o.ä.) für das signal> "state" auf "user" setzen, sonst nutzt das enum-encoding nichts.
Und schon wenn man sowas machen muss, um das Design "halbwegs" zum
Laufen zu bekommen, stinkt es irgendwo.
Im Normalfall läuft bei einem sauberen Design eine FSM unabhängig vom
Typ. Und dann ist es bestenfalls noch ein persönlicher Spleen oder eine
Firmendirektive, dass unbedingt ein bestimmter Encoding-Typ verwendet
werden muss.
> ein anderes Signal benötigt, welches erst deutlich nach dem Reset kommt
Ja, das mag prinzipiell so sein. Aber wenn das Reset-Signal direkt
vom Pin kommt, dann reicht evtl. schon ein 500ps-EMV-Impuls aus, um eine
undefinierte Anzahl der Flipflops vom FPGA zurückzusetzen. BTDT.
> Jedoch ist im Diagramm das Signal a vermutlich zu knapp vor dem Takt> (nicht synchonisiert, obwohl hier wichtig).
Ich gebe (wie schon gesagt) auf solche Timing-Simulationen nichts, weil
das Modell der Umwelt idR. nicht gut genug ist: in der Simulation kommt
dieses Signal immer zum selben Zeitpunkt. In der Realität kommt das
auch mal ganz anders...
So viele Antworten. Ich danke Euch allen vielmals.
Da muss ich mal ein wenig drüber nachdenken.
Aber zweierlei möchte ich doch gleich nachfragen. Vielleicht geht es aus
dem von Euch geschriebenen ja hervor, aber dann erkenne ich es nicht.
1. Das Reset-Signal liegt doch recht lange an. Warum geht dann die
State-Machine nicht in den Reset-Zustand? Der Zustand ändert sich ja
überhaupt nicht!
2. Verstehe ich die Aussage von Thomas
>Einen Vorrang gibt es nur bei if elsif jedoch nicht beim case.
recht? Heisst, das, das in meiner State-Machine, falls schon ein when
durchlaufen wurde, im selben Takt, d.h. unmittelbar danach, ein weiteres
when durchlaufen wird, falls der vorherige den entsprechenden
Folgezustand gesetzt hat? Das also nicht auf die nächste steigende
Flanke gewartet wird, was ich nach dem Code erwarten würde.
Hmm schrieb:> 2. Verstehe ich die Aussage von Thomas>>Einen Vorrang gibt es nur bei if elsif jedoch nicht beim case.> recht? Heisst, das, das in meiner State-Machine, falls schon ein when> durchlaufen wurde, im selben Takt, d.h. unmittelbar danach, ein weiteres> when durchlaufen wird,
Großer Denkfehler, da wird nichts durchlaufen, aus dem Zustand und den
Bedingungen in Zuständen werden boolsche Funktionen gebildet, in der Art
ungetaktet
s.M_state <= reset and not a;
getaktet
s.N_state <= s.M_state and a
s.O_state <= s.N_state;
und die werden parallel abgearbeitet. Bei dir ist s.M_state ständig
aktiv, wenn jetzt a = 1 für mindestens zwei Takte, dann wird im 1. Takt
s.N_state zusätzlich aktiv und im 2. Takt auch noch s.O_state.
Beim if elsif gehen vorherigen Bedingungen noch mit ein.
Dabei ist mir aufgefallen, dass du deine FSM zwei Mal initialisierts
signal state : state_type := M_State;
if reset = '1' then
state <= M_State;
Vielleicht hat dein Syntheser damit Probleme. Entferne mal die
Signalinitialisierung, denn bei dir bleibt ja dieser Zustand ständig
aktiv.
Tom
Hmm schrieb:> 1. Das Reset-Signal liegt doch recht lange an. Warum geht dann die> State-Machine nicht in den Reset-Zustand?
Wie sieht die funktionelle Simulation aus?
Gibt es evtl. Probleme mit der Defaultzuweisung und dem sofort aktiven
Reset?
In Kürze:
1. Vermutlich: Da die switch/when Zweige konkurieren, falsche Zustände
falls Bedingungen für Übergang aus dem Ausgangszustand und dem
Folgezustand wahr sind.
2. Vermutlich: Problem mit initialisiertem Zustand
3. Vermutlich: Problem mit sofort aktivem Reset.
@ Thomas
>Großer Denkfehler
Nicht wirklich. Aber ohne genügend Kaffee so ausgedrückt wie ich nicht
gedacht habe. Ich habe schon so gedacht, wie ich die Frage formuliert
habe und wie Du es dann bestätigt hast, mit:
>ungetaktet>s.M_state <= reset and not a;>getaktet>s.N_state <= s.M_state and a>s.O_state <= s.N_state;
D.h. alle when konkurieren und schliessen sich nicht gegenseitig aus.
Komisch. Das ist ein Template aus Quartus. Wenn man weiss wie das
funktioniert: Wann verwendet man sowas?
Da ich ja auch Epsilon-Übergänge in der Statemachine habe, kann das ja
nie sinnvoll gehen. Auch ist nach dem Reset in der Regel (aber nicht
grundsätzlich) schon eine Bedingung von einem Übergang gültig. Ich habe
angenommen, das pro Flanke genau ein Zustandswechsel erfolgt.
Na gut. Ich kann noch die Variante mit der Zwischenspeicherung des
nächsten Zustandes nehmen.
>...dass du deine FSM zwei Mal initialisierts
Kann ich probieren mal rauszunehmen.
@ Lothar
>Wie sieht die funktionelle Simulation aus?
Die sieht gut aus. Ich habe mit der Timing-Simulation gearbeitet, weil,
wie oben beschrieben, die Statemachine in der Realität manchmal aufhört
zu reagieren.
>In der Realität (also dieses>File in den Baustein programmiert) tritt sporadisch der Fall auf, das>keine Reaktion mehr auf die Input-Änderungen geschieht. Die Häufigkeit>variiert aber.
... und hängt vom Gesamtdesign ab. Vermutlich also vom Routing ->
Timing.
Das mit dem One-Hot ist mehr oder weniger Zufall und nicht zwingend
erforderlich. Ich habe nur mal gesehen, das der Advisor von Quartus das
empfiehlt, weil, wenn nur ein Flip-Flop den Zustand wechselt, weniger
starke Störungen herumschwirren. Es schien mir auch günstig, weil man in
der Simulation dann direkt den momentanen Zustand sieht, ohne erst die
Codierung anschauen zu müssen.
Es ging mir darum, durch das explizite benutzen von attribute
enum_encoding, obwohl das durch die Quartus Optionen eigentlich
erzwungen werden sollte, "wirklich" ein One-Hot encoding zu erreichen,
weil es nämlich einfach nicht passiert.
>Gibt es evtl. Probleme mit der Defaultzuweisung und dem sofort aktiven
Reset?
Das scheint so zu sein. Ich probiere das mal.
Kennt jemand bei Quartus ne Möglichkeit die RTL nach dem analysieren,
elaborieren etc. anzuschauen? Vor allem der Statemachine.
Hmm schrieb:> "wirklich" ein One-Hot encoding zu erreichen
Ja nun, wie wird ein One-Hot-Encoding umgesetzt?
Richtig: für jeden Zustand gibt es ein Flipflop. Aber es gibt
überhaupt keine Möglichkeit, sicherzustellen, dass ausschliesslich 1
Flipflop aktiv ist! Und genauso gibt es im Umkehrschluss keine
Möglichkeit zu verhindern, dass gar kein FF oder auch mehrere FF
gesetzt sind.
Das habe ich mit den asynchronen Eingängen und der FSM im Link dort im
Beitrag "Re: One-Hot encoded Statemachine kommt in illegalen Zustand, wird nicht reseted, gibt unerwartetes a" gemeint.
Also die Frage schlechthin:
sind a, b und/oder c solche asynchronen Eingänge?
Oder andersrum:
woher kommen diese Signale?
BTW:
process (clk, reset, a, b, c)
In dieser Sensitivliste sind a, b und c unnötig.
@ Lothar
Das ist, denke ich, ein Missverständnis.
Was ich meine, ist, das die Kodierung der Zustände nicht One-Hot ist
obwohl sie es sein sollte. Das ist ja unabhängig von der Kombinatorik,
die dann die Zustandsübergänge macht. Eine rein statische Zuordnung. Das
sieht man im Compilation-Report. Jeder Zustand sollte nur eine 1 haben
und die restlichen Flip-Flops 0 sein. Das ist aber nicht so. Tatsächlich
hat (ausgerechnet) der Reset-Zustand nur eine 0 und alle anderen sind 1.
Wenn der Rest der Kombinatorik richtig synthetisiert wird, ist das an
sich kein Problem. Nur, beunruhigt mich das, wenn er schon diese simple
Zuordnung nicht One-Hot macht, wie er es verspricht.
Der zweite Punkt, wegen der asynchronen Inputs, habe ich, ich habe das
leider nicht ausdrücklich bestätigt, inhaltlich verstanden worden.
Bei asynchronen Inputs kann es durch bei den Zustandsübergängen durch
>... es gibt>überhaupt keine Möglichkeit, sicherzustellen, dass ausschliesslich 1>Flipflop aktiv ist! Und genauso gibt es im Umkehrschluss keine>Möglichkeit zu verhindern, dass gar kein FF oder auch mehrere FF>gesetzt sind.
vorkommen das ich zeitweise oder dauernd unmögliche, Zustände sehe,
deren Codierung nicht dem One-Hot Schema entspricht.
Das ist klar. Da muss ich was ändern.
Also Sginale einsynchronisieren.
Aber wird das nicht durch die Nebenläufigkeit des case/when
konkterkariert?
Das muss ich mal ausprobieren.
Hmm schrieb:> Was ich meine, ist, das die Kodierung der Zustände nicht One-Hot ist> obwohl sie es sein sollte.
Naja, es könnte sein, dass in der Grafik M_State irgendwie einfach
invertiert ist. Dann würde das alles Sinn machen...
> Also Sginale einsynchronisieren.
Ja.
> Aber wird das nicht durch die Nebenläufigkeit des case/when> konkterkariert?
Das hat mit Nebenläufigkeit nix zu tun. Auch Kombinatorik, die im
getakteten Prozess steht, wird ein paar ns brauchen, bis der "neue" Wert
stabil ist. Nach jedem Takt hat diese Kombinatorik (nebenläufig oder im
Prozess) dann paar ns Zeit zum "zappeln", sie muss nur rechtzeitig vor
der nächsten steigenden Flanke stabil sein. Denn dann übernehmen die
Speicher-FFs den frisch "zusammengezappelten" Zustand.
>Naja, es könnte sein, dass in der Grafik M_State irgendwie einfach>invertiert ist. Dann würde das alles Sinn machen...
Hmm...
>Das hat mit Nebenläufigkeit nix zu tun.
Ja. Da habe ich mich irgendwie selbst verwirrt und dabei Thomas zu Hilfe
genommen. Der neue Zustand wird zwar andauernd durch die Kombinatorik
neu berechnet aber nur bei der Flanke auch übernommen.
Einsynchronisieren! Ohne das: Böser Fehler. :-{
Urteil: Nochmal Kapitel 6.4.2 vom Reichardt lesen
Jetzt habe ich die Eingangssignale einsynchronisiert und muss ich doch
noch mal um Rat fragen, denn nun merke ich wieder warum ich das
eigentlich nicht gemacht habe.
Durch das Einsynchronisieren merkt die Statemachine alle Änderungen erst
einen Takt später.
D.h. nun dauern einige Zustände länger an, als eigentlich geplant.
Wie geht Ihr damit um? Den Takt kann ich nicht ändern. Der kommt von
aussen und ist vorgegeben.
Hmm schrieb:> Durch das Einsynchronisieren merkt die Statemachine alle Änderungen erst> einen Takt später.
Sollten nach 2 Flipflops eigentlich 1-2 Takte sein. Im Schnitt also 1,5
Takte...
> Wie geht Ihr damit um?
Wir beantworten erst mal die Frage, die ich schon mal gestellt habe:
WOHER kommen diese Signale und wass sollen sie bewirken?
>Sollten nach 2 Flipflops eigentlich 1-2 Takte sein. Im Schnitt also 1,5>Takte...
Ja. Richtig.
>> Wie geht Ihr damit um?>Wir beantworten erst mal die Frage, die ich schon mal gestellt habe:>WOHER kommen diese Signale und wass sollen sie bewirken?
Ich bitte Dich, Lothar und auch alle anderen um Entschuldigung, aber
diese Frage kann ich nicht beantworten. Nicht so sehr wegen des Codes
oder seiner Anwendung als wegen der Öffentlichkeit an sich.
Ich bedanke mich sehr herzlich bei allen und besonders bei Lothar. Ihr
wart sehr hilfsbereit und ich bin einen Schritt weiter.