Hallo,
da ich im Rahmen eines Uni-Projektes einen asynchronen FIFO (der einen
Lesetakt und einen Schreibetakt besittz) erstellen soll (bei dem die
gray codierung jedoch komplett vernachlässigt werden soll!) und ich im
Bereich VHDL doch noch ziemlich frisch bin, stoße ich hier leider immer
wieder auf Probleme und hoffe, dass mir hier weitergeholfen werden kann.
:)
Zunächst bin ich mir etwas unsicher, wie die Wahrscheinlichkeit des
Auftretens eines Metastabilen Zustandes verringern kann.
Ich habe mich umgesehen und habe erfahren, dass man dies mit 2 direkt
hintereinander geschalteten D-FFs macht.
Ich weis, dass jede Signalzuweisung innerhalb eines Prozesses einen D-FF
zur Folge hat, jedoch bin ich mir unsicher wie die Implementation
umgesetzt werden soll:
Würde ich das so machen, dann hätte ich ja das Problem, dass Signale ja
erst im Takt später den neuen Wert annehmen würden, also kann das so ja
nicht gehen oder?
1
clk1:process(clk_in)--Prozess für Write
2
begin
3
if(clk_in'eventandclk_in='1')then
4
data_tmp_in<=data_in;
5
data_sync_in<=data_tmp_in;
6
endif;
7
endprocessclk1;
Denke ich denn überhaupt in die richtige Richtung?
Muss ich es statt dessen mit variablen schreiben? (werden bei variable
zuweisungen überhaupt dffs erzeugt?)
Soll ich 2 Prozesse daraus machen?
Ich hoffe, dass mir jemand einen Tipp in die Richtige Richtung geben
kann :)
Bin für jeden Rat offen!
Vielen lieben Dank schon mal im Voraus! :)
MFG, Henry.
So wie du es beschrieben hast, ist es korrekt.
Wo genau siehst du das Problem, dass das Signal erst im Takt später den
neuen Wert annimmt? Du musst die Abläufe im Design eben mit Rücksicht
darauf beschreiben.
so wie du es beschreibst wird ein FF von data_in nach data_tmp_in und
ein FF von data_tmp_in nach data_sync_in beschrieben. Sieht eigentlich
gut aus.
Damit dauert es 2 Takte bis der Wert von data_in nach data_sync_in
übernommen wird.
Henry D. schrieb:> Würde ich das so machen, dann hätte ich ja das Problem, dass Signale ja> erst im Takt später den neuen Wert annehmen würden, also kann das so ja> nicht gehen oder?
Ich versteh die Frage nicht. Natürlich verzögert ein FF das Signal um
einen Takt.
Henry D. schrieb:> Denke ich denn überhaupt in die richtige Richtung?
Ja.
> Muss ich es statt dessen mit variablen schreiben?
Du sollst keine Variablen verwenden, wenn es nicht nötig ist. Und schon
gleich überhaupt sollst du keine speichernden Variablen verwenden.
> (werden bei variable zuweisungen überhaupt dffs erzeugt?)
Solange du dir solche Fragen stellt darfst (die Amis sagen
richtigerweise MUSST) du keine Variablen nehmen!
Siehe mal den Beitrag "Variable vs Signal"> Soll ich 2 Prozesse daraus machen?
Nein, wozu?
Ich würde gar keinen Prozess draus machen und ein
2-Bit-Schieberegister nehmen:
1
signalinp_sr=std_logic_vector(1downto0);
2
...
3
inp_sr<=inp_sr(0)&data_inwhenrising_edge(clk);
Und dann verwendest du den inp_sr(1) als einsynchronisierten Eingang.
Das ist einfach wiel übersichtlicher...
> Zunächst bin ich mir etwas unsicher, wie die Wahrscheinlichkeit des> Auftretens eines Metastabilen Zustandes verringern kann.
Das ist sicher nicht dein Problem, solange du Taktfrequenzen unter
300MHz verwendest! Siehe das dort:
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
Vielen Dank für die Antworten, das hat mir schon mal weitergeholfen! :)
War etwas verwirrt da ja immer überall angesprochen wird, dass man ja
darauf achten soll, dass Signalzuweisungen erst einen Takt später erst
gültig werden, dass ich total verpeilt hab dass dieser Effekt hier ja
erwünscht ist ;)
@Lothar Miller: Vielen Dank, dieses Vorgehen mit den Schieberegistern
ist natürlich clever (und gut zu wissen!), aber leider ist vorgegeben,
dass wir getaktete Prozesse verwenden sollen in dieser Aufgabe :/
Auch Danke für die zusätzlichen Informationsverweise!
Ich habe etwas weiter gearbeitet an meinem FIFO, jedoch glaube ich habe
ich noch ein Verständnisproblem...
Ich habe mithilfe der oben beschriebenen Methode (mit den direkt
hintereinander geschalteten zwei D-FFs) die Daten (std_logic_vectors),
data_in und data_out, also die zu lesenden/schreibenden Daten so
synchronisiert.
Jedoch muss man hier nicht die zu schreibenden/lesenden Daten an sich
synchronisieren, sondern nur die lese/schreibe Pointer, oder?
Vielen Dank euch! :)
MFG, Henry.
Henry D. schrieb:> Ich habe etwas weiter gearbeitet an meinem FIFO, jedoch glaube ich habe> ich noch ein Verständnisproblem...> Ich habe mithilfe der oben beschriebenen Methode (mit den direkt> hintereinander geschalteten zwei D-FFs) die Daten (std_logic_vectors),> data_in und data_out, also die zu lesenden/schreibenden Daten so> synchronisiert.
Genau das funktioniert auch nicht, da zwar jedes Bit einzeln
synchronsiert wird, aber nicht notwendigerweise beim gleichen Takt.
> Jedoch muss man hier nicht die zu schreibenden/lesenden Daten an sich> synchronisieren, sondern nur die lese/schreibe Pointer, oder?>
Richtig, nur die lese/schreibe Pointer. Aber wenn sich mehr als ein Bit
in den Pointern "gleichzeitog" ändert steht du wieder bei den gleich
Problem wie oben.
Abhilfe: Die Pointer im Graycode ausführen, denn dann ändert sich
garantiert immer nur ein Bit im Pointer, und du kannst alle bits der
Pointer ohne zuhilfenahme von Strobes synchroniseren.
Henry D. schrieb:> dieses Vorgehen mit den Schieberegistern ist natürlich clever (und gut> zu wissen!), aber leider ist vorgegeben, dass wir getaktete Prozesse> verwenden sollen
Dann nach das Schieberegister in einen Prozess... :-)