Hallo, ich habe mit einem Spartan 3E eine VGA-Monitporansteuerung gebastelt. Es funktioniert so weit auch, allerdings kommt es zu Interlacing-Effekten (siehe Bild im Anhang). Hat jemand eine Idee, welche Modifikation am VGA-Signal das Problem beheben würde?
Martin S. schrieb: > allerdings kommt es zu Interlacing-Effekten (siehe Bild im Anhang). Wo ist da das fehlerhafte Interlacing zu sehen? Bzw: wie sollte das Bild denn richtig aussehen? > welche Modifikation am VGA-Signal das Problem beheben würde? Kann man erst sagen, wenn man weiß was falsch ist...
Ok, das hätte ich noch dazuschreiben können: Es handelt sich um ein normales Quadrat. Es ist mit Paint nachgemalt, wie es am Monitor aussieht, wobei die Ein-/Ausbuchtungen stochastisch sind (also wechseln und nicht fest diese Form haben müssen) und nur am rechten und linken Rand vorkommen. Und die Farbe ist in echt nicht rot, sondern weiß, aber das ist ja egal...(Der Fehler ist Farbunabhängig). Ich habe den Code angehängt. Im Code kommt zwar eine Bewegung des Quadrates auf dem Monitorschirm vor, diese ist jedoch nicht Schuld an diesem Phänomen. Es tritt auch bei stehendem Quadrat auf. Verzeiht mir bitte für die zu wenigen Kommentare im Code.
> if CLK25MHZ'event and CLK25MHZ='1' and CLK25MHZ'last_value='0'
Dafür gibt es die Funktion rising_edge()...
1 | CLK25MHZ_p: process(CLK) |
2 | begin
|
3 | if CLK'event and CLK='1' and CLK'last_value='0' |
4 | then CLK25MHZ<= not CLK25MHZ; |
5 | else null; |
6 | end if; |
7 | end process CLK25MHZ_p; |
8 | :
|
9 | if CLK25MHZ'event and CLK25MHZ='1' and CLK25MHZ'last_value='0' |
So werden keine Takte geteilt/erzeugt! Hast du ein Constraint auf den 50MHz-Takt gesetzt?
Da ich eher Anfänger in VHDL bin, habe ich mich natürlich bei einigen Sachen von anderen Projekten inspirieren lassen. Dort habe ich die Taktteiler-Variante gesehen. Sollte ich es sonst mit einer if-Abfrage gestalten? Die "wait until rising_edge()"-Version führt zu großem Ressourcenverbrauch bezüglich Slices und LUTs, weshalb ich die "if CLK'event and CLK='1' and CLK'last_value='0'"-Stratgie verwende. >Hast du ein Constraint auf den 50MHz-Takt gesetzt? Was bedeutet das für mich? Der 50MHZ-Takt ist ja doch ein Eingang (CLK), dort kann ich doch nichts vorgeben.
Martin S. schrieb: > Die "wait until rising_edge()"-Version führt zu großem > Ressourcenverbrauch bezüglich Slices und LUTs, weshalb ich die "if > CLK'event and CLK='1' and CLK'last_value='0'"-Stratgie verwende. Kannst du diese Behauptung beweisen? Woher kommt diese Information? Kannst du diese Behauptung an deinem Design begründen? Sieh dir das mal an: http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html Davon abgesehen... Ich meinte damit: if rising_edge(CLK) then ... statt if CLK'event and CLK='1' and CLK'last_value='0' then ... Denn: was ist besser lesbar? (Die Funktion rising_edge() macht genau das, was du lang und breit ausgeschrieben hast) > von anderen Projekten inspirieren lassen. Dort habe ich die > Taktteiler-Variante gesehen. Ja, was man nicht alles so sieht. Da klatscht jeder Anfänger sein erstes Design ins Internet, und Jahre später geistern die immer noch rum... :-/ Wenn Taktteiler so gemacht werden, dann hast du evtl. ein ungünstiges lokales Routing auf dem Takt. Das kann alles mögliche mit sich bringen... > Sollte ich es sonst mit einer if-Abfrage gestalten? Du solltest nur 1 Takt verwenden (deinen 50MHz CLK) und mit Clock-Enables arbeiten... >>Hast du ein Constraint auf den 50MHz-Takt gesetzt? > Was bedeutet das für mich? Der 50MHZ-Takt ist ja doch ein Eingang (CLK), > dort kann ich doch nichts vorgeben. Dann mach dich mal zum Thema Timing-Constraints (insbesondere dem Period-Constraint) schlau. Wenn du den Tools überhaupt keine Vorgabe zur gewünschten Taktfrequenz gibst, dann heißt das im Umkehrschluss, dass du auch mit 16MHz zufrieden wärst/bist...
vielleicht noch mal register an die ausgänge setzen, dass auch alles im gleichen takt rausgeht?
Random ... schrieb: > vielleicht noch mal register an die ausgänge setzen > dass auch alles im gleichen takt rausgeht? Das Design ist schon komplett synchron, da wird nichts kombinatorisch an die Ausgänge gegeben... Ich würde jetzt erst mal ein 25MHz-clock-Enable einführen:
1 | signal CE25MHZ: STD_LOGIC:='0'; |
2 | |
3 | :
|
4 | |
5 | process(CLK) begin |
6 | if rising_edge(CLK) then |
7 | CE25MHZ<= not CE25MHZ; |
8 | end if; |
9 | end process; |
10 | |
11 | :
|
12 | |
13 | process(CLK) |
14 | begin
|
15 | if rising_edge(CLK) then |
16 | if CE25MHZ='1' then |
17 | -- Zaehler
|
18 | if VGA_Zaehler_HS<799 then |
19 | :
|
20 | |
21 | process begin |
22 | wait until rising_edge(CLK); |
23 | if CE25MHZ='1' then |
24 | if VGA_Zaehler_VS < 2 |
25 | :
|
Vielen Dank schonmal für die vielen Informationen! > > Die "wait until rising_edge()"-Version führt zu großem > > Ressourcenverbrauch bezüglich Slices und LUTs, weshalb ich die "if > > CLK'event and CLK='1' and CLK'last_value='0'"-Stratgie verwende. > Kannst du diese Behauptung beweisen? > Woher kommt diese Information? > Kannst du diese Behauptung an deinem Design begründen? Nun, ich weiß nicht mehr wirklich, wo ich es aufgegabelt habe. Ich meine, dass sich irgendwann mal in einem anderen Testprojekt eine enorme Änderung der Ressourcen durch die Änderung von "wait until..." auf "if > > CLK'event and CLK='1' and CLK'last_value='0'" ergeben hat und das als Bestätigung der Aussage angesehen. Da ich allerdings nicht mehr sicher sagen kann, ob ich auch andere Änderungen parallel gemacht habe, und ein Test mit dem aktuellem Projekt gezeigt hat, dass man bei allen Varianten immer den gleichen Verbrauch hat, möchte ich die Aussage hiermit zurücknehmen. Ich habe nun das Projekt gemäß der Ideen oben umgebaut (und danach noch etwas umgestaltet, um die Übersichtlichkeit zu erhöhen) und ein Constraint für das CLK-Signal hinzugefügt ("TIMESPEC TS_CLK = PERIOD "CLK" 50 MHz HIGH 50%;" hat ein normaler Quarz eigentlich 50% High-Periode? Eigentlich schon, oder?). Allerdings habe ich das eigentliche Problem immer noch, ich fürchte, dass es mehr ein VGA statt ein FPGA-Phönomen ist, welches sich vielleicht irgendwie mit einem anderen Timingverhalten ausschalten lässt? Es sei noch dazugesagt, dass es sich um ein TFT-Monitor handelt, an dem ich es teste. Allerdings kann er ohne Probleme das Bildsignal 640x480 mit 60 HZ anzeigen.
Martin S. schrieb: > hat ein normaler Quarz eigentlich 50% > High-Periode? Eigentlich schon, oder?) Üblicherweise schon. > dass es mehr ein VGA statt ein FPGA-Phönomen ist, Hast du dein Timing mal mit einem Oszi kontrolliert? Reichen die Pegel aus?
Nun, hier sind die Messungen. Eigentlich sieht es doch recht ähnlich aus (echter Monitor und eigenes Projekt im Vergleich). Oder wird beim echten VGA-Monitor über einen der auf der Basys2-Platine auf GND gelegten Verbindungen eine weitere Information übertragen? Bei den ersten beiden Bildern muss man übrigens die unterschiedliche Zeitbasis und die vertauschten Farben beachten.
Martin S. schrieb: > Eigentlich sieht es doch recht ähnlich aus > (echter Monitor und eigenes Projekt im Vergleich). Ja. Das sieht eigentlich soweit gut aus... > Oder wird beim echten > VGA-Monitor über einen der auf der Basys2-Platine auf GND gelegten > Verbindungen eine weitere Information übertragen? Sieh dir mal das Grün-Signal des Referenz-Monitorausgangs zusammen mit den Sync-Signalen an. Ältere Monitore verwenden u.U. Sync-On-Green... :-/
Naja ein älterer Monitor ist es nicht wirklich, sondern eher genau das Gegenteil. Ich fürchte sogar, dass da das Problem liegt... Über das Forum dieses Projektes: http://avga.prometheus4.com/index.php bin ich zu diesen beiden nützlichen Quellen gekommen, die ich mir mal morgen in Ruhe ansehen werde: http://www.maxim-ic.com/app-notes/index.mvp/id/734 http://www.maxim-ic.com/app-notes/index.mvp/id/1184 Vielleicht finde ich dort die Lösung.
Für Interessenten möchte ich folgendes noch erwähnen: - Ich habe auf dieser Seite: http://www.derepas.com/fabrice/hard/#squares einen Code gefunden, der ebenfalls auf den Monitor schreiben kann. Auch bei diesem Code war auf dem Monitor dieses Krisseln deutlich. Eine Änderung der Back-Porch-Werte hat auch so recht nichts gebracht. - Laut http://www.epanorama.net/faq/vga2rgb/calc.html muss man bei 640x480, 60HZ einen Takt von 25,17MHZ verwenden. Jedoch kann man 800x600, 72HZ direkt mit 50MHZ betreiben. Eine Änderung des Ursprungscodes hat zwar letzendlich funktioniert, jedoch ebenfalls mit dem Krissel, zum Teil sogar mehr Pixel weit als im 640x480 Code. => Ich schließe darauf, das das Problem vielleicht gar nicht im Code selbst liegt, sondern möglicherweise die Hardware etwas damit zu tun haben könnte.
Martin S. schrieb: > Ich schließe darauf, das das Problem vielleicht gar nicht im Code > selbst liegt, sondern möglicherweise die Hardware etwas damit zu tun > haben könnte. Was hast Du denn für einen Monitor? Bei TFTs hilft es oft die Auto bzw. Sync-Funktion zu aktivieren. Duke
Ich habe es sowohl mit einem TFT als auch mit einem älteren Röhren-Monitor ausprobiert. Das mit dem Snyc könnte ich mal bei Gelegenheit testen.
Martin S. schrieb: > - Laut http://www.epanorama.net/faq/vga2rgb/calc.html muss man bei > > 640x480, 60HZ einen Takt von 25,17MHZ verwenden. Hallo, 640x480@60Hz läuft perfekt mit genau 25.000MHz. Ich habe diese Auflösung schon mehrmals verwendet und es gab noch nie Probleme mit Darstellung. Egal ob auf CRT/TFT Monitor oder auf Plasma/LCD Fernseher. MfG aus Westerwald
Martin S. schrieb: > Ich schließe darauf, das das Problem vielleicht gar nicht im Code > selbst liegt, sondern möglicherweise die Hardware etwas damit zu tun > haben könnte. Hast Du eine Testbench? Ansonsten nimm mal die aus dem Anhang und schau nach, ob die timings stimmen. Außerdem könntest Du nochmal prüfen ob die Polarität von HSYNC und VSYNC richtig ist. Duke P.S.: Es ist übersichtlicher, wenn die Datei so heißt, wie die entity bzw. das package.
Hi, danke für die Hilfe. Aber ich verstehe nicht ganz, was mir die Testbench bringt. Ich habe bereits den vhdl-Code in ModelSim simuliert, indem ich das clock-Signal über die after-Befehle generiert habe (so wie in der Testbench). Warum sollte man, wie es in der Testbench der Fall ist, sämtliche Signale quasie neu benennen und mit den "alten" über die Port-Map verknüpfen? Es sei nebenbei gesagt, dass mir das Simulationsergebniss recht schlüssig aussah. Ich habe das Ergebnis in den Anhang geladen.
Martin S. schrieb: > Warum sollte man, wie es in der Testbench der Fall ist, > sämtliche Signale quasie neu benennen und mit den "alten" über die > Port-Map verknüpfen? Damit klar ist, welches Signal in der Testbench definiert ist. Damit kann man sie schön von internen Signalen unterscheiden. Außerdem baue ich mir gern ein paar Signalchecker in die Testbench ein. > Es sei nebenbei gesagt, dass mir das Simulationsergebniss recht > schlüssig aussah. Schlüssig aussehen reicht dem Display vermutlich nicht. Hast Du die Zeiten im Simulator mal nachgemessen und verglichen [1]? Deine Sync-Timings sehen ganz gut aus:
1 | # ** Note: :pong_480x640_tb: hsync rate: 31250 Hz |
2 | # ** Note: :pong_480x640_tb: hsync pulse width: 3840 ns |
3 | # ** Note: :pong_480x640_tb: vsync rate: 59 Hz |
4 | # ** Note: :pong_480x640_tb: vsync pulse width: 64000 ns |
Duke [1] http://tinyvga.com/vga-timing/640x480@60Hz
Die Frage ist schnell beantwortet, siehe Anhang, dort habe ich die ucf eingefügt.
danke, hat mich mal eben interessiert, da ich das spartan-3e entwicklungsboard habe, und der vga port auf diesem board ja "nur" fünf verbundene pins hat. grüsse
Falls jemand beim Suchen auf diesen Thread stößt: Das Problem ist behoben. Ich hatte das Board ohne externen Quarz betrieben. Der interne hatte wohl eine so schlechte Qualität, dass das Bild einfach grausig aussah. Mit einem externen Quarz läuft es super!
Martin S. schrieb: > Ich hatte das Board ohne externen Quarz betrieben. Der interne hatte > wohl eine so schlechte Qualität, dass das Bild einfach grausig aussah. Das würde mir zu denken geben... :-/ Was ist "der interne Quarz"? Was kann an diesem Quarz so schlecht sein, dass dein Bild nicht gut aussieht? Das was du da hattest sieht eher nach einem "klitzekleinen" Timingproblem aus. Durch die Verwendung eines anderen Takteingangs und das dadurch nötige geänderte Routing kann es dann schon mal passieren, dass das eine Design scheinbar stabil und das Andere gar nicht läuft...
Bei näherer Betrachtung des Schaltplans fällt auf, dass der Taktgeber kein Quarz (-oszillator) ist, sondern der IC LTC6905, welcher wahrscheinlich nicht so genau ist wie ein Quarz. Dass der Fehler am Routing liegt wäre aber durchaus auch denkbar.
Wenn das Ding über eine DSM läuft, dann spielt das bei 25Mhz gar keine Rolle! Eher schon ist es so, dass da was von den Teilerverhältnissen nicht gepasst hat.
> RED<="111"; > GRN<="111"; > BLUE<="11"; Warum werden den Farben unterschiedliche Bitbreiten zugeordnet?
Das ist so hardwareseitig auf dem Board vorgegeben. Vielleicht haben die Entwickler sich überlegt, dass man in blau nicht so viele Unterschiede erkennen kann... Siehe http://www.digilentinc.com/Data/Products/BASYS2/Basys2_sch.pdf Seite 1, unten links.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.