Forum: FPGA, VHDL & Co. Memory Arbiter - Ideen sammeln


von Holger K. (holgerkraehe)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich möchte gerne ein SDRAM mittels Wishbone Bus an einem virtuellen uC 
(also einem als VHDL-File) und einem VGA-Controller betreiben.

Ziel soll sein, der VGA Controller hat fixe Speicherbereiche für LayerA 
und LayerB. Über ein Signal wird dem VGA-Controller mitgeteilt, dass er 
den Speicherbereich ändern soll.

Der uC schreibt seine Bilddaten auch in den RAM.
Nun müssen ja beide mit dem RAM kommunizieren können.
Meine frage ist nun, wie könnte solch ein Arbiter aufgebaut werden?

Anbei habe ich ein Bild aus einem Pdf
(http://www.es.ele.tue.nl/premadona/files/akesson01.pdf)

Ich verstehe die Idee, dass da jedes Device seine Requests deponiert und 
die nacheinander oder je nach Algo abgearbeitet werden.

Mein Problem ist momentan noch dieses Konzept mit dem Wishbone zu 
vereinen.
Meldet der SDRAM Controller dann einfach STALL wenn der VGA zugreift und 
der uC auch möchte und der uC muss quasi pollen bis der RAM frei ist?

Oder wie löst man sowas?

Danke

von Duke Scarring (Gast)


Lesenswert?

Holger K. schrieb:
> Meldet der SDRAM Controller dann einfach STALL wenn der VGA zugreift und
> der uC auch möchte und der uC muss quasi pollen bis der RAM frei ist?
So könnte man das lösen.
Alternativ habe ich auch schon eine CPU so lange angehalten, bis der 
Speicher wieder lesbar war.

> Oder wie löst man sowas?
Evtl. kann man auch den SDRAM schneller laufen lassen, so das mehrere 
Zugriffe pro Zeiteinheit möglich sind.

Oder man cacht eine ganze VGA-Zeile und hat dann das Interface bis kurz 
vorm nächsten VSYNC zur freien Verfügung.

Natürlich kann man auch der CPU einen Cache spendieren...

Die Lösung ist also sehr Applikationsabhängig.

Duke

von Holger K. (holgerkraehe)


Lesenswert?

Duke Scarring schrieb:
> Holger K. schrieb:
>> Meldet der SDRAM Controller dann einfach STALL wenn der VGA zugreift und
>> der uC auch möchte und der uC muss quasi pollen bis der RAM frei ist?
> So könnte man das lösen.
> Alternativ habe ich auch schon eine CPU so lange angehalten, bis der
> Speicher wieder lesbar war.
>
>> Oder wie löst man sowas?
> Evtl. kann man auch den SDRAM schneller laufen lassen, so das mehrere
> Zugriffe pro Zeiteinheit möglich sind.
>
> Oder man cacht eine ganze VGA-Zeile und hat dann das Interface bis kurz
> vorm nächsten VSYNC zur freien Verfügung.
>
> Natürlich kann man auch der CPU einen Cache spendieren...
>
> Die Lösung ist also sehr Applikationsabhängig.
>
> Duke

Vielen Dank für deine Antwort.

Dann bin ich also nicht ganz auf dem Holzweg.

Die Applikation ist ja soweit beschrieben.
Das RAM dient lediglich als Bildspeicher. Wobei zweit Bilder vorhanden 
sein sollen.

Der uC schreibt in den einen Speicherbereich und gibt dann dem 
VGA-Controller den Befehl zum wechseln der Speicheradresse.

Angezeigt soll ein GUI werden.


Freue mich über weitere Inputs, Anregungen, Kommentare.

Danke

von Markus F. (mfro)


Lesenswert?

SDRAM im Burst ist (wahrscheinlich) deutlich schneller, als dein 
VGA-Controller das gebrauchen kann. Außerdem liest er ja soweiso nur.

Ich würde deswegen einen (möglichst großen) FIFO anlegen und den bei 
niedrigem Füllstand im Burst füllen, dann wirst Du bei deinen sonstigen 
RAM-Aktivitäten möglichst wenig gestört.

von Dr. Sommer (Gast)


Lesenswert?

Vielleicht hilft's ja: Die TI Sitara AM335x Prozessoren machen es genau 
so mit dem LCD-Controller (funktioniert letztendlich genau wie ein 
VGA-Controller aber ohne DAC). Der LCD-Controller hat eine eigene 
DMA-Einheit und greift darüber auf den Prozessorbus zu. Somit können CPU 
und LCD beide auf den SDRAM-Controller ("EMIF") zugreifen. Dieser 
besitzt FIFOs für die Operationen. Die Software konfiguriert im 
Controller die gewünschte Adresse für den Framebuffer. VHDL-Code gibt's 
dafür aber wohl eher nicht... ;-)

von Holger K. (holgerkraehe)


Lesenswert?

Markus F. schrieb:
> Ich würde deswegen einen (möglichst großen) FIFO anlegen und den bei
> niedrigem Füllstand im Burst füllen, dann wirst Du bei deinen sonstigen
> RAM-Aktivitäten möglichst wenig gestört.

Das würde aber bedeuten, dass dies nicht über den Wishbone geht oder?
Ausser der VGA FIFO wäre ein SLAVE und der RAM Controller SLAVE 
gegenüber dem uC und Master gegenüber dem VGA.

Ich meine damit nicht, dass das so nicht ginge.
Dein Ansatz wäre sogar eine gute Lösung.
Ich versuche nur herauszufinden, ob du den Wishbone im hinterkopf 
hattest oder nicht.

