Hallo,
ich habe ein Problem bezüglich der Bildverarbeitung in einem FPGA.
Ziehl ist es ein Graustufenbild einer Kamera (288*384 50Hz) in einem
FPGA einzulesen, und auf einem TFT Bildsschirm auszugeben (640*480
60Hz).
Beide schnittstellen wurden bereits erfolgreich Implementiert, d.h. ich
kann ein Bild einlesen und ein Testbild ausgeben.
Aufrund der Bildverarbeitung, hab ich vor, dass empfangene Bild zwischen
zu speichern. Dies wollte ich auf grund der Größe des Bildes in einem
externen Speicher machen (SRAM oder DDR2). Da später eine Mittelung über
mehrere Bilder vorgenommen werden soll, werde ich wohl nicht ohne
externen Speicher auskommen.
Mein Problem besteht nun darin wie ich gewährleisten kann, dass das
eingelesene Bild im speicher abgelegt wird und auch die Ausgabe
erfolgreich das Bild wieder laden kann, ohne Timing probleme. Zudem ist
die Bildfrequenz des auszugebenden Bildes auch hoher, als die des
einzulesenden Bildes.
Ist der DDR2 speicher hier schnell genug, sodas ich mir da keine sorgen
machen muss? Oder reicht dazu auch ein SRAM aus?
Ich möchte kein Qellcode, sondern anregungen wie man soetwas am besten
realisieren kann (eventuell Blockschaltbild).
Ich habe noch sehr wenig bis keine Erfahrung auf diesem gebiet der
Bildverarbeitung im FPGA und hoffe das mein Problem verständlich
geworden ist und das mir jemand weiterhelfen kann.
Danke
Stichwort: FIFO
+---------------+
| Arbiter |
| |
Video In-> FIFO -> DDR2 -> FIFO -> Video Out
| |
+---------------+
So oder ähnlich schaut das Ganze aus. Auf der Eingagnsseite schreibst Du
in das Fifo so lange, bis die Daten kommen. Auf der Ausgangsseite, liest
Du die Daten, solange das Fifo nicht leer ist. In den DDR Speicher
schreibst Du die Daten, solange das Eingangsfifo nicht leer ist. Aus dem
DDR Speicher liest Du die Daten, solange das Fifo nicht voll ist.
Arbiter läuft meistens mit einem viel häheren Takt, sodaß die Fifos
rechtzeitig befüllt und ausgelesen werden können
Im Prinzip reicht ein einfacher Arbiter, der die Zugriffe zum Speicher
koordiniert (Du kannst ja nicht gleichzeitig lesen und schreiben).
Ich glaube kaum, dass bei so kleinen Bildern Du Probleme mit der
Bandbreite des DDR2-Speicher bekommst.
Gruß,
Kest
Ok schonmal vielen Dank.
Also seh ich das richtig, dass vor und nach dem DDR2 RAM noch ein FIFO
kommt.
Da ich die Bilder ja langsamer einlese, kommt es doch zwangsweise dazu,
das das Ausgangs-FIFO irgendwann leer sein wird. Wie kann ich dann
verhindern, das ich trotzdem was anzeige, auch wenn man eventuell die
fehlenden Bilder nicht mitbekommen würde.
Du machst einfach Dual-Buffer! Also während Du ein Bild im Speicher
ablegst (z.B. ab Adresse 0), liest Du unabhängig davon aus dem anderen
Buffer im Speicher (z.B. Addresse 0x10000). Wenn das eingehene Bild
fertig im Speicher ist, schaltest Du um und schreibst in den zweiten
Buffer (Adresse 0x10000) und liest aus dem zweiten (Adresse 0). So geht
es dann weiter.
Grüße,
Kest
Passiert das auslesen des ersten FIFO's dann am besten Zeilenweise? Ich
benötige ja auch etwas Zeit, um die Daten in das DDR2 zu schreiben. Nehm
ich dazu die Zeit die ich am ende einer Zeile habe?
Wenn die Bilddaten gültig sind, schreibst Du diese einfach in das FIFO.
Das Auslesen aus dem FIFO kann z.B. mit almost_full-flag oder ähnlich
getartet werden. Da der DDR-Speicher viel schneller ist, als die
eingehende Bilder, ist das überhaupt kein Problem. Auf Zeilen würde ich
mich nicht beschränken, macht nur Kopfzerbrechen -- einfach Video_valid
mit z.B. "Frame_Valid and Line_Valid" generieren und ab da nur
Video_valid arbeiten.
Grüße,
Kest
Und was mach ich wenn ich genau in dem Moment, wenn mein video_valid
signalisert, Daten in DDR2 speichern, der DDR2 gerade mein Ausgangs FIFO
voll macht? kann ich es mir dann erlauben zu warten?
Das Schlimmste was passieren kann ist, dass mit jedem Takt ein Wert in
den Speicher geschrieben und ein Wert aus dem Speicher gelesen werden
soll.
Um sowas zu vermeiden, macht man eben almost_full_ und _almost_empty
nicht einfach full_ und _empty. :-)
Grüße,
Kest
Du hast je ein FIFO mit entsprechenden Signalen (z.B.)
FIFO_IN_data
FIFO_IN_rdclk
FIFO_IN_rdreq
FIFO_IN_wrclk
FIFO_IN_wrreq
FIFO_IN_q
FIFO_IN_rdempty
FIFO_IN_wrfull
FIFO_OUT_data
FIFO_OUT_rdclk
FIFO_OUT_rdreq
FIFO_OUT_wrclk
FIFO_OUT_wrreq
FIFO_OUT_q
FIFO_OUT_rdempty
FIFO_OUT_wrfull
almost_empty und almost_full sind dann Deine eigene Signale, die Du
selber generierst, wenn z.B. im FIFO eine bestimmte Anzahl von Werten
drin steht. Diverse Core-Generatoren können diese aber auch für Dich
generieren.
im Prinzip, verbindest Du dann alles etwa so (kein Anspruch auf
Vollständigkeit -> nur Pseudocode)
FIFO_IN_wrclk <= Video_clock;
FIFO_IN_data <= Video_data;
FIFO_IN_wrreq <= Video_Frame_Val and Video_Line_val and not
FIFO_IN_wrfull;
FIFO_IN_rdclk <= DDR2_Clock;
DDR2_Data <= FIFO_IN_q;
FIFO_IN_rdreq <= not FIFO_IN_rdempty and not DDR2_busy;
DDR2_write <= FIFO_IN_rdreq um einen Takt verzögert;
DDR_write_addr <= +1 wenn DDR2_write='1'
Und dann das ganze für FIFO_OUT...
Und schon läuft alles von alleie.
almost_full ist etwa
almost_full <='1' when (Anzahl der Daten im FIFO > 110) else '0'; --
z.B. bei Maximum 128 Werten)
almost_empty <='1' when (Anzahl der Daten im FIFO < 10) else '0';
Grüße,
Kest
Ok hab ich das richtig verstanden, ich generiere mir ein Signal was
signalisiet, dass die Daten in den DDR Speicher geschrieben werden
können, obwohl das FIFO noch nicht komplett voll ist. Wenn ich dann
nicht auf den DDR Speicher schreiben kann, weil er gerade in Benutzung
ist, kann ich noch einen moment warten bis ich drann bin ohne das das
FIFO überläuft.
Ist das richtig so?
Schönen Dank schonmal für die Erklärungen.
Das geht, zum Beispiel hier:
http://www.baumeroptronic.com/verisens_technical_data.html?&L=0
Da die daten von der Kamera wohl nur mit 8bit und 50 MHz anfallen, muss
der RAM halt nur breit (32 bit) und mit höherer Taktrate (z.B. 150 MHz)
betrieben werden. Xilinx hat unter dem Stichwort MIG (memory Interface
Generator) entsprechende Cores.
Gruessle
>Da die daten von der Kamera wohl nur mit 8bit und 50 MHz anfallen, muss>der RAM halt nur breit (32 bit) und mit
... NIEDRIGERER Taktrate gefahren werden.
8/32 * 50 12,5 MHz. Aus dem SOPC kriegt man z.B. 125 raus. Bleiben 90%
Reserve fürs Schreiben.
Das mit den 8Bit und 50Hz stimmt... wie kommt man da auf 32Bit
Wortbreite des Speichers. Desweiteren versuche ich mich gerade mit dem
MIG zu beschäftigen (ist aber auch nicht ganz so einfach) und so wie ich
das seh, kann ich den RAM nur auf 64 oder 128 Datenwortbreite
einstellen.
Ich glaub ich hab mich gerade verlesen... der Pixeltakt beträgt bei mir
lediglich 10Mhz und die 32Bit nehmt ihr um 4 Pixel gleichzeitig zu
speichern oder? D.h. wenn die Wortbreite 64Bit ist dann 8/64 * 10MHz =
1,25Mz. Seh ich das richtig, das ich dann immer 8 Pixel aus meinen FIFO
lesen soll?
>8 Pixel aus meinen FIFO
lesen soll?
Im prinzip ja, es sollte ja kein problem sein ein Fifo mit 8 bit Eingang
und 64 bit Ausgang zu bauen. Ich habs grad mit dem Coregenerator für den
Spartan3E angetestet, damit kann man auch FIFOS genenerieren. Wählt man
Indepent Clock Block RAM und eine Write depth > 512, kann eine
Eingangsbreite 8 bit und eine ausgangsbreite 64 eingestellt werden.
MfG
Ja Danke, das hab ich mitlerweile auch gefunden. Momentan ist es
allerdings so, das es über einen MPMC realisiert werden soll, da später
auch andere logik auf den DDR2 Speicher zugreifen soll. Dieser hat auch
ein Video Frame Buffer Controller, in dem ich mich gerade versuche
einzuarbeiten, in wie fehrn dieser für mich nützlich ist.
>>Da die daten von der Kamera wohl nur mit 8bit und 50 MHz anfallen, muss>>der RAM halt nur breit (32 bit) und mit
... NIEDRIGERER Taktrate gefahren werden.
8/32 * 50 12,5 MHz. Aus dem SOPC kriegt man z.B. 125 raus. Bleiben 90%
Reserve fürs Schreiben.
Hm, es war eigentlich wirklich höhere takt gemeint, weil der SDRAM sich
ab und zu eine Pause gönnt (BANK Prefetch, Refresh, etc.) Das ist bei
heutigen SDRAMS zwar nicht mehr so kompliziert, aber sorgt immer noch
dafür das die realisierbare Datentransferrate nicht kontinuierlich
gleich ist. Und in meinem Beispiel greifen 3 Komponenten auf den SDRAM
zu,
-uC für Programm und Daten
-Businteface liest die Daten aus den RAM
-Kamera schreibt Daten in den RAM
Aber das ist naturlich nicht zwingend nötig, bei Dir beschleunig der
breite Datenbus den Transfer schon erheblich.
MfG