Hallo!
Vorab: ich habe noch keinerlei praktische Erfahrung mit
FPGA-Entwicklung. Aber ich habe ein Problem, das möglicherweise nicht
anders zu lösen ist. Es geht um Echtzeit-Videoverarbeitung. Prinzipiell
müssen für jedes Pixel eines hereinkommenden Videostroms mehrere
Speicherzugriffe erfolgen (Größenordnung ~10 Zugriffe, die mehr oder
weniger zufällig über den Adressraum verteilt sind, wobei jeweils 24
oder 32 Bits gelesen werden).
Bei hohen Auflösungen und Bildraten (z.B. Full HD mit 50 Hz) ist das, so
wie ich das sehe, mit einem einzigen Speichermodul nicht machbar, weil
es die Daten nicht schnell genug lesen könnte. Also habe ich mir
überlegt, mehrere Speichermodule parallel zu betreiben, die jeweils
denselben Inhalt haben. Alle 10 Speicherzugriffe könnten dann parallel
erfolgen.
Klingt das sinnvoll/machbar?
Gibt es Alternativen?
Worauf muss man achten, wenn man ein FPGA auswählt, damit so etwas
möglich ist?
Vielen Dank für Eure Ratschläge!
Arnold
Bevor du dir solch einen Krampf mit mehrern Speichermodulen machst die
dasselbe beinhalten würde ich mich nach schnelleren Speichermodulen
umsehen. Du könntest bsw. zu beginn von einem Flash Speicher in einen
DDR-RAM kopieren und dann auf dem DDR-RAM arbeiten. Der dürfte schnell
genug sein.
Also ich komme da auf ca. 4 GB pro Sekunde ... könnte mit DDR2/DDR3
machbar sein. Aber schaffe ich es überhaupt, ein FPGA mit so hohem Takt
zu betreiben?
Der Takt des FPGA muss gar nicht so hoch sein, die meisten
Leistungsstärkeren FPGA besitzen spezielle Transceiver Blöcke um
DDR-RAMS auszulesen. Da gehen bsi zu 25Gbit/s (bsw. Virtex 7 von
Xilinx).
Musst du in den Datenblättern des FPGA nachsehen. Wird aber aller
wahrscheinlichkeit nach nur in den Devices der Mid-range Klasse (bei
Altera bsw. der Arria V (GX and GT) und Kintex-7 bei Xilinx) oder sogar
nur in der High-End Klasse (bei Altera Stratix II/III/IV/V und Virtex-7
bei Xilinx)
Die von mir gennanten FPGA's sollen nur als Beispiele dienen. Gibt
bestimmt auch kleinere FPGA's die Transceiver Blöcke mit der benötigten
Geschwindigkeit aufweisen. muss man sich halt mal bei
Altera/Xilinx/Lattice umsehen, dann wird man bestimmt fündig.
du hast nen bandbreitenbedarf von 40Gbit/s, bei einem 64bittigen
interface sind das dann ca 500MHz, dazu brauchst du aber keine 25Gbit/s
transreceiver, sondern nur ein normales ddr2/3 interface
Wie wärs erstmal das Problem anzugehen?
>> Prinzipiell>> müssen für jedes Pixel eines hereinkommenden Videostroms mehrere>> Speicherzugriffe erfolgen
Das macht schon rein logisch keinen Sinn. Warum sollte das zwingend
nötig sein?
Selbst wenn du mehrere Postprocessing Stufen hast ist das mit 95%iger
Warscheinlichkeit nicht nötig.
Denk drüber nach wie du lokale Blöcke bearbeiten kannst und gut. 32 GBIT
für 50 HZ Full HD ist ja wohl Overkill. Vor allem weil der
Speicherbedarf wohl nur bei 8Mbyte(event. Double Buffered bei 16 Mbyte)
liegt.
Ich sehe da eher Latenzprobleme beim DDR... denk auch mal über ZBT SRAM
nach. Mit 64(72)Bit * 300 MHz sollte man da ggf besser hinkommen.
Ü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
Hagen Re schrieb:> Du solltest also deine Videobearbeitungsfunktionen alle so aufbauen das> sie mit dem sequentiellen Stream arbeiten können.
Vergessen: das oben gesagte ist die eigentliche Herausforderung. Nämlich
deine Videofilter so zu konstruieren das sie sequentiell und damit oft
pipelined arbeiten können.
Dazu benötigst du einen FPGA mit viel internem BRAM + DSP Blöcken. Im
Idealfall benötigst du dann garkeinen ext. RAM mehr.
Gruß Hagen
Naja, mir ist keine HDMI App bekannt, wo man alles im BRAM hatte halten
können. Die FPGAs die dort zum einsatz kommen, haben ja auch noch andere
Aufgaben, als nur Bildlein verwursten,
Eine eigene Frage?
Dieser Thread ist über 15 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.