Hallo zusammen, ich möchte gerne ein Fifo verwenden, um Daten lesen zu können. Da Schreib- und Lesetakt unabhängig voneinander sind, habe ich es im IP-Core-Gen auf "Independent clocks" gestellt. Nun ergibt sich in meiner Simulation das folgende Bild. Oben der Schreibtakt und die anliegenden Daten, die geschrieben werden sollen und unten der Lesetakt mit dem Ausgang des FiFos. Nun wundere ich mich, warum der erste Wert 0x5887 nicht auch als erstes gelesen werden kann, sondern erst der zweite Wert 0x61a5. Dann stimmt der Leseprozess mit der Reihenfolge der geschriebenen Werte überein. Ist es normal, dass die Daten 10 Lesetakte brauchen, um am Ausgang ausgelesen zu werden? Ich habe sowohl ein Standard Fifo, also auch ein "First-Word-Fall-Through" ausprobiert. Der erste dargestellte Schreibtakt ist auch der erste global gesehen. Die 5887 sollte also im FiFo drin stehen... Fragen Überblick: - Wo ist der erste geschriebene Wert hin? - Ist die Verzögerung vom Schreiben zum Lesen normal? VIELEN DANK!
Andreas B. schrieb: > Nun ergibt sich in meiner Simulation das folgende Bild. Asynchrone Sachen lassen sich leider sehr schlecht simulieren. > Fragen Überblick: > - Wo ist der erste geschriebene Wert hin? Das weiß ich auch nicht. > - Ist die Verzögerung vom Schreiben zum Lesen normal? Ja, ist mir auch schon aufgefallen. Es dauert ja schon ungefähr vier Takte, ehe der erste Wert im leeren FIFO auf der anderen Seite signalisiert wird. Duke
Hallo Andreas, aus deiner Simulation(Wave) geht nicht hervor zu welchem Simulationszeitpunkt gelesen wird. Dein Fifo benötigt nach dem Reset einige Takte bis die Schreiblesecounter korrekt initialisiert sind. Wenn Du nicht weisst was am Fifo genau ab geht, so würde ich mir auch die anderen Statussignale (so nicht geschehen) mit erzeugen lassen... Und dann z.B. schauen ob Du ein WR_ACK für den ersten geschriebenen Wert erhällst... du kannst im Coregen auch einstellen, ob Du während der FIFO Initialisierung ein FIFO Full gesetzt haben willst, oder nicht... Das FWFT-Fifo ist meiner Erfahrung nach mit Vorsicht zu geniessen, auch nach etlichen Versionen tauchen immer wieder Bugs oder Probleme auf. Das die Latenz zwischen Eingangs- und Ausgangsseite so hoch ist IST normal, liegt daran dass die Statussignale erst einmal über den Clockdomainübergang gehieft werden müssen und das dauert... Gruß Andreas
Was bei Deiner Simulation auffällt, ist, dass die Schreibdaten nur sehr kurz vor der aufsteigenden Flanke oder gar gleichzeit mit der Flanke gültig werden. Taktest Du wirklich die Daten sauber ein? Auch das Auslesen schaut nicht gut aus. Abgesehen von den 0000 Daten am Anfang wird jedes Datenword 2 x ausgelesen. Wie schaut der Reset von deinem Fifo aus? Außerdem sollte man das FIFO nur auslesen, wenn auch wirklich etwas drinnen ist. Du solltest das Signale FIFO Empty verwenden, und ev. auch in der Simulation anschauen.
Zunächst mal solltest du das dringend auf einen synchronen FIFO umbauen. WR_CLK und RD_CLK, und das was du jetzt als CLK hast für Write Enable und Read Enable nehmen. So ein asynchrones Geraffel ist gefährlich. Dann wie gesagt nur lesen, wenn auch Empty 0 ist. Dann hast du gültige Daten. Die Latenz ist normal, allerdings ist die Behavioral Simulation nicht Cycle akkurat: Modelsim: Note: WARNING: Behavioral models for independent clock FIFO configurations are not cycle-accurate. You may wish to choose the structural simulation model instead of the behavioral model. This will ensure accurate behavior and latencies during simulation. You can enable this from CORE Generator by selecting Project -> Project Options -> Generation tab -> Structural Simulation. See the FIFO Generator User Guide for more information.
@Christian, Nur weil Andreas zwei verschiedene Clocks hat ist das ganze noch kein Asynchrones Geraffel... Die Coregen Komponenten sind per se Synchrone FIFOs und wenn man die korrekt benutzt, dann macht das FIFO exakt was es soll, Daten aus einer Taktdomain in die nächste verschieben damit gerade ein synchrones Design durchgehalten werden kann. Die Modelsim Warnung bezieht sich nur darauf, das das Behavioral Model der Rams seitens Xilinx ( und wahrscheinlich auch der anderen ) vereinfachte Modelle sind ( was sich u.a. in der Simulationsgeschwindigkeit widerspiegelt). Jetzt mal nicht auf einen diskreten Zeitpunkt bezogen, passt die in der simulation gezeigte Latenz. @Andreas Wo kommt denn das asymetrische Taktverhälltnis deines WR_CLKs her? Je nachdem wie Du den erzeugt hast ist kann sowas kritisch zu bewerten sein... Ggfls. ist bei sowas auch über die Erzeugung eines Clockenables nachzudenken... Gruß Andreas
DANKE für die Hinweise! Das mit dem empty werde ich noch einpflegen, wollte nur erst einmal die Grundfunktion sicherstellen. Meinen WR_CLK generiere ich mir mit Hilfe eines Schieberegisters. Dort werden Daten parallelisiert und wenn das SR einmal komplett gefüllt wurde, erzeuge ich mir ein Signal, dass die Daten in das FIFO geschrieben werden können. Mit dem korrekten Eintakten der Daten habe ich immer wieder meine Probleme. Sobald das SR komplett mit neuen Daten gefüllt wurde, wird ein Signal erzeugt (FULL), was gleichzeitig der WR_CLK des FIFOs ist. Vielleicht sollte ich also diesen Takt nehmen und verzögern, so dass erst etwas später die Daten sicher und korrekt eingelesen werden. Nur hier scheitere ich wieder an der Designpraxis. Einen Takt verwenden und an den WR_CLK EIngang des FIFOs geben, ist ja problemlos mit Hilfe eines Signals möglich. Nur wie kann ich diesen Takt meinetwegen um eine halbe Periode verschieben, dass die Daten aus dem SR dann auch 100%ig am Eingang des FIFOs anliegen. Die ansynchrone Geschichte geht leider nicht anders. Der Schreibtakt beruht auf dem Takt des ADC und der Lesetakt beruht auf dem Lesetaktes des PPC. Ich sehe da keine Möglichkeit bzw. Notwendigkeit, beide Takte zu synchronisieren, zumal der Lesetakt ca. 83MHz beträgt und der EIngangstakt vom ADC 160MHz ist. Die 160MHz werden dann quasi im SR durch 4 geteilt, weil immer vier Bit parallelisiert werden und daraus ergibt sich dann der Schreibtakt des FIFOs. Ich könnte ihn auch symmetrisch gestalten, wenn das weniger Probleme gibt. Vielen DANK für die umfangreiche Hilfe! MfG Andi
Mit asynchron meine ich das fehlen des durchlaufenden Schreib- und Lesetaktes, also das Zugreifen auf den Fifo mit dem Gated Clock. Das macht die Sache unnötig fehleranfällig. Lass einfach den WR_CLK laufen und nimm dein "Full" Signal aus dem Schieberegister als WR_EN. Auf der Leseseite genauso, da nimmst du als RD_EN das not Empty und lässt den RD_CLK frei laufen. Wenn du dann eine Periode lang das WR_EN anlegst, stimmt das Timing. Es ist ein irrglaube, dass die Flanke genau in der Mitte des Steuersignals liegen muss. Innerhalb des FPGA kannst du beruhigt ein Steuersignal mit dem gleichen Takt generieren, mit dem es übernommen wird. Es wird dann mit der nächsten Flanke übernommen, denn da liegt es garantiert noch an, weil ja das vorhergehende FlipFlop auch erst mit dieser Flanke das Signal wieder weg nimmt. Somit ist innerhalb des FPGA die Setup- und Hold-Zeit garantiert (wenn da keine langen kombinatortischen Stufen zwischen sind). So ein "gated Clock" sollte man zunächst mal vermeiden, es sei denn, es ist absolut notwendig.
Andreas B. schrieb: > obald das SR komplett mit neuen Daten gefüllt wurde, wird ein > Signal erzeugt (FULL), was gleichzeitig der WR_CLK des FIFOs ist. > Vielleicht sollte ich also diesen Takt nehmen und verzögern, so dass > erst etwas später die Daten sicher und korrekt eingelesen werden. Nein, Du solltest für das Fifo den Takt vom ADC nehmen, das dieser ein sauberer Takt ist (hoffentlich). Das generierte FULL Signal wird das Write Enable Signal für das FIFO. Niemals generierte Signale als Takt-Signale verwenden, immer nur als Enable.
Hallo Andreas, > Nur wie kann ich diesen Takt meinetwegen um eine halbe Periode verschieben, dass die Daten aus dem SR dann auch 100%ig am >Eingang des FIFOs anliegen. ich glaube Du hast zuerst einmal ein Problem mit dem Verständnis was Du modellierst, bzw. was Du in der Simulation siehst?! Um eine halben Takt verschiebt man erst mal garnix... ( Es sei denn man weiss was man tut und bringt dies auch dem Synthesetool in geeigneter Weise bei). Etwas Hintergrund: Register: Wenn Du ein Datum an den Eingang legst und der Clock eine steigende Flanke macht, dann wird das Ergebnis innerhalb von sagen wir 150ps am Ausgang anliegen dieses Registers. Das Ausgangssignal wird dann über eine zunächst nicht bestimm(bare)te Anzahl Interconnects ( welche auch jeweils einige hundert Pikosekunden Laufzeit hinzuaddieren ) bis zum nächsten Einsatzort unterwegs sein. In der Behaveral-Simulation siehst Du dein Ausgangssignal aus Vereinfachungsgründen am nächsten Clockübergang... Hintergrund ist das Dir die Synthesetools nur garantieren werden das die Daten innerhalb von einer Periode an einem anderen register Element im FPGA anliegen UND das Signal nicht schneller sein wird wie der Clock-Skew zwischen den beiden Registern. Nur darauf sind Synthese und Place&Route Tools ausgerichtet. Alles andere ist asynchrones Design und auf FPGAs aufgrund nicht reproduzierbarer Eergebnisse zu unterlassen. Das heist aber auch wenn Du auf deiner Simulation dein Datum meinetwegen von NULL auf FF springt, dann wird dies an jeder Stelle im FPGA zu diesem Zeitpunkt (steigende Clockflanke) stabil zur Übernahme anliegen... Damit kannst Du Dir die versuchten Klimmzuege sparen. Gruß Andreas
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.