VGA Bild Interlaced

OP #2086022
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?
Angehängte Dateien:
OP #2086470
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.
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #2086541
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?
OP #2086614
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.
Moderator (Firma: Titel) Persönliche Seite #2086656
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...
Moderator (Firma: Titel) Persönliche Seite #2086858
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
        :
OP #2087686
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.
Angehängte Dateien:
OP #2088106
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.
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #2088148
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... 
:-/
OP #2088312
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.
OP #2119877
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.
Angehängte Dateien:
Gast #2121850
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
Gast #2123419
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.
Angehängte Dateien:
OP #2123730
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.
Angehängte Dateien:
Gast #2123896
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
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #2501005
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...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren