Hallo zusammen,
ich (VHDL-Anfänger) hab zu Übungszwecken mal versucht, eine
Statusmaschine nur mit nebenläufigen Befehlen zu schreiben:
----->8-----------------------------------------
architecture Architektur_main of main is
type statusmaschine_t is ( STATUS_0, STATUS_1, STATUS_2);
signal sig_Status_x: statusmaschine_t := STATUS_1;
begin
-- Statusmaschine
sig_Status_x <= STATUS_1 when ( (sig_Status_x = STATUS_0) and
(in_button0_b = '0') ) else
STATUS_2 when ( (sig_Status_x = STATUS_1) and
(in_button1_b = '0') ) else
STATUS_0 when ( (sig_Status_x = STATUS_2) and
(in_button2_b = '0') );
-- Status in der 7-Segmentanzeige anzeigen
with sig_Status_x select
out_bcd0_bv8 <= func_LED7SEG_bv8("0000") when STATUS_0,
func_LED7SEG_bv8("0001") when STATUS_1,
func_LED7SEG_bv8("0010") when STATUS_2,
func_LED7SEG_bv8("1111") when others;
end Architektur_main;
----->8-----------------------------------------
Ich habe den Code mit Xilinx ISE9.2i synthetisiert und lasse ihn auf
einem XC9500-CPLD laufen. Über eine 7-Segment-Anzeige wird mir der
Status angezeigt.
Das Problem ist, daß das Signal "sig_Status_x" nicht den Initialzustand
("STATUS_1") annimmt, den ich bei der Signal-Deklaration angegeben habe.
Tatsächlich nimmt "sig_Status_x" einen Zustand an, der außerhalb des
Wertebereiches des Typs "statusmaschine_t" liegt (die 7-Segmentanzeige
zeigt "F" an, also greift der "when others"-Zweig des Selects).
Wenn ich davon ausgehe, daß "sig_Status_x" als 2-Bit-Variable bzw.
-Latch angelegt wird, scheint diese mit "11" initialisiert zu werden.
Könnt Ihr mir sagen, warum das nicht funktioniert?
PS: Sorry für fehlende Formatierung
Sebastian F. schrieb:> Wenn ich davon ausgehe, daß "sig_Status_x" als 2-Bit-Variable bzw.> -Latch angelegt wird
Davon würde ich nicht ausgehen. Schau dir mal die Synthese-Einstellungen
an. Dort könnte z.B. One-Hot-Coding gewählt sein. Also hast du schon mal
3 Bit und folglich 8 Zustände von denen nur 3 auskodiert sind.
Aus welchem Grund versuchst du eine FSM so aufzubauen? Wäre ein Prozess
nicht sinnvoller? Nebenläufige Befehle erzeugen für gewöhnlich keine
Register oder Latches ... ein Prozess schon. Dann sollte es auch mit der
Initialisierung klappen.
Schau dir mal das Resultat der Synthese im RTL-Viewer an, vielleicht
stellst du ja fest, dass überhaupt keine Latches erzeugt werden?!
Die Statusmaschine funktioniert, wenn ich sie erstmal in einen erlaubten
Zustand gebracht hab (durch Einfügen eines Reset-Signals). Nur das
Initialisieren funktioniert nicht.
Inzwischen vermute ich, daß das wieder so eine
Simulation-versus-Synthese-Geschichte ist. Gilt die
Signal-Initialisierung vielleicht nur für den Simulator?
Ich meine, wenn ich so recht darüber nachdenke, hat es sicher einen
Grund, daß alle Bausteine einen Reset-Eingang haben...
> Aus welchem Grund versuchst du eine FSM so aufzubauen?
Nur zu Übungszwecken, hat keinen tieferen Sinn.
Sebastian F. schrieb:> Nur das> Initialisieren funktioniert nicht.
Du kannst auch nur speichernde Elemente (also z.B. FFs) initialisieren.
Bei ASICs, die sich selber aus dem Sumpf ziehen muessen, brauchst du
einen Reset auf '0' oder '1'. Beim FPGA wird beim konfigurieren jedes FF
auf den gewuenschten Wert initialisiert, wenn du da nix angibst
ueblicherweise auf '0'.
Was deine Simulation bzw. dein Synthesetool bei einem Latch macht, tja,
das duerfte hochgradig herstellerabhaengig sein...
Das ist interessant:
Wenn ich den Code auf einem FPGA laufen lassen, dann funktoniert die
Initialisierung. Auf dem CPLD hingegen nicht.
berndl (Gast) schrieb:
>Beim FPGA wird beim konfigurieren jedes FF>auf den gewuenschten Wert initialisiert, wenn du da nix angibst>ueblicherweise auf '0'.
D.h. im FPGA hat ein FF zu Beginn einen definierten Zustand.
Beim CPLD hingegen wird der Zustand des FF wohl eher zufällig bzw. von
der Hardware abhängig sein, daher braucht man da dann auch einen Reset,
richtig?
Sebastian F. schrieb:> D.h. im FPGA hat ein FF zu Beginn einen definierten Zustand.> Beim CPLD hingegen wird der Zustand des FF wohl eher zufällig bzw. von> der Hardware abhängig sein, daher braucht man da dann auch einen Reset,> richtig?
Nein.
Auch das CPLD wacht in einem bestimmten Zustand auf.
Schau Dir einmal den Fitter Report an, dort sind die Gleichungen
aufgelisten, sowie für jedes FF auch der Anfangswert.
Vorneweg: da ist gar kein FF beschrieben, sondern ein Latch.
Das ist für die weitere Verhaltensanalyse wichtig:
> D.h. im FPGA hat ein FF zu Beginn einen definierten Zustand.
Die FFs im FPGA können in die Betriebsart "Latch" umgeschaltet und
deshalb mit einem definierten Wert geladen werden.
> Beim CPLD hingegen wird der Zustand des FF wohl eher zufällig
In einem CPLD gibt es aber kein Latch. Solche Konstrukte werden da aus
Logik zusammengebaut (die getakteten FFs liegen brach). Und Logik lässt
sich nicht initialisieren...
mac4ever schrieb:> Nebenläufige Befehle erzeugen für gewöhnlich keine> Register oder Latches ... ein Prozess schon.
Hmmmmm...:
Wenn ich mir den Code anschaue fällt mir als erstes folgendes auf: Kein
Takt! Und eine State-Machine ohne Takt gibt es nicht!
Und Praktisch: Schau mal die Einstellungen zur State Machine in ISE
genau durch. Da gibt es Optionen wie "Save State Machine". Da würde ich
den Fehler suchen (Nachdem ich einen Takt in das Design implementiert
hätte)
Stefan R. schrieb:> Und eine State-Machine ohne Takt gibt es nicht!
Da solltest du aber nochmal die Grundlagen ansehen... :-o
Eine Zustandsmaschine hat prinzipiell keinen Takt. Nur ist eine
Umsetzung mit Takt durch die auf den Bausteinen vorhandenen
Speicherelemente einfacher zu realisieren. Denn prinzipiell funktioniert
die oben beschriebene FSM ja, nur die Initialisierung geht bei CPLDs
schief.
> Da würde ich den Fehler suchen
Unnötig, der Fehler wurde bereits geklärt.
Ich bin zwar kein Theoretiker, aber Automaten arbeiten Zeitdiskret. Für
mich als Praktiker heisst das: Zustände ändern sich bei
steigende/fallende Flanken!
Lothar Miller schrieb:
> In einem CPLD gibt es aber kein Latch. Solche Konstrukte werden da aus> Logik zusammengebaut (die getakteten FFs liegen brach). Und Logik lässt> sich nicht initialisieren...
Das müßte ja das Synthese-Tool erkennen können. Sollte es dann nicht
einen Fehler oder eine Warnung geben, daß sich die gewünschte
Initialisierung nicht umsetzen läßt?
Ich finde es reichlich verwirrend, daß bestimmte Befehle bzw.
Befehlsteile (wie z.B. "after x ns") vom Synthese-Tool (in meinem Fall
XST) einfach ignoriert werden, ohne daß der Programmier darüber
informiert wird. Ich meine, wie kann ich denn sicher sein, daß das, was
ich programmiert habe, auch tatsächlich alles im Chip ankommt?
Erfahrungssache?
> Vorneweg: da ist gar kein FF beschrieben, sondern ein Latch.
Das ist auch interessant! Ich hab nämlich bemerkt, daß die Maschine auf
dem FPGA zwar korrekt initialisiert wird, aber dafür regelmäßig
"abstürzt" (d.h. einen anderen Zustand annimmt, als der Datentyp
hergibt).
Mit einem Takt und Flankensteuerung war das Problem dann behoben.
Ich vermute, daß die Laufzeitunterschiede im FPGA dazu führen, daß die
einzelnen Signale der Weiterschaltbedingungslogik Glitches an den
Zustands-Latch-Eingängen erzeugen und die Zustands-Latches daher
Kombinsationen annehmen können, die es gar nicht geben dürfte.
Na dann hast du ja jetzt auf die harte Tour erfahren, was es bedeutet
ein nicht-synchrones Design zu bauen.
Für Anfänger gilt: Alles synchron! Dann gibt es auch keine Glitches.
Ich für meinen Teil habe Zustandsmaschinen jedenfalls nur mit Takt
kennengelernt, wie soll ohne einen Takt auch von einem in den nächsten
Takt umgeschalten werden?
Sebastian F. schrieb:> Ich finde es reichlich verwirrend, daß bestimmte Befehle bzw.> Befehlsteile (wie z.B. "after x ns") vom Synthese-Tool (in meinem Fall> XST) einfach ignoriert werden, ohne daß der Programmier darüber> informiert wird. Ich meine, wie kann ich denn sicher sein, daß das, was> ich programmiert habe, auch tatsächlich alles im Chip ankommt?> Erfahrungssache?
Es gibt einen Standard was ein Synthese-Werkzeug umsetzen muss und was
nicht: IEEE 1076.6
Zudem musst Du ins Handbuch des Werkzeuges schauen. Und manche Tools
geben Dir eine Warning oder eine Info mit der Information das etwas
nicht synthetisierbar ist.
Btw. IEEE 1076.6 lässt keine Initialisierung bei der Deklaration zu.
Doch viele Tools können das trotzdem. Bei XST ist es wohl standardmäßig
aktiviert. Bei manch anderem muss man es explizit aktivieren.
faul schrieb:> Na dann hast du ja jetzt auf die harte Tour erfahren, was es bedeutet> ein nicht-synchrones Design zu bauen.
Das ist übrigens falsch. Das Design an sich ist synchron. Und zwar zum
Signal in_button0_b.
Allerdings handelt es sich dabei um ein Design aus Latches. Das ist in
einem FPGA oder CPLD zwar eine Sünde, aber in einem ASIC kann man sowas
bauen. Allerdings muss ein solches Design umfassender mit Constraints
versehen werden und die STA muss genauer ausgeführt werden.
Lothar Miller schrieb:> Hmmmmm...:> latched <= input when speichern='1';> registered <= input when rising_edge(speichern);
Ok, so hab ich das noch nie versucht ...
Sebastian F. schrieb:> Ich finde es reichlich verwirrend, daß bestimmte Befehle bzw.> Befehlsteile (wie z.B. "after x ns") vom Synthese-Tool (in meinem Fall> XST) einfach ignoriert werden
Das after x ns nicht synthesefähig ist, wird durchaus in der Literatur
erwähnt. Die Unterschiede zw. Simulation und Synthese sollte man
unbedingt kennen und sich nicht auf das Synthesetool verlassen.
Mathi schrieb:> Das ist übrigens falsch. Das Design an sich ist synchron. Und zwar zum> Signal in_button0_b.
... und dann noch zu in_button1_b und in_button2_b ...
3 unsynchrone Signale ... sehr synchron
Stefan R. schrieb:> Ich bin zwar kein Theoretiker, aber Automaten arbeiten Zeitdiskret.
Nein. Die Übergänge eines Automaten sind idR. komplett zeitunabhängig.
Z.B. Kaffeeautomat: Irgendwann drückt einer mal die starttates, dann
wird ein Bescher ausgewrofen, der von der Schwerkraft gezogen beliebig
langsam in den Halter fällt. Danach wird Wasser eingelsaaen, was druck-
und kalkabhängig schneller oder langsamer geht. Dann das Aufheizen,
Abfüllen....
Nirgends in diesem Ablauf ist die Zeit vorrangig nötig.
> Für mich als Praktiker heisst das: Zustände ändern sich bei> steigende/fallende Flanken!
In der Praxis sind wie gesagt nur die Speicherglieder (hier FFs)
diejenigen, die einen Takt brauchen...
Die Automatentheorie schert sich nicht um Gatterlaufzeiten :-)
Damit kann man sie zwar als graue Theorie abtun, aber alle Algorithmen
der digitalen Signalverarbeitung basieren nun mal auf diesen Grundlagen.
Wenn man, wie ich, kein brillianter Mathematiker ist, bleibt einem
leider nicht anderes übrig, als diese Modelle als gegeben zu
akzeptieren. Ganz egal wie ich meine Schaltung aufbaue: Sie muss
möglichst nahe am Ideal der Theorie bleiben und die besagt: zeitdiskrete
Abstände und abgestufte Werte.
Ich nehme meine Behauptung zurück, wenn ihr mir einen FIR Filter ohne
Takt und ein halbes Bit zeigt!
mac4ever schrieb:> ... und dann noch zu in_button1_b und in_button2_b ...> 3 unsynchrone Signale ... sehr synchron
Ah, ich hatte übersehen das es drei unterschiedliche in_buttonX_b gibt.
Sorry!
Das ERSATZSCHALTBILD eines SAW Filters entspricht dem eines FIR-Filters.
D.h. nicht, dass es ein FIR Filter und schon gar nicht, dass es eines
ohne Takt ist.
http://www.axtal.com/data/buch/Kap9.pdf
Stefan R. schrieb:> Das ERSATZSCHALTBILD eines SAW Filters entspricht dem eines FIR-Filters.> D.h. nicht, dass es ein FIR Filter und schon gar nicht, dass es eines> ohne Takt ist.
Die Implementierung eines Automaten gelingt am zuverlässgsten mit einem
Takt. Das heißt aber nicht, dass es ohne Takt nicht ginge...
Zur Beruhigung: ich verwende für den Zustandsspeicher meiner Automaten
auch FFs. Und brauche daher einen Takt. Das ERSATZSCHALTBILD des
Automaten (die grafische Umsetzung) braucht allerdings keinerlei Takt,
und der taucht dort auch nirgends auf...