Hallo,
ich würde in VHDL gerne eine Art Ringpuffer realisieren, bei dem es
möglich ist, dass die write und read pointer nicht immer direkt auf die
nächste Adresse zeigen sondern jeweils ein offset zur letzten Adresse
haben können.
Die Abfolge der Adressen ist fix und hängt nur von der gesamt Anzahl der
Adressen ab.
Etwas blöd zu erklären, also versuch ich es mal an einem kleinen
Beispiel:
Angenommen wir haben insgesamt 6 Adressen. Dann sollen die Adressen wie
folgt abgelaufen werden.
1.Umlauf 2.Umlauf 3.Umlauf 4. Umlauf 5. Umlauf
write Adressen: 1 2 3 4 5 6 1 3 5 2 4 6 1 3 5 2 4 6 usw.
read Adressen : 1 3 5 2 4 6 1 3 5 2 4 6 1 3 5 usw.
Wie könnte ich so etwas am besten realisieren so dass es auch bei hohen
Taktraten (> 200 MHz) noch funktioniert. Die gesamt Anzahl der Adressen
kanns sich ändern wird aber immer 2ˆn sein (2 4 8 16 32 64...)
Kann mir jeamnd ein kurzes Code Beispiel schreiben?
Vielen Dank!
sehe ich es richtig, dass Du ein einem etwas schreiben willst und im
anderen etwas auslesen willst?
z.B. mit einem anderen Prozess? Was hälst Du davon ein DualPort Ram zu
nehmen?
Thomas schrieb:> read Adressen : 1 3 5 2 4 6 1 3 5 2 4 6 1 3 5 usw.
Wann findet denn da die Umschaltung von gerade nach ungerade statt?
Immer am "Ende" des "Rings"? Ist dir klar, das ein Ring per Definition
eigentlich kein Ende hat?
> Kann mir jeamnd ein kurzes Code Beispiel schreiben?
Ist das jetzt dein Ernst?
Wofür brauchst du das?
Was ist dein Speicher?
Du könntest immer das Ende eines Durchlaufs erkennen, also wann die
höchste Addresse erreicht wurde und dann das um 1 verschieben.
Also du nutzt ja jede 2. Addresse, also 1. Durchlauf:
1 3 5 7 9 ... 1023, Ende erkennen, also ein einziges Mal eine Addresse
um 1 oder 3 erhöhen, dann zweiter Durchlauf
2 4 6 8 ... 1024, wieder Ende erkennen.
Tja und das musst du halt für Lese- und Schreiboperation so bauen, dass
die jeweils das gewünschte bekommen.
Ich sehe darin nur keinen Sinn?!
Willst du den Speicher für zwei Operationen aufteilen? Vielleicht kannst
du dann der einen generell alle geraden und der anderen alle ungeraden
Addressen geben, einfacher wäre es aber jeder seinen Addressbereich zu
geben.
Also erkläre mal wozu du das brauchst, man kann es vermutlich anders
lösen.
Ach so, ja, man würde dann lesen und schreiben bei entweder geraden oder
ungeraden Addressen machen und eben nicht versetzt. Also muss man doch
verschieben wie ich oben schrieb.
Und damit lesen und schreiben jeweils die anderen Adressen nutzen müsste
man die Zahl der Durchläufe zählen oder irgendwie etwas bauen das sagt
was gerade die garaden und was die ungeraden Addressen nutzen soll.
Das Problem weshalb das aber nicht Sinnvoll ist:
Wenn der Puffer eben eben nicht voll ist, also nur langsam geschrieben
wird, dann müsste man mit dem Lesen immer warten. Also man schreibt
zuerst alle ungeraden Addressen und erst danach beginnt man diese zu
lesen und schreibt die geraden Addressen. Also eher sehr komisch.
Mir ist aber immer noch nicht klar wozu das nützlich sein soll.
Lothar Miller schrieb:> Und wer macht dann den Überlauf?
Ich hab leider keine Ahnung von VHDL, ich hab nur etwas nachgedacht und
bin darauf gekommen. Vielleicht hat es ihm ja etwas genutzt.
lg
Christopher B. schrieb:> Ich hab leider keine Ahnung von VHDL, ich hab nur etwas nachgedacht und> bin darauf gekommen.
Mit VHDL wird Hardware beschrieben. Und aus VHDL wird dann letztliche
Hardware gemacht. Nur gibt es in richtiger Hardware eben keinen Zähler,
der so einfach und von sich aus an einer 2^n-1 Grenze überlaufen würde.
Thomas schrieb:
> 1.Umlauf 2. 3. 4. 5. Umlauf> write Adressen: 1 2 3 4 5 6 1 3 5 2 4 6 1 3 5 2 4 6 usw.> read Adressen : 1 3 5 2 4 6 1 3 5 2 4 6 1 3 5 usw.
Wenn man den ersten Durchlauf/Initialisierung weglassen könnte, dann
wäre das unglaublich einfach: ein stinknormaler Ringpuffer ohne Offest
und sonstwas. Denn dann ist die Schreibreihenfolge gleich der
Lesereihenfolge:
> write Adressen: 1 3 5 2 4 6 1 3 5 2 4 6 usw.> read Adressen : 1 3 5 2 4 6 1 3 5 2 4 6 1 3 5 usw.
Schreibreihenfolge: 135246135246
Lesereihenfolge: 135246135246
Vom Adresszähler (Counter) wird das 3. Bit (q3)mit dem 0. Adressbit (A0
write) des write-Adressbusses des Dual Port RAMs verbunden, das
invertierte 3. Bit (/q3) mit dem 0. Adressbit (A0 read) des
read-Adressbusses.
Ich würde da einfach mal behaupten, dass dieser "Ringpuffer in
Wirklichkeit ein Fifo ist. Und bei einem Fifo sollten aber m.E. die
Schreib und Leseadressen unabhängig sein. Deshalb sollte es da 2
Adresszähler geben...
Oder ist da tatsächlich eine starre Kopplung benötigt?
Es stellt sich also die Frage:
Thomas schrieb:> ich würde in VHDL gerne eine Art Ringpuffer realisieren
WOFÜR?
Hallo,
also erst mal danke für die vielen Antworten.
Entschuldigung für die Verwirrung, das Beispiel sollte nur das Prinzip
zeigen. Später werden die write und read adressen nicht mehr durch
einfaches +2 erzeugt werden können.
Dann mal was ich machen möchte.
Ich bekomme in einzelnen Streams Rohdaten in falscher Reihenfolge. Ich
möchte die Rohdaten "on the fly" in die richitge Reihenfolge bringen
bevor ich sie weiter verabeiten kann. Das heisst mit minimalem BRAM
verbrauch.
Beispiel: Rohdaten bestehen insgesamt aus 20 Bit
Stream 1: Eingang 1 3 5 7 9 2 4 6 8 10
Stream 2: Eingang 11 13 15 17 19 12 14 16 18 20
Sortieren: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
(dies ist nur ein Beispiel, die Reihenfolge der Daten am Eingang kann
auch ander aussehen)
Ich würde gerne wissen wie ich die Sortierung am besten mache.
Da ich eben so wenig BRAM wie möglich verwenden möchte, dachte ich mir
ich nehme eine Art Ringpuffer (ich weiss der hat eigentlich kein Ende
deshalb so eine Art wie ... ) der genau so groß ist dass ich nur die
mindest Anzahl an Bits reinschreibe um sortieren zu können und dann die
freien Speicherplätze wieder verwende.
Also für das Beispiel oben wäre das ein Speicher für 7 Bits (evt.
klappts auch schon mit 6) dann schreibe ich
1 3 5 7 9 und 2 rein (ein Platz ist noch frei)
dann lese ich die 1 aus und schreibe die gerade kommende 4 an die noch
frei Stelle.
dann lese ich die 2 aus und schreibe die gerade kommende 6 an die Stelle
wo fühere die 1 stand
nun lese ich die 3 aus und schreibe die greade kommende 8 and die Stelle
wo fühere die 2 stand
usw. und so fort.
Ich bin mir nur nicht sicher wie ich das am besten mach, damit das auch
bei hohen Taktraten klappt.
Viele Grüße
Natürlich noch ein bischen Logik drumherum z.B. ein Counter der die
Richtige anzahl der bits Abzählt bzw. mit Komperator für den Alarmwert
bzw. die FFs nicht fest verdrahten sondern über programmierbare
Multiplexer usw.