Hallo Leute,
so ich will mich mal, wie der Titel schon sagt, mit einem TFT versuchen.
Und zwar möchte ich gerne einen FPGA einsetzen als Controller. Ich hätte
hier noch Muster rumliegen von einem Altera Cyclone II.
Für den FPGA wäre es ja kein Problem, alle die notwendigen Signale
(Pixel Clock, HSync, VSync etc) zu generieren.
Mein FPGA hat zu wenig internen RAM; deshalb würde ich extern mal ein
SRAM mit 512 kB anschliessen, damit könnte ich dann 2 vollständige
Bilder speichern (ich möchte 320 x 240 Px, bei 24 Bit).
Also, ansich wäre das ja machbar - mit dem FPGA die Daten aus dem SRAM
zum TFT schaufeln und das richtige Timing einhalten.
Soweit so gut, nun plagen mich aber noch zwei Fragen, bevor ich mich an
sowas komplexes wage:
- Wenn man das Gerät einschaltet, dann dauert es ja erst eine gewisse
Zeit (x Millisekunden), bis der FPGA configuriert ist. Wöhrend dieser
Zeit kann er ja keine Daten an das Display rausgeben. Die Frage ist
jetzt, ob das dem Display schadet, wenn es nach dem Power Up jeweils für
diese kurze Zeit keinen Clock und keine Daten kriegt? Weil, man muss das
Display ja kontinuierlich takten, sonst zeigt es nichts an und geht
kaputt.
- Wie könnte ich elegant die Daten, die ich anzeigen möchte, in das SRAM
bringen? irgend eine Schnittstelle muss das ja noch haben.
Als FPGA möchte ich, wie gesagt, einen Altera Cyclone II einsetzen.
Eigentlich müsste das ja mit einem EP2C8T144 gehen (solche habe ich
nämlich einige hier). Der hat 8k LEs.
> Weil, man muss das Display ja kontinuierlich takten, sonst zeigt es> nichts an und geht kaputt.
Diese Aussage würde ich erstmal prüfen. "Keine Pixelclock" gibt es
schließlich auch, wenn der Stecker draußen ist. Notfalls ist es sicher
nicht schwer, einen gezogenen Stecker zu simulieren (Tristate-Treiber),
wobei das der FPGA in der Config-Phase evtl. eh macht.
> - Wie könnte ich elegant die Daten, die ich anzeigen möchte, in das SRAM> bringen? irgend eine Schnittstelle muss das ja noch haben.
Hängt von der Anwendung ab. Standbilder? Textmatrix? Textmatrix und
Sprites? 2d-Rendering? 3d-Rendering?
Bedenke gleichzeitig die max. Übertragungsgeschwindigkeit des Speichers,
da du gleichzeitig ein dargestelltes Bild auslesen und evtl ein neues
reinschreiben musst.
Hi Morin,
Also ich möchte grundsätzlich Standbilder anzeigen. Rendering und solche
Geschichten habe ich nicht vor; es wäre aber doch schon ganz nützlich,
wenn ich eine ordentliche Bildwiederholrate erzielen könnte (ich sag mal
so 10..15 Bilder pro Sekunde sollten es schon sein).
Es soll unter anderem Text dargestellt werden; aber auch Grafik (ein
Diagramm). Text und Diagramm werden von einem Mikroprozessor als Daten
geliefert, der FPGA muss also wirklich nichts weiter tun, als das Zeug
im RAM zu speichern und das, was im RAM ist, auf dem Display anzuzeigen
(vorerst jedenfalls).
Später wäre es natürlich schon praktisch, wenn er z.B. Text selber
generieren könnte; das interessiert mich im Moment aber nicht wirklich.
Hmm, das mit der Übertragungsgeschwindigkeit ist ein wichtiger
Knackpunkt. Ich Gedenke, ein SRAM einzusetzen, das 512 kB hat, sowie
eine Zugriffszeit von 55 ns. Wenn der Pixelclock meines TFT's nominal
5.33 MHz beträgt, dann entspricht dies einer Periodendauer von 187.6 ns;
während dieser Zeit muss ich 3 Bytes aus dem Speicher auslesen -> ich
habe also zum auslesen eines Bytes 62.5 ns Zeit, das sollte ja
hinkommen. Allerdings kann ich dann nix mehr rein schreiben :-) Mist!
Wäre es evtl. klug, zwei SRAMs zu je 256 kB anzuschliessen, und diese
abwechslungsweise zu benutzen? Das heisst - erst werden die Daten aus
dem RAM1 angezeigt; in dieser Zeit kann man RAM2 füllen. Dann wird
umgeschaltet - RAM2 wird angezeigt, während RAM1 gefüllt wird.
Aber nee - das ist auch Murks.
Ich guck mich gleich nach schnelleren SRAMs um, sowas muss es doch
geben...
Gruss
Die SRAM's auf dem Spartan3-Eval Board von Trenz laufen mit 10 ns. Habe
sie aber mit meinem Controller nur mit max. 20ns ansprechen können, ein
perfomanten Controller zu schreiben ist recht knifflig
Hallo,
ja mittlerweile habe ich mir auch ein SRAM mit 10ns rausgesucht. Das
sollte nun also gehen.
Nun mache ich es wie folgt: ich schliesse einen 16 MHz Quarzoszillator
am FPGA an. Bei jeder Taktflanke wird der Adresszähler fürs RAM um 1
hochgezählt.
Nach der 1. Taktflanke wird das Datenbyte für R aus dem RAM geholt; eine
weitere Taktflanke später das Grüne Datenbyte, danach das Blaue, und
dann wird der Pixelclock generiert. Das sollte so also passen; mein
beabsichtigtes TFT hat wie gesagt einen Pixelclock von 5.33 MHz.
Was haltet ihr davon?
Nun muss ich nur noch ne kluge Idee finden, um Daten ins RAM zu
bekommen. Am liebsten seriell.... Mal schauen. Ideen?
@franz
ich hab mal vor längerer zeit sowas gemacht. bei mir waren es zwei
getrennte projekte. zum einen die reine text-darstellung. da brauchst du
keinen externen speicher. ich hab damals 3 block-rams (ich verwende
xilinx, die blockrams haben eine größe von 2kB) verwendet. eins als
char-rom (konnte man aber verändern, da die blockrams alle als dual-port
ausgelegt sind), eines als text-speicher, und eins als farb-speicher.
die grafik-variante hatte es dann in sich :-))
auf dem spartan-3 board ist 1mb speicher organisiert als 256kx32
vorhanden. ich habe immer 32 bit eingelesen, 4 pixel ausgegeben, und die
zwischenzeit dafür genutzt ein byte in den speicher schreiben zu können.
dabei konnte ich entweder von einem mikrocontroller aus in den
speicher-schreiben, oder aber (und das war das geniale daran) eine
state-machine im fpga bemühen mir bestimmte grafik-operationen
durchzuführen. dies waren dann operationen wie blöcke
kopieren/modifizieren.
ich habe dann von dem mikrocontroller aus einen/mehrere zeichensätze in
den speicher geschrieben (im nicht sichtbaren bereich) und später dann
über die gme (so hab ich das teil genannt : graphics memory engine)
einzelne zeichen in den sichtbaren bereich kopiert. es gibt dann auch
noch so operationen wie and/or/xor die sich auf die speicherbereiche
anwenden lassen, und eben reine füll-operationen. das teil war schon
recht gut, und der aufwand war relativ gering. einzig und allein das
timing war was kniffelig, da ich nur mit den 50mhz gearbeitet hab, und
das doch etwas wenig war, aber es hat funktioniert :-)
das ganze lief dann an einem vga-monitor, sollte aber auf jedem anderen
tft-display auch lauffähig sein. hab später mal von einem bekannten 2
tft's bekommen die mit pixclk, vsync und hsync und 9 bit rgb versorgt
worden sind. und das display hats mir nicht übel genommen wenn da mal
was nicht stimmte bzw beim einschalten keine signale anlagen.
also wenn du erstmal soweit bist das du daten ins ram schreiben bzw
davon lesen kannst und gleichzeitig das bild ausgeben kannst ist der
rest ein kinderspiel.
zum thema geschwindigkeit ein kleiner tipp :
wenn die zeit von deinem ram nicht ausreicht (also bytes auslesen und
dann beschreiben) : lies einfach mehrere bytes/pixel ein und clocke sie
dann später raus (so ähnlich hab ich es ja auch gemacht). dadurch
bekommst du mehr zeit um das ram beschreiben zu können. wenn du 55ns
rams hast und 62.5 ns zeit -> 7.5 ns übrig / 55ns ~ 8 bytes einlesen um
eins schreiben zu können, oder aber 2 rams parallel -> 4 bytes einlesen
um 2 schreiben zu können. (alle angaben ohne gewehr gg)
Hi Mason,
Danke erstmal für deine Erläuterungen!
Schau mal, ich will das Display hier ansteuern:
http://www.hitachi-displays-eu.com/doc/TX09D70VM1CCA.PDF
Ich hab das mit dem RGB-Interface noch nie gemacht, aber mal so als
Verständnisfrage:
siehst du das auch so, dass ich jeweils die RGB-Daten an das Display
anlege, und mit DCLK (Dot Clock heisst das hier) in das Display clocke,
und nach 240 clocks wird mit DTMG (keine Ahnung was das heisst, das DB
sagt nur "timing signal for data") die Zeile weitergeschaltet.
Und nach 320 Zeilen ne kurze Pause, und danach geht es von vorne in
Zeile 1, Pixel Nr. 1, los. Richtig?
Viele Grüsse & Dank
also wenn ich mir das timing so grob angucke passt deine geplante
vorgehensweise. wichtig ist das du halt horizontal und verikalen sync
bzw die timings einhälst (also ein paar pixel von jeder zeile als
horiz.sync, und ein paar zeilen als vert.sync). in der zeit am besten
die pixeldaten (rgb) alle auf null setzen (hatte da bei der
vga-ansteuerung schonmal richtig schöne effekte wenn die nicht auf 0
waren).
noch nen kleinen tipp : (so hab ichs zumindest gemacht)
geb erstmal nur feste muster (z.b. 4x4 oder 8x8 pixelblöcke) aus, um zu
sehen ob das timing passt. dabei sieht man auch schon direkt schön alle
darstellbaren farben. den farbwert kannst du dir am besten über die x
und y zähler generieren lassen, die du später ja eh brauchst um das ram
zu adressieren. und für das erste erfolgserlebnis sicherlich hilfreich
:-)
Hi,
danke! die xy-Zähler als Mustergeneratoren zu benutzen ist ne gute Idee
:-)
meinst du, vom Timing her reicht das dann auch noch, um Bild-Daten ins
RAM zu schaufeln?
übrigens werde ich wohl einen einfachen 8bit-Datenbus verwenden, der
FPGA hat genug Pins. Was ich mir nur nicht ganz sicher bin ist, ob die
8k LEs auch reichen, wenn ich später paar simple Grafikfunktionen
realisieren möchte (Linie, Kreis, Rechteck, Text). Hast du da vllt. eine
Ahnung?
gruss
>die xy-Zähler als Mustergeneratoren zu benutzen ist ne gute Idee
so hab ich die ersten geh-versuche gemacht :-)
>meinst du, vom Timing her reicht das dann auch noch, um Bild-Daten ins>RAM zu schaufeln?
ich habe bei meinem vga-controller nen pixeltakt von 25 mhz gehabt. also
ich denke wenn du nen pixeltakt von 5,33 mhz hast dürftest du bei 10ns
rams looocker zeit haben da was zu machen ... aber nimm dann vllt lieber
nen schnelleren quarz, vor allem hast du dann die möglichkeit mehr als
einen schreibzyklus pro pixeltakt zu machen.
generell würd ich das mit dem interface so vorschlagen :
baue dir eine statemachine die ein bzw mehrere bytes in einen puffer
einliest und dann als pixel ausgibt (ich hab z.b. nur mit 8 bit
gearbeitet, aber konnte mittels einer farbtabelle (palette) trotzdem
alle farbwerte erreichen (wenn auch nicht gleichzeitig) ).
in der zeit wo du die pixel ausgibst, die du zwischengespeichert hast,
kannst du deine ram-zugriffe machen. hier empfiehlt es sich je nachdem
wieviele zugriffe du pro gelesenem und ausgegebenem buffer-inhalt machen
kannst, mehrere zugriffe zu machen. so kannst du über ein mikroprozessor
interface und gleichzeitig über eine kleine grafik-engine (wie ich das
bei mir gemacht hab) den bild-speicher bearbeiten.
eine grafik-engine würde im einfachsten falle auch aus einer
state-machine bestehen die dann rechtecke u.s.w. füllt.
funktionen wie kreise oder linien sind sicherlich auch drin, aber das
hängt davon ab wie groß dein fpga ist. also ich hab meine engine in
einen spartan-3-200 bekommen und hatte noch einiges an platz ...
aber ich weiß nicht wie weit sich die spartans und die alteras
vergleichen lassen.
wenn du wie gesagt erstmal soweit bist das du a) nen stehendes bild
erzeugen kannst b) ein bild aus dem ram darstellen kannst, und
gleichzeitig dieses ram noch beschreiben kannst (bestenfalls von
mehreren seiten aus) dann bist du schon sehr weit ...
eine grafik-engine ist zwar nicht in 5 min programmiert, aber wenn man
sich ein paar gedanken macht ist das ganze recht schnell umgesetzt. ich
hatte da z.b. 3 adress-generatoren (bei 2 davon hab ich eine
start-adresse, ein breiten-register und 2 zähler gehabt, damit ließen
sich virtuelle zeichenflächen erstellen in denen man rummalen konnte,
und dann später einfach wieder in den sichtbaren bereich verschoben hat)
und eine relativ große statemachine die das ganze dann gesteuert hat.
aber ich habs ohne großartig simulieren zu müssen hinbekommen. es war
sogar nen mauszeiger als hardware-sprite mit drin :-) (hat aber nicht so
ganz funktioniert, ist noch nen fehler drin gewesen)
soviel mal als anregung ...
Hi Mason,
Vielen Dank!
Deine Grafik-Engine interessiert mich sehr. Kannst du hierzu mal ein
paar Codeschnipsel posten? Würde mich sehr interessieren, wie das so
aussieht bei dir.
Wenn ich dann erst mal so weit bin mit dem TFT-Controller, werde ich,
sofern Interesse da ist, das hier veröffentlichen oder einen
Wiki-Artikel bauen. Was meinst du?
TFT-Controller könnte ja auch für die vielen AVR-Bastler hier
interessant sein; damit kann man schon viele tolle Dinge machen.
Grüsse
Ein Paar Gedanken zu Deinem Vorhaben:
wiso nimmst Du SRAM und nicht SDRAM? Da Du Altera FPGA verwendest ist
ein SDRAM Controller (für umsonst) mit dem SOPC Builder schnell
implementiert. Dann hast Du viel Speicher für z.B. mehrere Pages und so
weiter. Danach baust Du einfach einen AVALON-Master, der die Daten aus
dem Speicher liest und diese anzeigt. Danach baust Du noch einen
AVALON-Master, der die Daten über SPI oder was weis ich vom uC nimmt und
in den Speicher schreibt.
Um Timings zu entspannen brauchst Du Dual-Clock-FIFOs.
Wenn Du erstmal weist, wie man einen AVALON Master baut, dann kannst Du
sehr schnell solche Projekte aufbauen. Sicherlich ist für Xilinx ein
ähnliches Vorgehen angesagt, aber da kann ich nichts dazu sagen.
So ein TFT Controller habe ich oft gemacht und dank SOPC braucht man da
nicht mal eine Stunden (eher weniger) um komplett alles "from scratch"
zu schreiben.
Schaue Dir den BEispiel VGA-Controller von Altera an -- sehr hilfreich.
Das Linienzeichen und andere Grafikoperationen habe ich mit einem NIOS
Prozessor gemacht, ist schnell genug und einfach (weil eben in C
geschrieben).
Grüße,
Kest
Hi,
also so NIOS-Sachen wollte ich eigentlich vermeiden, da ich damit keine
Erfahrung habe.
Und mit SDRAM habe ich am FPGA auch noch nie was gemacht, ich könnte mir
vorstellen dass das nicht ganz so einfach ist.....
@TheMason:
kannst du nicht mal bisschen Code von deinem TFT-Controller posten? :D
würde mich sehr interessieren, wie du das so gemacht hast.
Ich hab schon mal was zusammen gebastelt, was mir erstmal die richtigen
Timing-Signale (HSYNC, DTMG, DCLK) generiert, das schaut am Oszi soweit
gut aus. Jetzt muss nur noch diese RAM-Adressiererei dran gebaut werden,
dann sollte das klappen ;)
Gruss
@franz
kann ich gerne mal machen, allerdings ist das ganze eh noch ein bissl
raw (also nicht so gut kommentiert usw) ...
den code vom generieren der signale bzw. das ram adressieren kann ich
gerne mal posten, funktioniert aber nur auf dem spartan 3 board (bzw.
wenn du ein 32-bit ram bzw. 2x16-bit rams dran hast)
der code von der memory-engine (also dem füllen bzw. modifzieren von
blöcken) kann ich auch gerne posten, dieser sollte auch leichter
anzupassen sein als der code zum generieren der vga-signale, allerdings
bringt dir dieser code erst etwas wenn du wie gesagt selbst schon in den
frame-buffer schreiben kannst und gleichzeitig bild dargestellt wird.
ich such dir die sachen mal raus ...
NIOS brauchst Du doch gar nicht, sondern verwendest einfach
SOPC-Builder. Da klickst Du einen SDRAM-Controller rein und das war's.
Um aus dem Speicher zu lesen oder zu schreiben musst dann sehr wenig
machen (halt AVALON Master). Wenn Du dann SDRAM nicht verwenden
möchtest, klikst Du SDRAM Controller weg unf fügst von mir aus SRAM
Controller ein. Da musst Du keine einzige Zeile Code schreiben.
Mach es Dir doch nicht so schwer :-)
Grüße,
Kest
p.s.: hier ist eine VGA Master Version ohne Kommentar(e). Vielleicht
kannst Du was davon gebrauchen. Die kannst Du direkt bei SOPC einklinken
-- Framebuffer ist dann irgendein Speicher ab addresse 0.
Hallo,
vielen dank für den Code.
Ich hab jetzt schon mal ein Schema gezeichnet mit allen nötigen
Komponenten (FPGA, schnelles SRAM, ein kleiner Mikrocontroller zum
Steuern & Konfigurieren des FPGA). Das Board habe ich auch begonnen zu
layouten; dank dem FPGA, wo ich ja die Pinbelegung beliebig wählen kann
ist das recht einfach. Dennoch habe ich ein "Problem" entdeckt, bin mir
aber nicht ganz sicher ob es wirklich eines ist.
Und zwar ist die längste Datenleitung vom FPGA zum SRAM ca. 5 cm lang.
Macht das wohl Probleme, so von wegen Laufzeit oder so?
Dass ich bei so langen Leitungen Terminierung brauche, steht ausser
Frage.
Ich habe irgendwo mal gelesen, dass die Altera FPGA's interne
Terminierungswiderstände haben, die man im Quartus II irgendwo
aktivieren kann, aber ich finde keine entsprechende Option. Wo ist die
versteckt?
Gruss
@franz
also bei 5,33 mhz brauchst du dir um leitungslänge und terminierung
erstmal keine sorgen machen ...
und selbst wenn du das ram mit 20-30 mhz ansprichst dürfte es bei der
länge keine probleme geben.
im zweifelsfalle einfach ausprobieren. ich hab bei meinen ersten geh
versuchen mit dem spartan 3 board auch erstmal versucht das ram per uC
anzusprechen um zu gucken ob meine ram-statemachine richtig
funktioniert.
so sieht man dann ob da noch ein fehler drin ist (zumindest ansatzweise)
@ Franz (Gast)
>Und zwar ist die längste Datenleitung vom FPGA zum SRAM ca. 5 cm lang.>Macht das wohl Probleme, so von wegen Laufzeit oder so?
Nöö. Aber bei schlechter Masseführung kann das klingeln.
>Dass ich bei so langen Leitungen Terminierung brauche, steht ausser>Frage.
Nööö. Siehe Artikel Wellenwiderstand.
@ TheMason (Gast)
>also bei 5,33 mhz brauchst du dir um leitungslänge und terminierung>erstmal keine sorgen machen ...>und selbst wenn du das ram mit 20-30 mhz ansprichst dürfte es bei der>länge keine probleme geben.
Auch du mein junger Freund solltest dich mit dem Artikel
Wellenwiderstand befassen. Dann siehst du das Problem wahrscheinlich
etwas anders.
MFG
Falk
@ Michael X. (Firma: vyuxc) (der-michl)
>Dann mach gleich einen ordentlichen Lagenaufbau. Pi x Daumen sind single>ended Impedanzen 60R, differentielle 120R.
Na dann mal viel Spass beim Autobahnbau auf der vierlagigegn Platine ;-)
Ist ja schon wieder ein weilchen her.. Aber wie ging denn nun dein
Projekt weiter Franz? Hast du schon erste Erfolge verzeichnen können?
Habe jetzt selber ein Hitachi TFT TX14D12VM1CAA geschenkt bekommen.
Möchte mir auch gerne einen TFT Controller dafür bauen.
Das TFT funktioniert zwar schon super an einem Sharp LH792525
Controller, aber ich will mich jetzt nicht erst in die ARM7-Core
programmierung incl. Tool Chain einarbeiten und doch lieber erst mal bei
den AVR Controllern bleiben.
Grüße Steffen