Dr. Sommer schrieb:
> Vielleicht hilft's ja: Die TI Sitara AM335x Prozessoren machen es genau
> so mit dem LCD-Controller (funktioniert letztendlich genau wie ein
> VGA-Controller aber ohne DAC). Der LCD-Controller hat eine eigene
> DMA-Einheit und greift darüber auf den Prozessorbus zu.

Wo wird dann aber der Zugriff von LCD und uC geregelt?

von Dr. Sommer (Gast)


Lesenswert?

Holger K. schrieb:
> Wo wird dann aber der Zugriff von LCD und uC geregelt?

Ich meine das macht der Prozessor-Bus an sich schon ("OCP"). Die 
Datenblätter und Reference Manuals sind alle online, da kannst du dir 
ansehen wie es funktioniert...

von Holger K. (holgerkraehe)


Lesenswert?

Dr. Sommer schrieb:
> Ich meine das macht der Prozessor-Bus an sich schon ("OCP"). Die
> Datenblätter und Reference Manuals sind alle online, da kannst du dir
> ansehen wie es funktioniert...

Ok schaue ich mir mal an. Danke.

Falls noch jemand Vorschläge etc. hat. Bitte her damit :)

von Markus F. (mfro)


Lesenswert?

Holger K. schrieb:
> Das würde aber bedeuten, dass dies nicht über den Wishbone geht oder?
> Ausser der VGA FIFO wäre ein SLAVE und der RAM Controller SLAVE
> gegenüber dem uC und Master gegenüber dem VGA.
>
> Ich meine damit nicht, dass das so nicht ginge.
> Dein Ansatz wäre sogar eine gute Lösung.
> Ich versuche nur herauszufinden, ob du den Wishbone im hinterkopf
> hattest oder nicht.

Abhängig davon, wie dein RAM angebunden ist, würde ich den 
"Video-Ausgang" unabhängig von deinem Wishbone-Bus wahrscheinlich als 
völlig separate "Anzapfung" realisieren.

Wenn Du z.B. 266 MHz DDR-RAM hättest, könntest Du bei einigermaßen 
geschickter Umsetzung das RAM-seitige FIFO-Ende direkt mit der daraus 
resultierenden Bandbreite bespaßen (das andere Ende wird mit dem 
VGA-Pixeltakt ausgelesen) während dein Wishbone-Bus (wahrscheinlich) 
wesentlich gemächlicher getaktet wäre.

Wenn Du das einigermaßen geschickt machst, wird dein µC wahrscheinlich 
kaum was von dem extra "RAM-Bandbreitenschmarotzer" mitbekommen.

von Holger K. (holgerkraehe)


Lesenswert?

Danke für deine Antwort.

Dein Vorschlag ist vermutlich am einfachsten umzusetzen.
Dann würde also der VGA-Controller über ein eigenes Interface z.B. die 
StartAdresse und die anzahl Words mitteilen.
Nun befüllt der Arbiter automatisch ein bestimmtes Array mit den Daten 
aus diesem Speicherbereich. Setzt eine Leitung high zum signalisieren 
dass fertig.
Der VGA bedient sich nun dieses Buffers.
Vermutlich braucht es zwei buffer, damit der VGA nicht auf dem trockenen 
sitzt. Somit würde der VGA beim wechsel auf den zweiten buffer das 
befüllen des ersten in "Aufrag" geben.

Wenn nun eine uC Anfrage über den wishbone an den arbiter kommt, während 
der Buffer befüllt wird, wird einfach ein stall signalisiert.

Ich denke mal in etwa so hast du dies gemeint?

von Markus F. (mfro)


Lesenswert?

Holger K. schrieb:
> Ich denke mal in etwa so hast du dies gemeint?

So ungefähr.

Holger K. schrieb:
> Vermutlich braucht es zwei buffer, damit der VGA nicht auf dem trockenen
> sitzt. Somit würde der VGA beim wechsel auf den zweiten buffer das
> befüllen des ersten in "Aufrag" geben.

Das ist gar nicht notwendig. Dein FIFO braucht nur ein "low watermark" 
Signal (die gängigen IPs haben dafür meist schon einen "almost 
empty"-Ausgang), das rechtzeitig vor dem Leerlaufen aktiv wird und alle 
anderen Aktivitäten deines Memory-Controllers unterbricht. Dann wird 
"mit Vollgas" frisch befüllt und anschließend wieder (gemächlich) da 
weitergemacht, wo unterbrochen wurde.

von Holger K. (holgerkraehe)


Lesenswert?

Markus F. schrieb:
> Das ist gar nicht notwendig. Dein FIFO braucht nur ein "low watermark"
> Signal (die gängigen IPs haben dafür meist schon einen "almost
> empty"-Ausgang), das rechtzeitig vor dem Leerlaufen aktiv wird und alle
> anderen Aktivitäten deines Memory-Controllers unterbricht. Dann wird
> "mit Vollgas" frisch befüllt und anschließend wieder (gemächlich) da
> weitergemacht, wo unterbrochen wurde.

Nun, der MemoryController wurde von mir selbst geschrieben.
Daher weiss ich, dass er keine solche Funktion hat. Zumindest bisher.

Aus aktueller sicht, ist für mich die Implementierung zweier Buffer 
etwas einfacher. Obwohl dies prinzipiell ja nichts anderes ist, als das 
von dir beschrieben Verhalten. Mit der Ausnahme, dass mein FIFO in zwei 
Buffer aufgeteilt wurde.

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.