Board: Altera Cyclone III Development Board
Hallo zusammen,
ich versuche gerade im Altera SOPC Builder, mehrere Clipper- Scaler-
Kombinationen umzusetzen. Also ungefähr so:
... Clipper1 -> FrameBuffer1 -> Scaler1 ...
... Clipper2 -> FrameBuffer2 -> Scaler2 ...
... Clipper3 -> FrameBuffer3 -> Scaler3 ...
Dabei tritt das Problem auf, dass ich mehr als zwei FrameBuffer benötige
und somit auch auf mehr als zwei SDRAM Controller zurückgreifen müsste.
Das Board hat jedoch nur zwei RAM.
Kennt hier jemand eine andere Möglichkeit, trotzdem mehrere FrameBuffer
zu benutzen?
Vielen Dank
Marc
Dann musst du dir wohl einen Wrapper um den RAM-Controller schreiben,
der die verfügbare Bandbreite auf mehrere Ausgangsports verteilt, und
jedem Port einen separaten Adressbereich zur Verfügung stellt.
Die Framebuffer kannst Du alle an einen SDRAM Controller hängen.
Verstehe gerade nicht das Problem. Da musst Du keinen Wrapper schreiben,
sondern einfach unterschiedliche Adressen angeben, an die im Speicher
geschrieben werden soll
Kest
Kest schrieb:> Die Framebuffer kannst Du alle an einen SDRAM Controller hängen.> Verstehe gerade nicht das Problem. Da musst Du keinen Wrapper schreiben,> sondern einfach unterschiedliche Adressen angeben, an die im Speicher> geschrieben werden soll
Natürlich verringert sich die Bandbreite pro Zugreifer (d.h. Du musst
nicht nur den Adressraum aufteilen, sondern auch das Zeitmultiplex für
die Zugriffe meistern).
Kest schrieb:> Die Framebuffer kannst Du alle an einen SDRAM Controller hängen.> Verstehe gerade nicht das Problem. Da musst Du keinen Wrapper schreiben,> sondern einfach unterschiedliche Adressen angeben, an die im Speicher> geschrieben werden soll
Ok, wenn das doch geht, ziehe ich meinen Vorschlag zurück ;-) Das war
als Lösung gedacht, wenn man tatsächlich nur einen RAM Controller mit
einem lokalen Port hat, und mehrere Module anschließen möchte.
Danke für die schnellen Antworten.
Ich habe bei den beiden Controllern jeweils eine "Base" von 0x00000000
und ein "End" von 0x07ffffff. Das wären 134.217.727bit, also 16,7MB.
Wenn ich euch richtig verstanden habe, kann ich bei den Frame Buffern,
also einfach die 0x07ffffff durch meine Anzahl an Frame Buffern teilen
und die entsprechenden Startbereiche bei "Base address of frame buffers"
eintragen.
Das werde ich gleich mal ausprobieren. Vielen Dank
Kest schrieb:> Die Framebuffer kannst Du alle an einen SDRAM Controller hängen.> Verstehe gerade nicht das Problem. Da musst Du keinen Wrapper schreiben,> sondern einfach unterschiedliche Adressen angeben, an die im Speicher> geschrieben werden soll
Das ist leider fehlgeschlagen. Ich habe erstmal nur zwei Frame Buffer an
einen Controller gehangen. Dazu habe ich bei dem ersten den Startbereich
ab 0x00000000 angegeben und beim zweiten den Bereich ab 0x03ffffff. Dann
sollten beide Buffer einen Speicher von gut 8MB zur Verfügung haben,
obwohl sie nur gut 2MB brauchen. Leider funktioniert das wie gesagt
nicht.
Gruß
Was heißt "funktioniert nicht"?
Im Framebuffer kannst Du Unmengen an Parametern einstellen --
single/tripple buffer, Burst-Länge, Bit-Breite und so weiter... Es
funktioniert erst wenn alles "richtig" ist.
Fang mal "klein" an mit einem Testpatterngenerator und einem Ausgang...
Funktioniert? Dann klinkst Du Framebuffer dazwischen? Funktioniert? Dann
nimmst Du Scaler dazu... funktioniert? Dann nimmst Du einen Input dazu
statt Testpattern-Generator...
Gleichzeitig spielst Du halt mit Einstellungen, Buffer-Längen,
FIFO-Größen und so weiter.
Kest
Kest schrieb:> Fang mal "klein" an mit einem Testpatterngenerator und einem Ausgang...> Funktioniert? Dann klinkst Du Framebuffer dazwischen? Funktioniert? Dann> nimmst Du Scaler dazu... funktioniert? Dann nimmst Du einen Input dazu> statt Testpattern-Generator...> Gleichzeitig spielst Du halt mit Einstellungen, Buffer-Längen,> FIFO-Größen und so weiter.
Die schrittweisen Aufbauten funktionieren soweit alle. Auch mit Frame
Buffer. Das Problem liegt wie gesagt nur in der Nutzung mehrerer Frame
Buffer mit einem Controller. Was mir noch aufgefallen ist, ist eine
Warnung beim Framebuffer: "Warning: Base address is not aligned to burst
boundary.".
Das hört sich garnicht so gut an. Die Warnung tritt auf, sobald ich die
"Base address of frame buffers:" ändere. Welchen Wert ich eintrage ist
egal. Alle ausser 0x00000000 erzeugen diese Warnung.
Gruß
Marc85 schrieb:> Das hört sich garnicht so gut an. Die Warnung tritt auf, sobald ich die> "Base address of frame buffers:" ändere. Welchen Wert ich eintrage ist> egal. Alle ausser 0x00000000 erzeugen diese Warnung.
Schaue mal im Framebuffer, wie lang Deine Bursts sind. Ein Vielfaches
von diesem Wert sollst Du im Framebuffer auch eintragen -- das
funktioniert bestimmt ;-)
Kest
Kest schrieb:> Schaue mal im Framebuffer, wie lang Deine Bursts sind. Ein Vielfaches> von diesem Wert sollst Du im Framebuffer auch eintragen -- das> funktioniert bestimmt ;-)
Hi,
ich habe eine Lösung gefunden.
Man benötigt das Multi-port Front-end von Altera. Dieses muss jedoch
extra heruntergeladen werden. Falls es noch irgendjemanden interessiert:
http://www.altera.com/literature/an/an637.pdf
Wenn man das benutzt und dazu noch deine Anweisung befolgt (also die
Adressbereiche für die Framebuffer aufteilt), funktioniert alles.
Danke nochmal an alle
Ich denke, Du brauchst eigentlich keinen extra Multiport-Frontend. Es
gibt die sogenannten "Arbitration Shares" (rechte Maustaste im QSYS). da
kannst Du für jede Verbindung die Priorität einstellen. Damit habe ich
immer meine Master/Framebuffer realisiert.
Kest
Kest schrieb:> Ich denke, Du brauchst eigentlich keinen extra Multiport-Frontend. Es> gibt die sogenannten "Arbitration Shares" (rechte Maustaste im QSYS). da> kannst Du für jede Verbindung die Priorität einstellen. Damit habe ich> immer meine Master/Framebuffer realisiert.
Hi,
nächstes Problem...
Mit dem Multiport Frontend (MPFE) funktioniert es flüssig für bis zu
sechs Frame Buffer. Ohne Multiport Frontend leider nach wie vor
garnicht.
Die Adressen habe ich eingetragen wie du vorgeschlagen hast
64*64= 4096
2298kbyte/4096byte=561
Also nehme ich als Multiplikator 600.
4096byte*600=4096000byte
Dez Hex
0 0
4096000 3E8000
8192000 7D0000
12288000 BB8000
16384000 FA0000
20480000 1388000
24576000 1770000
28672000 1B58000
Das Problem bei meinem MPFE ist, das Slave 0-5 mit 64bit für Master und
Slave Port konfigurierbar sind, Port 6 und 7 aber fest auf 32bit
eingestellt sind. Somit kann ich diese Ports nicht nutzen. Wenn ich sie
einfach frei lassen will, gibt es errors.
Dann habe ich noch probiert 2 MPFE's zu nutzen und diese auf den zweiten
Teil des dual-channel DDR2's zu legen. Diese scheinen sich aber
ebenfalls negativ zu beeinflussen, egal ob ich die Adressen fortlaufend
vergebe, oder für den zweiten DDR2 wieder bei 0x0 anfange.
Ich würds natürlich gerne ganz ohne MPFE machen. Aber dann bekomme ich
wie gesagt nur einen Frame Buffer ans laufen, bzw. zwei FB auf zwei
verschiedenen DDR2's.
Vielen Dank für eure Hilfe
Marc
ich habe jetzt nicht ganz verstanden, was Du meinst bzw. habe ich die
Frage nicht gesehen ;-)
Unklar, was die Zahlen bedeuten: 64x64 Bit?Byte? Burstlänge?
Burstbitbreite? ...Sorry, ohne Kontext kann ich nicht viel helfen, auch
nicht, weil ich mit dem MPFE noch nichts gemacht habe. Aber es soll Dir
klar werden, dass es theoretisch auch ohne gehen muss! Denn die
Bandbreite des DDR2 scheint ja auszureichen.
Wenn Du 2 DDR2 Controller hast, kannst Du nicht einfach je 3 FB
dranhängen? Die dürfen sich aber nicht überschneiden und jeweils eigenen
AVALON-Bus haben...
Dein Multiplikator von 600 verstehe ich auch nicht ganz. Wenn man schon
mit den Bursts arbeitet, dann sollte man auch Zweierpotenz nehmen, also
eher 1024. Darauf hin muss Du dann alles optimieren.
Ist schwer zu sagen, was da passiert
kest
Kest schrieb:> ich habe jetzt nicht ganz verstanden, was Du meinst bzw. habe ich die> Frage nicht gesehen ;-)> Unklar, was die Zahlen bedeuten: 64x64 Bit?Byte? Burstlänge?> Burstbitbreite? ...Sorry, ohne Kontext kann ich nicht viel helfen, auch> nicht, weil ich mit dem MPFE noch nichts gemacht habe.
Hi,
ja das soll tatsächlich die Burstlänge sein. Dazu habe ich das burst
target von 64 words genommen und mit der Portweite von 64byte
Multipliziert.
Kest schrieb:> Aber es soll Dir> klar werden, dass es theoretisch auch ohne gehen muss! Denn die> Bandbreite des DDR2 scheint ja auszureichen.> Wenn Du 2 DDR2 Controller hast, kannst Du nicht einfach je 3 FB> dranhängen? Die dürfen sich aber nicht überschneiden und jeweils eigenen> AVALON-Bus haben...
Am liebsten möchte ich es ja auch ohne MPFE machen ;)
Bisher hat es nur leider noch nicht einmal mit zwei FB an einem
Controller funktioniert. Bzw. wenn ich Glück hatte, habe ich ein
instabiles Bild bekommen, welches am zittern war und "zufallsmäßig"
Pixel von dem anderen Bild enthielt.
Kest schrieb:> Dein Multiplikator von 600 verstehe ich auch nicht ganz. Wenn man schon> mit den Bursts arbeitet, dann sollte man auch Zweierpotenz nehmen, also> eher 1024. Darauf hin muss Du dann alles optimieren.
Ok, das werde ich machen
Danke dir!
Marc85 schrieb:> Bisher hat es nur leider noch nicht einmal mit zwei FB an einem> Controller funktioniert. Bzw. wenn ich Glück hatte, habe ich ein> instabiles Bild bekommen, welches am zittern war und "zufallsmäßig"> Pixel von dem anderen Bild enthielt.
Hast Du denn den ganzen Kram mal simuliert? Auch wenn das in Deinem Fall
etwas komplexer ist, sieht man so die Probleme i.a. wesentlich besser
als auf der Hardware.
Duke
"Long shot": mach mal ein Screenshot von Deinem QSYS Aufbau. Ich wette,
es funktioniert ohne MPFE nicht, weil die Clocks nicht stimmen (habe
schon öfters gesehen). Ein Screenshot vom DDR2 Controller wäre auch
nicht schlecht und auch ein Scressnshot vom FrameBuffer
Kest
Duke Scarring schrieb:> Hast Du denn den ganzen Kram mal simuliert? Auch wenn das in Deinem Fall> etwas komplexer ist, sieht man so die Probleme i.a. wesentlich besser> als auf der Hardware.>> Duke
Hi,
ich versuch mal die Simulation ans laufen zu bekommen, war nur
eigentlich für einen späteren Zeitpunkt geplant.
> "Long shot": mach mal ein Screenshot von Deinem QSYS Aufbau. Ich wette,> es funktioniert ohne MPFE nicht, weil die Clocks nicht stimmen (habe> schon öfters gesehen). Ein Screenshot vom DDR2 Controller wäre auch> nicht schlecht und auch ein Scressnshot vom FrameBuffer> Kest
Hab ich gemacht.
In dem Ohne_MPFE.png sind alle Settings wie in MPFE.png. Lediglich das
MPFE wird wie gezeigt übersprungen und die FB gehen direkt auf den DDR2
Controller.
Die Settings vom DDR2 Controller wurden vom "DVI 1080P Loop-through"
Tutorial von Bitec übernommen (http://www.bitec.ltd.uk/hsmc_dvi.html)
Danke!
Mehrere Sachen fallen mir auf:
- zunächst mal würde ich DDR2 Controller auf Half-Rate stellen, damit
hast Du statt 64 Bit Bursts 128 Bit. Die Timings sind dann entspannter.
Außerdem habe ich die Erfahrung gemacht, dass DDR2 Controller (sowohl
legacy, als auch der Neue) nicht richtig mit dem Framebuffer arbeitet
(Die Zugriffe sind dann jeden 2. Takt). Ob das ein Bug im Framebuffer
ist oder im Controller, weiß ich nicht. Altera support meinte nur, ich
möge doch half-rate verwenden, später wird es gefixt werden.
Lustigerweise, hat es mit Quartus 9.0 wunderbar funktioniert.
- Die Bursts von 1024 (im Framebuffer) sind viel zu lang! In der Zeit
"verhungern" andere Framebuffer, weil im SOPC ein sequenzeeller Zugriff
nicht länger als 100 sein kann (Arbitrieringsshares). Stell sie mal auf
32-64 (je nach dem wieviel Speicher Du hast)
- Ganz wichtig ist die Reihenfolge Scaler<->Framebuffer! Ob Up-Scaler
oder Down-Scaler -- es macht einen Riesenunterschied. Die
Clock-Input/Output-Buffer müssen entsprechend ausgelegt sein. Es hilft
mit einem Blatt Papier und Bleistift die Bandbreite auszurechnen, bevor
man da was anfängt. Da siehst Du sofort wo Bottlenecks sind.
- Allgemein: Die FB-Fifos (Input und Output) sollten in etwa gleich der
Arbitrierungsshares sein (direkt am DDR2). Die Summe aller
Arbitrierungsshares sollte etwa die FIFO-Größe der Input/Outputs sein.
Noch mal zusammengefasst: Inputbandbreite ausrechnen (maximale Auflösung
x fps) + Outputbandbreite (scaler berücksichtigen) sollte kleiner sein,
als 64 Bit * 166 MHz
Kest
Habe mir gerade Bittec-Design angeschaut -- schrecklich! Ich glaube, sie
haben so lange irgendwelche Zahlen geändert, bis es zufälligerweise
funktioniert hat, anders kann ich es mir nicht erklären. Alleine 13
Zeilen Zwischenbuffer im Ausgangs-Pfand spricht Bände! 1920x13x24Bit =
73 kByte an m9k Blöcken! Wahnsinn! Soetwas sollte verboten werden.
Und wieso man die Daten über 2 Framebuffer durchschiebt ist mir auch ein
Rätsel (um einfach zu zeigen, dass das funktioniert?)... Vergiss
schnell, was Du da gesehen hast! :-)
Kest
Puh, das ist mal ausführlich!
Kest schrieb:> Noch mal zusammengefasst: Inputbandbreite ausrechnen (maximale Auflösung> x fps) + Outputbandbreite (scaler berücksichtigen) sollte kleiner sein,> als 64 Bit * 166 MHz
Ok, das habe ich ausgerechnet:
Der Scaler ist ein Up- Scaler
560*24*350*60/s= 282240000bit
1680*24*1050*60/s= 2540160000bit
2.822.400.000 = 2,822Gbit/s
64bit*166.000.000Hz= 10,624Gbit/s
Die 24 ist noch dabei da ich die Farben parallel übertrage.
Passt aber offensichtlich trotzdem dicke.
Was ich noch nicht ganz verstehe ist, was die Bursts von 1024 bzw 64
oder 32, mit der größe des Speichers zu tun haben. Ich habe die
Einstellungen jetzt wie folgt geändert:
Portweite: 64
Write FIFO tiefe: 64
Write burst target: 32
Read FIFO tiefe: 64
Read burst target: 32
Die Arbitrierungsshares habe ich auf jeweils 10 gestellt, so dass
6*10=60 ergibt, also fast 64.
Der Controller steht jetzt auf Half- Rate.
Leider habe ich immer noch ein schwarzes Bild.
Was mir aber aufgefallen ist, ist das ich durch die Einstellung "Half-
Rate", ja nur noch eine DDR2.sysclock von 83MHz habe. Damit laufen bei
mir ja alle Clipper, Scaler usw. Das Videosignal kommt aber mit 119MHz
rein.
Werde nochmal versuchen alles ausser die DDR2 Controller auf CLK
(125MHz) zu setzen.
Vielen Dank nochmal für die ausführliche Hilfe!
Marc85 schrieb:> Was ich noch nicht ganz verstehe ist, was die Bursts von 1024 bzw 64> oder 32, mit der größe des Speichers zu tun haben. Ich habe die
Ein Burst von 1024 erzeugt im FPGA ein Fifo mit 1024 * 64 Bit (aus M9K
Blöcken)... Das hat mit der Größe des Speichers (DDR2) überhaupt nichts
zu tun, aber mit den M9K Blöcken -- die hat man nicht unendlich ;-))
Marc85 schrieb:> Die Arbitrierungsshares habe ich auf jeweils 10 gestellt, so dass> 6*10=60 ergibt, also fast 64.
genau
Marc85 schrieb:> Leider habe ich immer noch ein schwarzes Bild.
das kann mehrere Gründe haben. Da ist es wichtig festzustellen, was
blockiert. Wenn Du Control-Ports hast, dann kannst Du mit NIOS
Statusregister auslesen und (viel wichtiger) die Reihenfolge des
"Anstartens" festlegen. Die ganze Video-Pipeline kann nämlich
blockieren, sodaß es nur ein Reset hilft (danke Altera).
Über so einen Control-Port kannst Du dann Komponenten gezielt anhalten
und wieder starten, wenn es z.B. zum Überlauf gekommen ist.
Marc85 schrieb:> Was mir aber aufgefallen ist, ist das ich durch die Einstellung "Half-> Rate", ja nur noch eine DDR2.sysclock von 83MHz habe. Damit laufen bei
ja, das ist immer so, dass die Taktrate halbiert wird. Du könntest alle
Komponenten mit full-rate betreiben (ddr2_32bit_bot_auxfull),
Framebuffer aber mit ddr2_32bit_bot_auxhalf, sodaß nur Dein Speicher und
AVALON-Master (Frambuffer) mit der Hälfte rennen.
Du siehst, das Ganze ist nicht ohne.
Ich kann Dir nur empfehlen mit SignalTap zu arbeiten
Hi,
also nach langem hin und her, und der beachtung deiner Einstellungen,
laufen immer noch nur maximal 5 FrameBuffer pro Speicher. Eine Änderung
habe ich jedoch noch vorgenommen, die FIFO Tiefe sollte laut Alteraforum
bei M9K auf 512 gesetzt werden
(http://www.alteraforum.com/forum/showthread.php?t=5794). Andere Tiefen
habe ich auch probiert. Es scheint wirklich dran zu liegen das bei noch
mehr FrameBuffern, der Stream "verhungert".
Jetzt bleibt mir wohl nichts anderes übrig, als die restlichen Buffer
auf den zweiten Ram Controller zu legen.
Wenn ich das mache, bleibt das Bild des zweiten Controllers jedoch
schwarz, das des ersten Controllers funktioniert nach wie vor gut.
Bildlich:
RAM1(bottom): x/2 Framebuffer läuft einwandfrei
RAM2 (top): x/2 Framebuffer ergeben schwarzes Bild
Ich habe beide in zwei unterschiedlichen SOPC Files verarbeitet und
beide nutzen den TestPattern- Generator. Sie sind auch beide gleich
eingestellt. Muss ich da noch irgendwas mit den clocks beachten?
Danke und Gruß
So,
in lauter Verzweiflung bin ich alle 730 Zeilen im Assignment Editor
durchgegangen und siehe da, memtop_cke war nicht eingetragen, danke
BITEC =)
Alles läuft und das Thema hat sich erledigt.
Ha-Ha
Nach Jahren im FPGA-"Geschäft" weiß ich nun zu genau, dass man sich nie
und nimmer auf die andere verlassen sollte. Den Speicher (Memorytest)
hätte ich als erstes gemacht. Dabei ist interessant zu erfahren, wie die
Kalibrierung erfolgreich funktioniert hat :-o
Schön, dass Du jetzt weiterkommst! :-)
Kest
Kest schrieb:> Dabei ist interessant zu erfahren, wie die> Kalibrierung erfolgreich funktioniert hat :-o
Hi,
also:
CVI => Clipper => FB => Scaler => CVO
Und vom FB aus:
FB => Pipeline Bridge => Memory
(Die Pipe wurde von Altera in einem Schulungsvideo eingesetzt, jeweils
ein Read und Write Master auf eine Pipe, geht jedoch auch ohne)
Separate Clock im FB aktiviert.
FIFO Tiefe 256 (von Altera empfohlen da wohl kein kleinerer M9K
existiert, 128 tuts auch).
Burst Target 32.
In den Memorys habe ich Half Rate aktiviert.
Achja, wegen den M9K Blöcken, ich hab es mal versucht zu übertreiben,
der Compiler haut dann jedoch einen Error raus. Also ist man in der
Hinsicht ein wenig "abgesichert".
Gruß