Hallo, ich habe einen "circular fifo" in VHDL (512 Byte) und ich brauche eine Bedienung für BufferFull (es wird noch 6 byte freigelassen) und BufferEmpty. BufferEmpty ist einfach: IF(Addresse1=Adresse2)THEN Bufferempty=1; BufferFull fällt mir nichts anderes ein , als sowas zu schreiben: If( (Adresse1=Adresse2+7) OR (Adresse1=505 AND Adresse2=0) OR (Adresse1=506 AND Adresse2=1) usw... D.h. ich muss jede Adresskombination erwähnen, weil der Nulldurchgang bei (Adresse1=Adresse2+7) nicht funktioniert. Das sieht aber sehr unübersichtlich aus. Gibt es eine elegante Lösung dafür?
Man könnte der Antwort von VHDL noch folgende Erklärung hinzufügen. Der Teilsatz: "weil der Nulldurchgang ... nicht funktioniert" trifft so nicht zu. Stichwort ist hier die Modulo-Arithmetik. Ohne das im Einzelnen auszuführen, kann man sagen, dass sowohl die Differenz, als auch die Summe in der Modulo-Arithmetik immer stimmen. Auch in den Fällen wo eine Differenz auf den ersten Blick negativ ist. Denn, wenn die Zähler mit der Bitbreite deklariert sind, die nötig ist, dann werden die höherwertigen Bits der Differenz einfach "abgeschnitten". Die verbleibenden unteren Bits aber geben korrekt die Differenz (aber eben nur einen Teil davon) an. Man kann sich das selbst leicht verdeutlichen, in dem man sich einen zirkularen Rechenschieber denkt. Die zirkulare Eigenschaft des Rechenschiebers verwirklicht die Modulo-Arithmetik.
ABSD schrieb: > If( (Adresse1=Adresse2+7) Addierer gesucht... if ((adresse+1) mod Puffergröße) = adresse2 then BufferIstVoll oder? W.S.
Solange deine FIFO-Größe 2^x ist, funktioniert wie beschrieben die Differenz. Das liegt an dem, was man in der Arithmetik als Ring bezeichnet. Man kann sich das auch gut bildlich vorstellen. Stell dir eine runde Uhr vor, mit dem Ziffernblatt 1-12. Die Differenz zwischen zwei Zeiten kann dann einfach über die Differenz der Uhrzeiten berechnet werden. So z.B. als Trivialbeispiel, von 3 Uhr bis 4 Uhr ist eine Stunde Unterschied entspricht 4(Uhr) - 3(Uhr) = +1(Stunde). Interessant wird es beim Nulldurchgang (also der 12 auf dem Ziffernblatt): z.B. von 4 Uhr bis (zum nächsten) 3 Uhr sind es logisch 11 Stunden Unterschied, entspricht mathematisch 3(Uhr) - 4(Uhr) = -1. Jetzt gehst du vom Nullpunkt (12 Uhr) also 1 zurück (da -1) und landest bei: (+)11, der gesuchten Differenz. Bei der Uhr klappt es ohne 2^x, im binären werden diese Ringe halt bei 2^x aufgespannt. Der Nullpunkt ist da auch wirklich 0 ;-) . Um komplexere Rumrechnerei zu ersparen, sollte man Eigenbau-FIFOs also möglichst 2^x Einträge groß machen.
Einfacher geht's, wenn du neben den Lesezeiger(LZ) und Schreibzeiger (SZ) noch einen weiteren Full-Zeiger (FZ) einführst: FZ = SZ + 6 (6: Deine Reserve). FZ wird dann immer mit SZ geändert. Damit: Empty = (WZ equal LZ) Full = (FZ equal LZ)
Im Ringspeicher nähert er sich von hinten an den Lesezeiger. Er ist einer Runde rum. full when write_zeiger-1=read_zeiger
René D. schrieb: > Im Ringspeicher nähert er sich von hinten an den Lesezeiger. Er ist > einer Runde rum. > > full when write_zeiger-1=read_zeiger Ich muss korrigieren, ich hatte deinen Text nicht voll gelesen. Du must den Typ unsigned nehmen. wenn dein Adresscounter vom typ unsigend (8 downto 0) ( entspricht den Wertebereich 0...511) ist, kannst du den Overflow nutzen. Dann ist 0-1=511 1-2=511 1-3=510
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.