Forum: FPGA, VHDL & Co. VGA Controller mit Krummen und Flimmerndem Bild, Timings scheinen korrekt


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Matze (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich möchte an einem Nexys4DDR (Artix7) einen VGA-Monitor betreiben, dass 
Bild flimmert jedoch und ist auch recht krumm...

Hier die Timings:
https://www.avrfreaks.net/sites/default/files/k2J87.jpg

Das Board läuft mit 100MHz...

Also stimmt vermutlich was mit meinem Code nicht:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use work.utilities.all;
4
5
-- Uncomment the following library declaration if using
6
-- arithmetic functions with Signed or Unsigned values
7
use IEEE.NUMERIC_STD.ALL;
8
9
-- Uncomment the following library declaration if instantiating
10
-- any Xilinx leaf cells in this code.
11
--library UNISIM;
12
--use UNISIM.VComponents.all;
13
14
entity VGA_Controller is
15
    Port ( red : out STD_LOGIC_VECTOR (3 downto 0);
16
           grn : out STD_LOGIC_VECTOR (3 downto 0);
17
           blu : out STD_LOGIC_VECTOR (3 downto 0);
18
           vsync : out STD_LOGIC;
19
           hsync : out STD_LOGIC;
20
           
21
           clk : in STD_LOGIC);
22
end VGA_Controller;
23
24
architecture Behavioral of VGA_Controller is
25
signal int_vsync : STD_LOGIC; -- Triggert 2. Timer für Signalverlängerung
26
signal int_hsync : STD_LOGIC; -- Triggert 2. Timer für Signalverlängerung
27
signal start_vsync : std_logic;
28
signal start_hsync : std_logic;
29
signal end_vsync : std_logic;
30
signal end_hsync : std_logic;
31
signal rst_vsync : std_logic;
32
signal rst_hsync : std_logic;
33
signal vsync_count : std_logic_vector(log2(1678400)-1 downto 0);
34
signal hsync_count : std_logic_vector(log2(3177)-1 downto 0);
35
begin
36
37
    process (clk)
38
    begin
39
        if rising_edge(clk) then
40
            if hsync_count <= x"236" or hsync_count >= x"C0B" or vsync_count >= ('1' & x"8EC78") or vsync_count <= ('0' & x"1A770") then
41
                red <= "0000";
42
                blu <= "0000";
43
                grn <= "0000";
44
            else
45
                red <= "1111";
46
                blu <= "1111";
47
                grn <= "1111";           
48
            end if;         
49
        end if;
50
    end process;
51
    
52
    process (clk)
53
    begin      
54
        if rising_edge(clk) then  
55
            if hsync_count <= x"04D" then    --x"fe4d90" then 
56
                hsync <= '0';                   --Signal ausgeben
57
            else    
58
                hsync <= '1';
59
            end if;
60
        end if;
61
    end process; 
62
63
    h_sync: entity work.Counter 
64
    generic map (
65
        MAX   => 3177,
66
        MIN   => log2(3177-1)
67
    )
68
    port map(
69
        d_in   => x"04E", --: in  std_logic_vector(log2(MAX)-1 downto 0),
70
        load   => int_vsync,    --: in  std_logic,
71
        up     => '1',   --: in  std_logic := '1',
72
        en     => '1',    --: in  std_logic,
73
        rst    => '0',        --: in  std_logic,
74
        clk    => clk,     --: in  std_logic,
75
        ov     => int_hsync,
76
        count  => hsync_count   --: out std_logic_vector(log2(MAX)-1 downto 0)
77
    );
78
79
    process (clk)
80
    begin      
81
        if rising_edge(clk) then  
82
            if vsync_count <= '0' & x"00960" then     --x"AFC8" then 
83
                vsync <= '0';                   --Signal ausgeben
84
            else
85
                vsync <= '1';
86
            end if;
87
        end if;
88
    end process; 
89
    
90
    v_sync: entity work.Counter 
91
    generic map (
92
        MAX   => 1678400-1,
93
        MIN   => log2(1678400-1)
94
    )
95
    port map(
96
        d_in   => (others => '0'), --: in  std_logic_vector(log2(MAX)-1 downto 0),
97
        load   => '0',    --: in  std_logic,
98
        up     => '1',   --: in  std_logic := '1',
99
        en     => '1',    --: in  std_logic,
100
        rst    => '0',        --: in  std_logic,
101
        clk    => clk,     --: in  std_logic,
102
        ov     => int_vsync,
103
        count  => vsync_count   --: out std_logic_vector(log2(MAX)-1 downto 0)
104
    );
105
end Behavioral;

Hier der Counter:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.all;
3
use IEEE.numeric_std.all; --Signed/unsigned
4
use work.utilities.all;
5
6
entity Counter is
7
  generic (
8
    MAX   : positive := 8;
9
    MIN   : positive := 4
10
  );
11
  port (
12
    d_in   : in  std_logic_vector(MIN-1 downto 0);
13
    load   : in  std_logic;
14
    up     : in  std_logic := '1';
15
    en     : in  std_logic;
16
    rst    : in  std_logic;
17
    clk    : in  std_logic;
18
    ov     : out std_logic;
19
    count  : out std_logic_vector(MIN-1 downto 0)
20
  );
21
end entity;
22
23
architecture rtl of Counter is 
24
  signal counter : unsigned(count'range) := (others => '0');
25
begin
26
  process (clk)
27
  begin
28
    if rising_edge(clk) then
29
      if (rst or ov)= '1' then
30
        counter <= (others => '0');
31
      elsif load = '1' then
32
        counter <= unsigned(d_in);
33
      elsif en = '1' then
34
        if up = '1' then
35
          counter <= counter + 1;
36
        else
37
          counter <= counter - 1;
38
        end if;
39
      end if;
40
    end if;
41
  end process;
42
  ov <= '1' when (counter >= MAX and en = '1') else '0';
43
  count <= (count'high downto counter'length => '0') & std_logic_vector(counter);
44
end architecture;

Vielleicht hat mir jemand eine Idee woran es liegen könnte???

Schonmal vielen Dank,
Matze

: Bearbeitet durch Admin
von Matze (Gast)


Angehängte Dateien:

Bewertung
1 lesenswert
nicht lesenswert
Hier ein Bild dazu...

von Klakx (Gast)


Bewertung
0 lesenswert
nicht lesenswert
funktioniert die Simulation? Testbench?

vielleicht hängt ein Counter schief. Die hex-Werte finde ich jetzt nicht 
unbedingt einfach zu debuggen beim Gegenlesen.

von C. A. Rotwang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Matze schrieb:

>     process (clk)
>     begin
>         if rising_edge(clk) then
>             if hsync_count <= x"04D" then    --x"fe4d90" then
>                 hsync <= '0';                   --Signal ausgeben
>             else
>                 hsync <= '1';
>             end if;
>         end if;
>     end process;
>
>     h_sync: entity work.Counter
>     generic map (
>         MAX   => 3177,
>         MIN   => log2(3177-1)
>     )
Hm, counter der nicht ab 0 zählt?!
>
>     process (clk)
>     begin
>         if rising_edge(clk) then
>             if vsync_count <= '0' & x"00960" then     --x"AFC8" then
>                 vsync <= '0';                   --Signal ausgeben
>             else
>                 vsync <= '1';
>             end if;
>         end if;
>     end process;


sind die syncs in der richtigen Polarität?
http://martin.hinner.info/vga/timing.html

Pegel in Ordnung? Also 5V knackige Flanke? liegen die Grounds richtig?
http://www.javiervalcarce.eu/html/vga-signal-format-timming-specs-en.html

von C. A. Rotwang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Da gab es mal einen Thread zu einem ähnlichen Fehlerbild:
Beitrag "VGA Testbild-Fehler-Symptome bekannt ?"

von Duke Scarring (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Eine schöne Einschwingkurve hast Du da...

Geht Deine log2-Funktion richtig?
Nicht das da ein Bit im Zählvektor fehlt. BTDT.

Duke

von Jürgen S. (engineer) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Matze schrieb:
> Hier ein Bild dazu...

Cool! Ich würde sagen, du zählst mal deine Synchs durch oder misst die 
Pegel.

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
Matze schrieb:
> Vielleicht hat mir jemand eine Idee woran es liegen könnte???

Irgendwas machst du falsch. Ich sehe in deinem Code die üblichen 
Konstanten nicht. Die Berechnungen habe ich mir jetzt nicht im Detail 
angeschaut, aber es ist sinnvoller, sämtliche Zähler auf Pixeltakt-Basis 
aufzubauen als mit den Mikrosekunden zu hantieren.

Für 640x480@60 (25 MHz Pixeltakt) reicht es also völlig aus, wenn du die 
Zeilen von 0..799 zählst (hcount) und die Spalten von 0..524 (vcount).

Das Bild ist sichtbar, wenn (hcount < 640 and vcount < 480).
Hsync ist High, wenn (hcount >= 656 and hcount < 752), sonst Low.
Vsync ist High, wenn (vcount >= 490 and vcount < 492), sonst Low.
Das ergibt ein stabiles Bild.

Mit einem 100 MHz Basistakt kannst du auch 800x600@72 (50 MHz Pixeltakt) 
bauen. Dann gelten folgende Zahlen:

Das Bild ist sichtbar, wenn (hcount < 800 and vcount < 600).
Hsync ist High, wenn (hcount >= 856 and hcount < 976), sonst Low.
Vsync ist High, wenn (vcount >= 637 and vcount < 643), sonst Low.

Den Zählertakt von 100 MHz musst du entsprechend runterteilen, oder du 
ignorierst bei den Vergleichen einfach die unteren ein oder zwei Bits.

Und dann simulierst du den Kram mal über 20-50 ms (mehr als einen ganzen 
Frame) und schaust, ob die Syncsignale auch zu den richtigen Zeiten 
kommen und ob die Zähler ordentlich zählen (und nicht um ±1 daneben 
liegen).

von Pedro (Gast)


Bewertung
0 lesenswert
nicht lesenswert
S. R. schrieb:
> Mit einem 100 MHz Basistakt kannst du auch 800x600@72 (50 MHz Pixeltakt)
> bauen. Dann gelten folgende Zahlen:

Da geht laut Tabelle Projekt VGA Core in VHDL unten offenbar auch 
1280x1024.

von *.* (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Schaltest du HSYNC während VSYNC aus? Das wäre falsch.

Und dieser Monitor funktioniert ansonsten noch? ;)

von S. R. (svenska)


Bewertung
0 lesenswert
nicht lesenswert
Pedro schrieb:
> Da geht laut Tabelle Projekt VGA Core in VHDL
> unten offenbar auch 1280x1024.

Das stimmt, allerdings muss die Gesamtschaltung dann auch 100 MHz 
schaffen und es passiert relativ schnell, dass das nicht mehr so ist. 
Mit einem Pixeltakt von 50 MHz hat man da deutlich mehr Luft.

Außerdem kann mein Testmonitor nur 1024x768. :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.