Forum: FPGA, VHDL & Co. Frame-Synchronisierung für VGA


von S. R. (svenska)


Angehängte Dateien:

Lesenswert?

Hi,

ich habe einen VGA-Controller in VHDL gebaut (für einen Spartan 6, 
Pixeltakt 50 MHz), der die Pixeldaten linear anfordert und darstellt. 
Wenn die Daten schnell genug ankommen, funktioniert das auch.

Jetzt möchte ich den Frame in einem SDRAM ablegen, welches gleichzeitig 
für andere Dinge genutzt wird und gelegentlich länger braucht. Also habe 
ich einen FIFO in den Controller gebaut. Das Bild (vorerst noch 
taktgenau generiert) ist jetzt zwar wunderbar stabil, aber leicht nach 
rechts verschoben.

Meine Frage ist: Wie synchronisiere ich FIFO und Ausgabe am besten 
miteinander? Langfristig soll der Pixeltakt auch in seine eigene 
Taktdomäne, dann sind "FIFO lesen" und "FIFO schreiben" auch noch 
asynchron zueinander. Wie geht man bei sowas am besten vor?

Mein jetziger Code im Anhang. Für Hinweise bin ich dankbar. ;-)

Gruß,
Svenska

von Duke Scarring (Gast)


Lesenswert?

S. R. schrieb:
> Wie synchronisiere ich FIFO und Ausgabe am besten
> miteinander?
Wenn das Bild unter allen Umständen stabil bleiben soll, müssen immer 
wenn Pixeldaten gebraucht werden, auch welche im FIFO sein.
Die Daten müssen also rechtzeitig angefordert werden.
Ich würde einen FIFO mit 'almost empty'-Flag bauen, der das Nachladen 
der Pixeldaten triggert.
Die Synchronisation könnte stattfinden, wenn Du rechts unten bist. Da 
bleibt ein kompletter Rücklauf von unten nach oben Zeit, um den FIFO zu 
leeren und mit neuen Daten für das nächste Frame zu füllen...

Duke

von J. S. (engineer) Benutzerseite


Lesenswert?

Wann da ein anderer Takt verwendet iwrd, gibt es 2 Synch-Anforderungen: 
Die des Taktes gegen den Fifo und den anderen Takt sowie die der 
Bildsynchronisiation. Das kann man mit einem asnchronen FIFO 
bewerkstelligen, wenn man den ausreichend gross macht. Kommt drauf an, 
wie lange das RAM belegt ist. Ich verwende sowas bei meinem 
Zeichengenerator:

Projekt VGA Core in VHDL

von S. R. (svenska)


Lesenswert?

Duke Scarring schrieb:
> Wenn das Bild unter allen Umständen stabil bleiben soll, müssen immer
> wenn Pixeldaten gebraucht werden, auch welche im FIFO sein.

Logisch. Wobei ich auch damit zufrieden wäre, wenn ein Unterlauf den 
Rest des Bildes zerstört. Dann sieht man, wenn man es mit der Bandbreite 
übertrieben hat. ;-) Wichtig ist nur, dass es sich zügig wieder fängt.

Duke Scarring schrieb:
> Ich würde einen FIFO mit 'almost empty'-Flag bauen, der das Nachladen
> der Pixeldaten triggert.

Mein FIFO ist nicht riesig (ein BlockRAM, also etwa anderthalb Zeilen) 
und hält sich unabhängig von der Ausgabe selbst dauerhaft gefüllt 
('almost full'-Flag). Dein Vorschlag läuft darauf hinaus, dass der FIFO 
in jedem Frame leerläuft und von der eigentlichen Ausgabe neu getriggert 
wird, richtig? Hmm, muss ich mal drüber nachdenken.

Jürgen S. schrieb:
> Kommt drauf an, wie lange das RAM belegt ist.

