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


von Matze (Gast)


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:

Lesenswert?

Hier ein Bild dazu...

von Klakx (Gast)


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)


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)


Lesenswert?

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

von Duke Scarring (Gast)


Angehängte Dateien:

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. S. (engineer) Benutzerseite


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)


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)


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)


Lesenswert?

Schaltest du HSYNC während VSYNC aus? Das wäre falsch.

Und dieser Monitor funktioniert ansonsten noch? ;)

von S. R. (svenska)


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

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.