Forum: FPGA, VHDL & Co. Probleme VGA-Controller


von VGA (Gast)


Lesenswert?

Hallo,
ich verzweifel langsam. Ich will einen einfachen VGA-Controller 
schreiben und bekomme auch ein Bild auf dem Monitor angezeigt. Der 
Monitor gibt immer eine Fehlermeldung aus bezüglich Auflösung und 
Frequenz. Deshalb gehe ich von einem Timing-Problem aus.

Hier mein VHDL Code
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_UNSIGNED.ALL;
4
use IEEE.STD_LOGIC_ARITH.ALL;
5
use IEEE.NUMERIC_STD.ALL;
6
7
8
entity vga_control is
9
    Port (
10
            clk:     IN     std_logic;
11
            reset:   IN     std_logic;
12
            vsync:   OUT    std_logic;
13
            hsync:   OUT    std_logic;
14
            red:     OUT    std_logic_vector(3 downto 0);
15
            green:   OUT    std_logic_vector(3 downto 0);
16
            blue:    OUT    std_logic_vector(3 downto 0)
17
     );
18
end vga_control;
19
20
21
22
architecture Behavioral of vga_control is
23
24
25
signal counter_h :  std_logic_vector(11 downto 0) ;
26
signal counter_v :  std_logic_vector(11 downto 0) ;
27
28
29
30
31
32
begin 
33
process(clk, reset) is
34
  
35
begin
36
    if reset='1' then 
37
        counter_h <= (others => '0');
38
        counter_v <= (others => '0');
39
    hsync<='1';
40
    vsync<='1';
41
    red<=(others => '0');
42
    green<=(others => '0');
43
    blue<=(others => '0');
44
    
45
    elsif rising_edge(clk) then
46
        
47
        if counter_h<1688 then 
48
      counter_h <= counter_h+1;
49
    else 
50
      counter_h<= (others => '0');            
51
            if counter_v<1066 then
52
        counter_v<=counter_v+1;  
53
      else 
54
        counter_v<=(others => '0');
55
      end if;
56
        end if;  
57
    end if;
58
  
59
  
60
--generate v- and hsync
61
if counter_h<112 then
62
  hsync<='0';
63
else
64
  hsync<='1';
65
end if;
66
67
if counter_v<3 then
68
  vsync<='0';
69
else
70
  vsync<='1';
71
end if;
72
73
--set black during fron/back porch and retrache
74
if( counter_h < 360 ) then
75
  red<=(others => '0');
76
  green<=(others => '0');
77
  blue<=(others => '0');
78
elsif( counter_h >= 1640 and counter_h < 1688 )
79
  red<=(others => '0');
80
  green<=(others => '0');
81
  blue<=(others => '0');
82
elsif( counter_v < 41 )
83
  red<=(others => '0');
84
  green<=(others => '0');
85
  blue<=(others => '0');
86
  elsif( counter_h >= 1065 and counter_h < 1066 )
87
  red<=(others => '0');
88
  green<=(others => '0');
89
  blue<=(others => '0');
90
91
  
92
--activ part
93
else 
94
95
96
--here is some sample code to test
97
98
end Behavioral;

Der Input Clock kommt von einem AXI-Businterface und hat eine geringe 
Abweichung von den 108MHz (~106.7 MHz). Als Hardware dient ein Zedboard.

Über möglich Problemlösung wäre ich sehr dankbar.

Gruß

von Sigi (Gast)


Lesenswert?

0. Async-Reset? muss das sein?
1. Hast du alle Pins überprüft, Pinzuweisung in UCF etc. ok?
2. Deine Ziel-Auflösung ist 1280x1024@~60Hz  ??
2. Lass doch einfach mal zu Beginn die Farbe komplett auf "00..0",
   dann bleibt nur die Sync-Signale, der Monitor sollte darauf
   ansprechen und Fehlersuche ist ein Stück einfacher.
3. Ich würde den Sync- und Farbbereich anders aufteilen:
   von       0   ..1023       : Farbe
   von 1024      ..1023+FP    : Front Porch
   von 1024+FP   ..1023+FP+SY : Sync
   von 1024+FP+SY..1688-1     : Back Porch
   dann kannst du aus count_h/v direkt auf das Pixel schliessen.

Bem: deine Counter und die Syncs sehen eigentlich ok aus.

von VGA (Gast)


Lesenswert?

Das mit dem reset werde ich ändern, muss natürlich nicht unbedingt sein.
Ja genau die Ziel-Auflösung soll 1280x1024@~60Hz sein.

Ok das, mit den Farben, werde ich mal morgen versuchen, da ich die 
Hardware gerade nicht zur Verfügung habe.

Danke für die Tipps. Morgen werde ich dann auch den Counter umschreiben 
so dass dieser mit den Pixel übereinstimmt.

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


Lesenswert?

VGA schrieb:
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
> use IEEE.STD_LOGIC_ARITH.ALL;
> use IEEE.NUMERIC_STD.ALL;
Viel hilft viel?
Mein Tipp: die letzte Zeile reicht aus.

