Überlege dir ob du den wahlfreien Zugriff auf einzelne Pixel des Bildes
wirklich benötigst. Denn falls ja wird das wirklich nicht einfach auch
nicht mit DDR2/3 SDRAM, bzw. besonders nicht mit diesem RAM Typ. Denn
DDR SDRAM ist nur schnell wenn du ganze Datenblöcke liest und scheibst.
Je weiterentwickelter der DDR SDRAM ist, also DDR -> DDR2 -> DDR3, desto
größer muß das Ratio der Datenblock Länge zu Datenblockanzahl werden.
In meinem LED Wand Projekt (HDMI 4096×2160p24) mussten die Pixel des
Streams um 90 Grad rotiert werden. Dh. aus einem Zeilenweisen Bild muß
die LED Wand als spaltenweises Bild rausgesendet werden und das noch in
Pixel-Kacheln a 8x16 Pixel umgruppiert werden. Ich habe das mit einem
FIFO gleich am DVI/HDMI Eingangscore erschlagen. Diesen benötigst du
sowieso um die Taktdomaine des DVI/HDMI Signales mit der Taktdomaine des
internen Controllers (auch Speichercontrollers, läuft nur mit 166Mhz)
anzupassen. Dieser FIFO ist als langes RAM-Shiftregister mit Taps
aufbebaut. Somit habe ich das Pixelprozessing pipelined und sequentiell
direkt im Eingangsstream eingebaut. Dieses "FIFO" arbeitet Zeilenweise
am Input und gruppiert jeden 8'ten Pixel so um das wir 8 Pixel pro
Gruppe am Ausgang haben. Ich habe also am Ausgang 8 Pixel die später auf
der LED Wand senkrecht untereinander stehen und somit sequentiell aus
dem SDRAM gelsen werden können (als Blöcke). Defakto also eine 90 Grad
Rotation des Bildes aber in kleinere Segemente zerteilt.
Im externen DDR2 SDRAM liegen dann die Pixel des Bildes schon in Blöcke
zerlegt an festen Adressen. Also intern wird das Eingangsbild immer auf
virtuelle 4096×2160 umgerechnet (fehlende Pixel sind schwarz).
Der Speichercontroller benutzt dabei ein Tripple Buffering, dh. ein
Speicherbereich wird durch den DVI/HDMI Eingangscontroller geschrieben,
ein weiterer Buffer wird für die Ausgabe gelesen und ein dritter Buffer
steht als nächster freier Buffer zur Verfügung.
Mit dieser Methode baust du die sogenannte Frameraten Anpassung vom DVI
Eingang zum Ausgang bei mir die LED Wand.
Parallel zu den zu lesenden Pixeln kann im SDRAM eine Tabelle für die
Helligkeitskorrektur jedes Pixel in RGB hinterlegt werden (Dotcorrection
48Bit).
Werden die Pixel ausgegeben so stehen sie im 24Bit RGB Format zur
Verfügung. Sie werden dann erstmal über einen FIFO an die Taktdomain von
166MHz intern aus X MHz extern für den LED Wand Controller
zwischengespeichert. Danach mit Hilfe von drei Gammatabellen (RGB) von
24 Bit nach 48 Bit gewandelt (die LED Wand hat 48Bit Farbtiefe mit einem
Set von 24Bit gleichzeitig darstellbaren Farben). Nach dieser Wandlung
erfolgt noch die Dotkorrection. Dazu wie gesagt wird für jeden Pixel
ebenfalls aus dem SDRAM drei 16 Bit Werte geladen und mit dem 48Bit
multipliziert. Erst danach wird ein Bitparelleler Datenstrom aus den LED
Pixel erzeugt der mit 96 internen SerDes Cores mit max. 860MBit/sec pro
SerDes rausgesendet werden.
Nun lange Rede: ich behaupte das es sehr schwierig für dich als FPGA
Anfänger wird nur annähernd an das ran zu kommen was du möchtest. Ich
könnte es derzeit nicht, wenn du wirklich pro Pixel mehrfachen
wahlfreien Zugriff benötigst und das alles innerhalb eines Frames,
sprich als Echtzeit-Video-Prozessing.
In meinem Projekt kommen wir pro Pixel auf 1 Schreib + 1 Lese + 2 Lese
für Dotcorrection. Und das mit 166MHz = 333MHz DDR2 SDRAM. Dabei musste
ich dem internen Speichercontroller sowohl für das Schreiben und Lesen
mit FIFO Buffern arbeiten um die Daten in möglichst großen Blöcken zum
DDR2 Controller schicken zu können. Das System ist bei 4096×2160p24 an
seiner Grenze, ganz ohne weiteres Pixelprozessing.
Mit DDR-SDRAM auf einzelne Pixel wahlfrei zugreifen zu wollen ist
sinnfrei und geht auch garnicht so einfach. Man muß dann zB. das
Maskregister benutzen und liest denoch für einen Pixdel quasi X Pixel
Daten umsonst. Schau, wir haben einen externen 48Bit breiten DDR2-SDRAM
angeschlossen. Daraus werden bei DDR2 also 96Bit und der Altera DDR2
Controller macht daraus 192Bit interne Datenbusbreite. 192Bit/24Bit=8.
Wir schreiben/lesen in diesem Fall also immer 8 Pixel auf einmal, egal
ob wir davon nur 1 Pixel real benötigen.
Dein wahlfreier Pixelzugriff würde in dieser Konfiguration also 8 mal
mehr lesen und schreiben müssen als du eigentlich benötigst. Du bist 8
mal langsammer durch die DDR2 Technologie. Mal noch nicht die Latenzen
des SDRAM Controlelrs in den Speicherchips mit eingerechnet, denn das
umswitchen von Commando zu Commando benötigt nochmals Zeit ebenso muß
der SDRAM auch regelmäßig aufgfrischt werden (refresh), was ebenfalls
Latenzen hat.
Du solltest also deine Videobearbeitungsfunktionen alle so aufbauen das
sie mit dem sequentiellen Stream arbeiten können. Deren Output in
interne FIFOs schreiben und diese dann Blockweise zum DDR2 Controller
Core senden/lesen.
Ich habe auf einem Altera CycloneIII(120) entwickelt.
Gruß Hagen