www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Bild- speicherung, -verarbeitung im FPGA


Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok danke.

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kanns du mir bitte das noch ein bischen näher erklären was du mit 
almost_full_ und _almost_empty meinst?

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast richtig verstanden!

Grüße,
Kest

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank nochmal, für die Hilfe :)

Autor: Peter Propeller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht, zum Beispiel hier:
http://www.baumeroptronic.com/verisens_technical_d...

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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: matzunami (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Peter Propeller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls jemand so etwas auf diese weise schoneinmal realisiert hat, würd 
ich mich über nützliche Informationen freuen.

Autor: Peter Propeller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.