Forum: FPGA, VHDL & Co. Leseprobleme mit 16bit FiFo


von Andreas B. (loopy83)


Angehängte Dateien:

Lesenswert?

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!

von Duke Scarring (Gast)


Lesenswert?

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

von Andreas B. (Firma: www.collion.de) (bergy) Benutzerseite


Lesenswert?

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

von Klaus F. (kfalser)


Lesenswert?

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.

von Christian R. (supachris)


Lesenswert?

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.

von Andreas B. (Firma: www.collion.de) (bergy) Benutzerseite


Lesenswert?

@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

von Andreas B. (loopy83)


Lesenswert?

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

von Christian R. (supachris)


Lesenswert?

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.

von Klaus F. (kfalser)


Lesenswert?

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.

von Andreas B. (Firma: www.collion.de) (bergy) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.