Forum: FPGA, VHDL & Co. VGA Bild Interlaced


von Martin S. (maklin)


Angehängte Dateien:

Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Martin S. (maklin)


Angehängte Dateien:

Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>     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?

von Martin S. (maklin)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Random .. (thorstendb) Benutzerseite


Lesenswert?

vielleicht noch mal register an die ausgänge setzen, dass auch alles im 
gleichen takt rausgeht?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
        :

von Martin S. (maklin)


Angehängte Dateien:

Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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?

von Martin S. (maklin)


Angehängte Dateien:

Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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... 
:-/

von Martin S. (maklin)


Lesenswert?

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.

von Martin S. (maklin)


Angehängte Dateien:

Lesenswert?

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.

von Duke Scarring (Gast)


Lesenswert?

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

von Martin S. (maklin)


Lesenswert?

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.

von Dimi S. (ilovespeccy)


Lesenswert?

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

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Martin S. (maklin)


Angehängte Dateien:

Lesenswert?

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.

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

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

von joe (Gast)


Lesenswert?

Hallo,

@Martin S.

Welche Eingänge / Ausgänge konfigurierts Du in der UFC?

von Martin S. (maklin)


Angehängte Dateien:

Lesenswert?

Die Frage ist schnell beantwortet, siehe Anhang, dort habe ich die ucf 
eingefügt.

von joe (Gast)


Lesenswert?

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

von Martin S. (maklin)


Lesenswert?

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!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Martin S. (maklin)


Lesenswert?

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.

von Terry (Gast)


Lesenswert?

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.

von Weltbester FPGA-Pongo (Gast)


Lesenswert?

> RED<="111";
> GRN<="111";
> BLUE<="11";

Warum werden den Farben unterschiedliche Bitbreiten zugeordnet?

von Martin S. (maklin)


Lesenswert?

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.

von B. (Gast)


Lesenswert?

Die hatten wohl nur 8 Bit zur Verfügung.

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
Noch kein Account? Hier anmelden.