Das kann ich nicht einschätzen, da ich mit SDRAM (kein DDR) keine 
Erfahrung habe. Im Internet habe ich einen einfachen Core gefunden, der 
zwei Ports zur Verfügung stellt und Lesezugriffe priorisieren kann. Was 
der Spartan6 Memory Controller kann, weiß ich ebenfalls nicht.

Vermutlich wird das aber auf 3-4 Blöcke hinauslaufen, die sich den 
Speicher teilen müssen (Videosignal, CPU, bisschen Kleinkram). Da ich 
noch kein genaues Ziel vor Augen habe, ist das nicht ganz so wild.

von Duke Scarring (Gast)


Lesenswert?

S. R. schrieb:
> die sich den
> Speicher teilen müssen (Videosignal, CPU, bisschen Kleinkram).
Ich hatte das mal nur mit Video und CPU-Zugriff gebaut. Die CPU-Zugriffe 
wurden immer bis zum Zeilenrücklauf verzögert. Das ging auch ohne FIFO 
:-)
Natürlich ist dann die Bandbreite zwischen CPU und Videospeicher arg 
limitiert...

Duke

von Christian B. (casandro)


Lesenswert?

Es gibt ein Buch namens "TV Typewriter Cookbook" (inzwischen als PDF von 
der Website des Autors herunterladbar) da werden solche Sachen 
besprochen und wie man das umgeht.

Ein FIFO an der Stelle ist etwas ungünstig, da der mit hohen Taktraten 
arbeiten muss, und es schwierig ist, den immer aufgefüllt zu halten. Was 
ist, wenn die CPU dem Graphikteil keine Zeit lässt?

Die gängige Technik ist es, dem Videoausgang immer Speicherzugriffe zu 
erlauben. Der Rest der Schaltung darf dann nur darauf zugreifen, wenn 
Zeit ist. (z.Bsp während den Austastlücken, etc)

Im Textmodus kannst Du eine Zeile "lokal" speichern und musst somit nur 
für jede Textzeile auf den externen Speicher zugreifen. Dann hast Du 
mehr Zeit für den Rest der Schaltung.

Was man früher auch gemacht hat, ist einfach Zugriffe von der CPU zu 
priorisieren und dann während der Zeit nichts auszugeben. Dabei ist es 
aber wichtig, dass alle Zähler für den Graphiktakt weiterlaufen. Man 
sieht dann halt kaputte Pixel während des Zugriffes. Speichert man 
zusätzlich noch die letzte Zeile im FPGA, so kann man dort auch die 
vorherige Zeile darstellen, was die Störung weniger auffällig macht.

von Markus F. (mfro)


Lesenswert?

S. R. schrieb:
> Das Bild (vorerst noch
> taktgenau generiert) ist jetzt zwar wunderbar stabil, aber leicht nach
> rechts verschoben.

wenn das Bild nach rechts verschoben ist, sind wahrscheinlich deine 
Pixeldaten aus dem FIFO gegenüber der Schwarzschulter versetzt. 
Dementsprechend wirst Du wohl HSYNC um die FIFO-Latenz verzögern müssen?

von S. R. (svenska)


Lesenswert?

Duke Scarring schrieb:
> Die CPU-Zugriffe wurden immer bis zum Zeilenrücklauf verzögert.

Wenn dein Speicher schnell genug ist, geht das prima. Davon gehe ich 
aber gerade nicht aus (SDRAM ist für Einzelzugriffe nicht schnell, aber 
mit Burstzugriffen schon).

Christian B. schrieb:
> Ein FIFO an der Stelle ist etwas ungünstig, da der mit hohen Taktraten
> arbeiten muss, und es schwierig ist, den immer aufgefüllt zu halten.

Was ist daran (innerhalb des FPGAs) schwierig?

> Was ist, wenn die CPU dem Graphikteil keine Zeit lässt?

Dann geht das Bild halt mal kaputt. Damit kann ich leben.
Oder ich vermeide es.