von peter (Gast)


Lesenswert?

http://tinyvga.com/vga-timing/1280x1024@60Hz

Habe ich auch gehabt, die Monitore sind  sehr pingelig geworden.
Schraube  ein wenig runter an den Zahlenwerten, die oben drin sind.

Ich habe 2 verschiedene Monitore, bei einem kommt die Meldung 
"Timingfehler", das Bild ist aber da, und auf den anderen Monitor läuft 
es ohne Meldung.

Gruss

von Fpgakuechle K. (Gast)


Lesenswert?

VGA schrieb:
> Hallo,
> ich verzweifel langsam. Ich will einen einfachen VGA-Controller
> schreiben und bekomme auch ein Bild auf dem Monitor angezeigt. Der
> Monitor gibt immer eine Fehlermeldung aus bezüglich Auflösung und
> Frequenz. Deshalb gehe ich von einem Timing-Problem aus.
>
> Hier mein VHDL Code
>
>
1
> elsif( counter_h >= 1640 and counter_h < 1688 )
2
>   red<=(others => '0');
3
>   green<=(others => '0');
4
>   blue<=(others => '0');
5
> elsif( counter_v < 41 )
6
>   red<=(others => '0');
7
>   green<=(others => '0');
8
>   blue<=(others => '0');
9
>   elsif( counter_h >= 1065 and counter_h < 1066 )
10
>   red<=(others => '0');
11
>   green<=(others => '0');
12
>   blue<=(others => '0');
13
14
>


der "else if" Zweig counter_h >= 1065 ist toter code da es ein paar 
zeilen drüber den Zweig if ( counter_h >= 1640 and counter_h < 1688 
gibt. Sollte jetz aber nicht das problem sein.


Verdrahtungsproblem kann auch ein problem sein oder takt fehlt. Wenn du 
ein scop hast dann schau dir mal die signale am Kabel an. Pinout 
checken, vielleicht ist ja sync am falschen Pin. Ohne scope sind die 
syncs auch messbar. schick sie einfach über andere pins wieder in den 
FPGA und leg sie auf counter die bspw bei vsync auf 60 zählen und dann 
einen ausgang mit LED negieren, die blinkt dan im sekundentakt. Oder du 
hast ein Multimeter mit Frequenzmesser.

Die syncs im resetfall (counter = 0) auf den selben Wert setzen wie im 
Normalbetrieb (bei dir '0').
1
 if reset='1' then 
2
        counter_h <= (others => '0');
3
        counter_v <= (others => '0');
4
    hsync<='1';   --besser '0'
5
    vsync<='1';
6
  
7
    
8
    elsif rising_edge(clk) then
9
        
10
  
11
--generate v- and hsync
12
if counter_h<112 then
13
  hsync<='0';
14
else
15
  hsync<='1';
16
end if;
17
18
if counter_v<3 then
19
  vsync<='0';
20
else
21
  vsync<='1';
22
end if;


In dem process wird der reset/clk Zweig zu früh beendet. Ich habs mal 
neu eingerückt, da siehts man besser:
1
process(clk, reset) is
2
  
3
begin
4
    if reset='1' then 
5
        counter_h <= (others => '0');
6
        counter_v <= (others => '0');
7
        hsync<='1';
8
        vsync<='1';
9
        red<=(others => '0');
10
        green<=(others => '0');
11
        blue<=(others => '0');
12
    
13
    elsif rising_edge(clk) then
14
        
15
        if counter_h<1688 then 
16
          counter_h <= counter_h+1;
17
        else 
18
          counter_h<= (others => '0');            
19
          if counter_v<1066 then
20
            counter_v<=counter_v+1;  
21
          else 
22
            counter_v<=(others => '0');
23
         end if;
24
       end if;  
25
    end if;

es könnte gut sein das die syncs ungebuffert laufen (spikes wegen 
counterumschaltung), nach richtiger synchroner Beschreibung sieht das 
nicht aus.

MfG,

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


Lesenswert?

VGA schrieb:
> Der Monitor gibt immer eine Fehlermeldung aus bezüglich Auflösung und
> Frequenz. Deshalb gehe ich von einem Timing-Problem aus.
Und was sagt die Simulation?
Die Simulation wird übrigens flasch sein, denn die Sensitivliste ist 
unvollständig! Man mischt nicht (wie von Fpga Kuechle schon angemerkt) 
Kombinatorik und getaktete Abläufe in einen Megamonsterprozess hinein!
1
process(clk, reset) is
2
  
3
begin
4
    if reset='1' then 
5
       ...
6
    elsif rising_edge(clk) then
7
       ...
8
    end if;   ----- ENDE des getakteten Prozesses
9
   
10
    if counter_h<112 then  ---- Hoppla, da kommt noch was!
11
      ...                  --  counter_h fehlt in der Sensitivliste
12
    end if;
13
    if counter_v<3 then    --  counter_v fehlt in der Sensitivliste
14
      ...
15
    end if;
16
     ....

Auch interessant: was sagt das Oszilloskop? Hast du brauchbare Pegel?

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.