Kennt sich jemand eventuell mit dual clock FIFOs gut aus und kann mir
sagen, was ich für unterschiedliche Taktfrequenzen auf read und write
Seite haben kann? Ich arbeite mit einem Xilinx Spartan 6. Ich habe den
Core Generator FIFO und auf der Read Seite 100MHz und auf der Write
Seite nur 2 MHz. Das funktioniert völlig unzuverlässig. auf beiden
Seiten 2 MHz funktioniert. Ich habe es immer so verstanden, dass bei
solchen FIFOs mit 2 Clocks die Synchronisierung für mich erledigt wird
und ich mich nicht darum kümmern muss oder sind solche starken
Unterschiede ein Problem? Ich habe auch mal mit dem VHDL-extras FIFO
herumprobiert aber da ist es das gleiche und der scheint wohl auch ein
Problem mit dem Handshake zu haben.
Axel F. schrieb:> Sollte eigentlich keine Probleme geben, wenn Graycounter und> korrekt> konfiguriertes RAM im Spiel sind. Welche Version nutzt du?
Ich nutze die letzte ISE Version. Beim VHDL extras wird kein gray
counter eingesetzt. Da fällt mir gerade noch auf, dass ich vermutlich
nicht beachte, dass die Empty flag um einen clock cycle verspätet kommt
und sich mein read enable und empty überlappen. Das heißt ja, dass ich
immer einen cycle warten muss um empty nach einem read zu prüfen. Das
heißt nur halbe bandbreite beim lesen, oder?
Tim Z. schrieb:> Das heißt ja, dass ich immer einen cycle warten muss um empty nach einem> read zu prüfen. Das heißt nur halbe bandbreite beim lesen, oder?
Du brauchst ja nur genug puffern (bis zu einer gewissen Wassermarke) und
mit 100 mhz in Bursts auszulesen .
Tim Z. schrieb:> Ich arbeite mit einem Xilinx Spartan 6.
Der hatte einige RAM-issues. Allerdings bezogen die sich auf bestimmte
Adress-Konstellationen und sollten bei den FIFOs keine Rolle spielen.
> Ich nutze die letzte ISE Version.
Die 14.7
> Beim VHDL extras wird kein gray counter eingesetzt.
Der gc wird automatisch im FIFO instanziiert.
> dass die Empty flag um einen clock cycle verspätet kommt> und sich mein read enable und empty überlappen.
Das gibt es nicht, wenn du synchron ausliest.
Schau dir mal die FIFOs genau an, mit welchem Takt die Statussignale
rauskommen. Einige liegen auf der Read-Seite, andere auf der Write
Seite. Je nachdem was du machen und synchen willst, musst du die
rübersynchronisieren.
Sieh auch zu, dass der initiale Reset aus dem langsameren der beiden
Takte kommt und lange genug dauert.
> heißt nur halbe bandbreite beim lesen, oder?
Nein. Du kannst z.B. das "not empty" direkt auf das read drahten, um
einen permanenten Ausgang zu haben. Wie man das FIFO nutzt, hängt
allerdings von der Anwendung ab. Ich benutze oft die
Transportbandfunktion.
Jürgen S. schrieb:>> dass die Empty flag um einen clock cycle verspätet kommt>> und sich mein read enable und empty überlappen.> Das gibt es nicht, wenn du synchron ausliest.
Doch, es gibt bei den Flags ein anderes Timing. Entweder mit halber
Frequenz lesen/schreiben oder - deutlich eleganter - mit einem almost
empty/full ausbremsen. Die Almost-Flags können jeweils auf einen Versatz
von Eins eingestellt werden. Während eines Bursts also auf das jeweilige
Almost-Flag schauen, außerhalb des Bursts (ohne gleichzeitigen Zugriff)
auf empty bzw. full achten. Das geht tatsächlich nicht anders.
Erwähnenswert bei diesen FIFOs auch noch die Möglichkeit, auf beiden
Seiten verschiedene Wortbreiten zu verwenden (2^n, also z. B. 8 auf 16
oder 9 auf 36). Man muss dann auf die Endianity achten (Symbolfolge auf
der breiteren Seite).
Jürgen S. schrieb:> Der gc wird automatisch im FIFO instanziiert.
Beim FIFO aus der vhdl-extras library ist kein gray counter
implementiert, sondern ein handshake.
Die Coregen-FIFOs habe ich in aelteren ISE wegen irgendwas nicht
brauchen koennen, kann schon sein, dass da ein Szenario nicht abgedeckt
ist, dazu muesste man die Testbench/Simulation sehen.
Ein FIFO fuer den Spezialfall 'Paket-Streaming' musste schlussendlich
von Hand geschrieben werden, dabei sind Gray-Counter ein Muss. Da ging
auch erst was schief, eine Implementation die auf Xilinx 24/7 lief,
schmiss auf einer anderen Architektur sporadisch Fehler, warum das so
ist, ist Xilinx' kleines Geheimnis zu seiner RAM-Architektur. Auf jeden
Fall muss man akribisch drauf achten, dass die Almost-Full bzw.
Wassermarken-Flags aus den Gray-Countern hergeleitet werden, dann ist es
voll portabel und verifizierbar. Keine Ahnung, ob VHDL-extras das
richtig macht.
Der Spartan6 RAM-Bock mit der Initialisierung hat definitiv keine
Auswirkung auf FIFO-Verhalten.
Tim Z. schrieb:> dass die Empty flag um einen clock cycle verspätet kommt> und sich mein read enable und empty überlappen. Das heißt ja, dass ich> immer einen cycle warten muss um empty nach einem read zu prüfen. Das> heißt nur halbe bandbreite beim lesen, oder?
Falls es das bei bei deiner library gibt (bei Xilinx-FifoGen lässt es
sich definitiv konfigurieren), nutze einen First-Word-Fall-Through
(FWFT)-FIFO. Da ist das Verhalten von empty m.M. nach angenehmer. (Man
kann das negierte empty z.B. direkt auf das valid-Signal eines
AXI-Stream-Interface o.ä. verdrahten.)
Tim Z. schrieb:> Jürgen S. schrieb:>> Der gc wird automatisch im FIFO instanziiert.>> Beim FIFO aus der vhdl-extras library ist kein gray counter> implementiert, sondern ein handshake.
Aha!
dfIas schrieb:> Jürgen S. schrieb:>>> dass die Empty flag um einen clock cycle verspätet kommt>>> und sich mein read enable und empty überlappen.>> Das gibt es nicht, wenn du synchron ausliest.> Doch, es gibt bei den Flags ein anderes Timing. Entweder mit halber> Frequenz lesen/schreiben oder - deutlich eleganter - mit einem almost> empty/full ausbremsen.
Ich blicke das Problem nicht. Wenn das empty zeitrichtig (gfs
kombinatorisch) ausgewertet wird, bekomme ich durch die Ausleseseite
keine Lücke. Nur, wenn nichts drinsteht, lese ich leer.
VHDL hotline schrieb im Beitrag #7097950:
> nutze einen First-Word-Fall-Through> (FWFT)-FIFO. Da ist das Verhalten von empty m.M. nach angenehmer. (Man> kann das negierte empty z.B. direkt auf das valid-Signal eines> AXI-Stream-Interface o.ä. verdrahten.)
oder so!
Jürgen S. schrieb:> dfIas schrieb:>> Jürgen S. schrieb:>>>> dass die Empty flag um einen clock cycle verspätet kommt>>>> und sich mein read enable und empty überlappen.>>> Das gibt es nicht, wenn du synchron ausliest.>> Doch, es gibt bei den Flags ein anderes Timing. Entweder mit halber>> Frequenz lesen/schreiben oder - deutlich eleganter - mit einem almost>> empty/full ausbremsen.> Ich blicke das Problem nicht. Wenn das empty zeitrichtig (gfs> kombinatorisch) ausgewertet wird, bekomme ich durch die Ausleseseite> keine Lücke. Nur, wenn nichts drinsteht, lese ich leer.
Das Empty kann meist nicht "zeitrichtig" ausgewertet werden, es kommt
einen Clock zu spät. Somit "unterliest" du das FIFO, wenn der
vorangegangene und der aktuelle Clock das Read aktiv halten (Burst).
Die Flaglogik muss während des Lesens auf Füllstand > 1 schauen (not
almost empty), außerhalb des Lesens auf Füllstand > 0 (not empty).
Analog dazu gilt beim Schreiben der Vergleich gegen Füllstand < Full - 1
(not almost full) oder Füllstand < Full (not full).
Mit halber Clockfrequenz schaffen es Empty/Full bis zum nächsten aktiven
Read/Write - das wäre die einfachere Implementation, wenn die Bandbreite
ausreicht. Andererseits ist es nicht sehr schwierig, die Almost-Flags
passend zu konfigurieren und auszuwerten.
Das Empty_1 ist aktiv bei Füllstand 0 und 1, Empty nur bei Füllstand 0.
Das Read muss als Signal definiert werden, damit man es auch lesen kann.
Bei vorangegangenem Read muss man quasi "einen im Sinn" haben.
Zumindest bei den Xilinx-FIFOs ist ein underrun (lesen bei empty=1) kein
Problem, sondern wird einfach ignoriert. D.h. man muss das Read nicht
zwingend von Empty abhängig machen, sondern nur auf die Validität der
ausgelesen Daten achten.
dfIas schrieb:> Das Empty kann meist nicht "zeitrichtig" ausgewertet werden, es kommt> einen Clock zu spät.
Ist aber kombinatorisch und kann direkt verwendet werden. Dass man mit
dem Takten seiner FSM nicht hinkommt, kann natürlich sein. Das liegt
aber darin, dass die Erzeugung des Empty einen Vergleich erfordert, der
bei breiten Countern sehr aufwändig ist und die Zeit hochtreibt. Die
Auswertung kann damit nur im nächsten Tag erfolgen, wenn die FPGA -
Frequenz zu hoch wird.
Nutzung des AlmostEmpty klappt dann auch nicht, wenn man den Takt
gewinnen will, weil man nicht weis, ob was eingeschrieben wird und er
wirklich empty wird.
Ich mache das daher so, dass ich die FIFOs im Zweifel unterlese und ein
Valid IM Fifo-Vektor mitschleppe.