Markus F. schrieb:
> wenn das Bild nach rechts verschoben ist, sind wahrscheinlich deine
> Pixeldaten aus dem FIFO gegenüber der Schwarzschulter versetzt.

FIFO und Bildausgabe sind bisher überhaupt nicht miteinander 
synchronisiert. Die Latenz zwischen beiden ist nicht fix, deswegen ist 
eine einfache Verzögerung nicht hilfreich...

: Bearbeitet durch User
von Christian B. (casandro)


Lesenswert?

Egal was Du machst, bedenke immer, dass Du ein korrektes Synchronsignal 
ausgeben musst, komme was wolle. Wenn Du einmal kurz einen Aussetzer 
drin hast, kannst Du davon ausgehen, dass die meisten Monitore heute 
mehrere Sekunden brauchen werden, um sich auf zu synchronisieren.

von S. R. (svenska)


Angehängte Dateien:

Lesenswert?

Duke Scarring schrieb:
> Die Synchronisation könnte stattfinden, wenn Du rechts unten bist.

Das habe ich jetzt so gemacht und es funktioniert. Siehe Anhang.

Wenn das letzte Pixel (unten rechts) ausgegeben wird, wird der FIFO 
aktiviert und fordert das erste Pixel (oben links) an. Ab dann fordert 
er alle weiteren Pixel dieses Frames an (solange Platz ist) und schaltet 
sich dann ab. Die Bildausgabe saugt den FIFO dann komplett leer und 
aktiviert ihn mit dem letzten Pixel erneut.

Ob sich das Teil wieder fängt, wenn der FIFO zwischendurch mal leer 
läuft, hab ich nicht getestet.

Die ganze Ausgabe ist übrigens im Prinzip unabhängig von der Auflösung. 
Es sollte an sich kein Problem sein, den Modus dynamisch einzustellen 
(solange der Pixeltakt passt).

Christian B. schrieb:
> Egal was Du machst, bedenke immer, dass Du ein korrektes Synchronsignal
> ausgeben musst, komme was wolle.

Im Gegensatz zu einem Controller ist das auf einem FPGA absolut kein 
Problem. Die Sync-Signale sind immer perfekt, da sie unabhängig vom 
Bildinhalt generiert werden. Für eine Störung muss da schon der Takt 
komplett ausfallen, aber dann spielt der Bildinhalt auch keine Rolle 
mehr. ;-)

edit: Datei vergessen. :-/

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

S. R. schrieb:
> FIFO und Bildausgabe sind bisher überhaupt nicht miteinander
> synchronisiert. Die Latenz zwischen beiden ist nicht fix, deswegen ist
> eine einfache Verzögerung nicht hilfreich...

die Latenz zwischen beiden muss m.E. fix sein (natürlich nur, wenn der 
FIFO nicht leerläuft), sonst hätte der TO höchstwahrscheinlich gar kein 
stabiles Bild ...

von S. R. (svenska)


Lesenswert?

Ich bin der TO. ;-)
Hast aber recht, die Latenz zwischen FIFO und Pixeldaten ist fest (1 
clk), aber die Latenz zwischen FIFO und Speicher ist es ziemlich sicher 
nicht.

von Duke Scarring (Gast)


Lesenswert?

S. R. schrieb:
> Hast aber recht, die Latenz zwischen FIFO und Pixeldaten ist fest (1
> clk), aber die Latenz zwischen FIFO und Speicher ist es ziemlich sicher
> nicht.
Dafür hast Du ja jetzt den (das?) FIFO :-)

Duke

von S. R. (svenska)


Lesenswert?

Duke Scarring schrieb:
> Dafür hast Du ja jetzt den (das?) FIFO :-)

Genau. Bleibt nur die Frage, ob (wie) man das noch besser machen kann. 
Aber im Augenblick reicht mir das, jetzt müssen erstmal andere Teile des 
Systems entstehen.

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.