Forum: FPGA, VHDL & Co. VGA-Signal -Übertragungsprobleme.


von Mike (Gast)


Lesenswert?

Hallo Zusammen,

dieser Code macht mich verrückt und ich kann den Fehler einfach nicht 
finden.

Folgender Zusammenhang: Habe den Code aus einer Übung heraus kopiert und 
wollte ihn einmal testen und ein Rechteckt per VGA auf den Monitor 
übertragen.


Leider wir kein Signal übertragen und ich begann Testleds in den Code 
einzubauen, um rauszufinden wo der Fehler liegen könnte.

Das Problem ist: Ich habe in den ersten beiden Prozessen über ein 
If-Statement, die einen Taster und die Reset-Taste abfragt, eine Ein- 
und Ausfunktion einer LED eingebaut. Das Ding ist nur, dass die LEDs 
immer brennen, egal ob ich den Taster drücke oder nicht.

PIN-Belegung der Taster ist tausendfach gecheckt worden und richtig.
Irgendwo muss ein grundlegender Fehler sein, den ich einfach nicht 
finden kann...

Vielleicht kann jemand mit mehr Erfahrung und Expertise mir 
weiterhelfen...
Vielen Dank für alle Antworten...

Hier der komplette Code:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
use ieee.numeric_std.all;
6
7
entity vga_control is
8
port (
9
reset, taster           : in std_logic;
10
clk                     : in std_logic; 
11
12
VGA_CLK,                                    -- Should be 25.125 MHz VGA_CLK,  Dot clock to DAC
13
VGA_HS,                                     -- Active Low Horizontal Sync
14
VGA_VS,                                     -- Active Low Vertical Sync
15
VGA_BLANK,                                   -- Active Low DAC blanking control
16
VGA_SYNC         : out std_logic;                -- Active Low DAC Sync on Green
17
VGA_R, VGA_G, VGA_B   : out std_logic_vector(7 downto 0);
18
ledtest1, ledtest2, ledtest3           : out std_logic := '0'
19
);
20
21
end vga_control;
22
23
architecture rtl of vga_control is
24
25
-- Video parameters
26
27
constant HTOTAL           : integer := 800;
28
constant HSYNC           : integer := 96;
29
constant HBACK_PORCH       : integer := 48; 
30
constant HACTIVE           : integer := 640;
31
constant HFRONT_PORCH       : integer := 16;
32
constant VTOTAL           : integer := 525;
33
constant VSYNC           : integer := 2;
34
constant VBACK_PORCH       : integer := 33;
35
constant VACTIVE           : integer := 480;
36
constant VFRONT_PORCH       : integer := 10;
37
constant RECTANGLE_HSTART     : integer := 100;
38
constant RECTANGLE_HEND     : integer := 540;
39
constant RECTANGLE_VSTART     : integer := 100;
40
constant RECTANGLE_VEND     : integer := 380;
41
42
signal Hcount             : std_logic_vector(9 downto 0):= "0000000000"; -- Horizontal position (0 - 800)
43
signal Vcount             : std_logic_vector(9 downto 0):= "0000000000";  -- Vertical position (0 - 524)
44
signal EndOfLine, EndOfField   : std_logic :='0';
45
signal vga_hblank, vga_hsync,
46
vga_vblank, vga_vsync       : std_logic;                     -- Sync. signals
47
48
signal rectangle_h, rectangle_v, rectangle : std_logic;        -- rectangle area
49
50
begin
51
52
test : process (clk)
53
begin
54
55
  if taster= '1' then
56
    ledtest1<='0';
57
  else
58
    ledtest1<='1';
59
  end if;
60
61
end process test;
62
63
64
 
65
HCounter : process (clk)
66
begin
67
68
  if reset = '0' then
69
    Hcount <= (others=> '0');
70
    ledtest2<='1';
71
    elsif  (clk'event and clk = '1') then
72
     ledtest2<='0';
73
   if EndOfLine = '1' then
74
    Hcount <= (others=> '0');
75
  else
76
    Hcount <= Hcount + 1;
77
  
78
  end if; 
79
  end if;
80
81
end process;
82
83
84
VCounter: process (clk)
85
begin
86
87
  if reset = '0' then
88
    Vcount <= (others=> '0');
89
90
  elsif (clk'event and clk = '1') then
91
      if EndOfLine = '1' then
92
      if  EndOfField = '1' then
93
        Vcount <= (others=> '0');
94
      
95
      else
96
        Vcount <= Vcount + 1;
97
      end if;
98
      end if;
99
  end if;
100
end process VCounter;
101
102
103
 HSyncGen : process (clk)
104
begin
105
  if reset = '1' then
106
    vga_hsync <= '1';
107
  elsif clk'event and clk = '1' then
108
    if EndOfLine = '1' then
109
      vga_hsync <= '1';
110
    elsif Hcount = HSYNC - 1 then 
111
        vga_hsync <= '0';
112
      end if;
113
  end if;
114
end process HSyncGen;
115
116
HBlankGen : process (clk)
117
begin
118
119
  if reset='1' then 
120
  vga_hblank <= '1';
121
122
  elsif clk'event and clk='1' then
123
  
124
      if Hcount = HSYNC + HBACK_PORCH then
125
        vga_hblank <= '0';
126
      elsif Hcount = HSYNC + HBACK_PORCH + HACTIVE then
127
          vga_hblank <= '1';
128
      end if;
129
      
130
  end if;
131
end process HBlankGen;
132
133
134
135
VSyncGen : process (clk)
136
begin
137
138
  if reset='1' then
139
    vga_vsync <= '1';
140
  elsif clk'event and clk = '1' then
141
    if EndOfLine ='1' then
142
    if EndOfField = '1' then
143
      vga_vsync <= '1';
144
  elsif Vcount = VSYNC - 1 then
145
      vga_vsync <= '0';
146
    end if;
147
    end if;
148
  end if;
149
end process VSyncGen;
150
151
152
VBlankGen : process (clk)
153
begin
154
155
  if reset = '1' then
156
    vga_vblank <= '1';
157
  elsif clk'event and clk = '1' then
158
    if EndOfLine = '1' then
159
    if Vcount = VSYNC + VBACK_PORCH - 1 then
160
      vga_vblank <= '0';
161
    elsif Vcount = VSYNC + VBACK_PORCH + VACTIVE - 1 then
162
        vga_vblank <= '1';
163
    end if;
164
    end if;
165
  end if;
166
end process VBlankGen;
167
168
169
RectangleHGen : process (clk)
170
begin
171
172
  if reset = '1' then
173
    rectangle_h <= '1';
174
  elsif clk'event and clk = '1' then
175
    if Hcount = HSYNC + HBACK_PORCH + RECTANGLE_HSTART then
176
      rectangle_h <= '1';
177
    elsif Hcount = HSYNC + HBACK_PORCH + RECTANGLE_HEND then
178
        rectangle_h <= '0';
179
    end if;
180
  end if;
181
end process RectangleHGen;
182
183
184
RectangleVGen : process (clk)
185
begin
186
  if reset = '1' then
187
  rectangle_v <= '0';
188
  elsif clk'event and clk = '1' then
189
    if EndOfLine = '1' then
190
    if Vcount = VSYNC + VBACK_PORCH - 1 + RECTANGLE_VSTART then
191
      rectangle_v <= '1';
192
  elsif Vcount = VSYNC + VBACK_PORCH - 1 + RECTANGLE_VEND then
193
      rectangle_v <= '0';
194
195
    end if;
196
    end if;
197
  end if;
198
end process RectangleVGen;
199
200
rectangle <= rectangle_h and rectangle_v;
201
202
203
204
VideoOut: process (clk)
205
begin
206
  
207
  if reset = '1' then
208
    VGA_R <= "00000000";
209
    VGA_G <= "00000000";
210
    VGA_B <= "00000000";
211
  elsif clk'event and clk = '1' then
212
213
  if rectangle = '1' then
214
    VGA_R <= "11111111";
215
    VGA_G <= "11111111";
216
    VGA_B <= "11111111";
217
  elsif vga_hblank = '0' and vga_vblank ='0' then
218
      VGA_R <= "00000000";
219
      VGA_G <= "00000000";
220
      VGA_B <= "11111111";
221
  else
222
    VGA_R <= "00000000";
223
    VGA_G <= "00000000";
224
    VGA_B <= "00000000";
225
  end if;
226
  end if;
227
end process VideoOut;
228
229
230
vga_clk_gen : PROCESS(clk)--devides 50MHz clock in 2, making it a 25MHz clock
231
       VARIABLE count : INTEGER := 0;
232
    BEGIN
233
234
       IF rising_edge(clk) THEN
235
          IF count = 0 THEN
236
              VGA_CLK <= '1';   --1 period of 50MHz high
237
              count := 1;
238
          ELSIF count = 1 THEN
239
              VGA_CLK <= '0';    
240
              count := 0;
241
       END IF; 
242
     END IF;
243
    END PROCESS vga_clk_gen;
244
245
246
247
VGA_HS <= not vga_hsync;
248
VGA_VS <= not vga_vsync;
249
VGA_SYNC <='0';
250
VGA_BLANK <= not (vga_hsync or vga_vsync);
251
252
end rtl;

von Mike (Gast)


Lesenswert?

kurzes Update:

LEDs funktionieren nun. Ich weiß zwar nicht warum ;-(, aber es geht nun.
Nur funktioniert der Code nicht, war auch ein Rätsel für mich ist...

Vielleicht kann mir jemand in dem Punkt weiter helfen...

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


Lesenswert?

Mike schrieb:
> Nur funktioniert der Code nicht, war auch ein Rätsel für mich ist...
WAS funktioniert nicht?
WIE hast du das festgestellt?
WO ist die Testbench?


Am Rande:
Entweder die
  use ieee.std_logic_arith.all;
  use ieee.std_logic_unsigned.all;
oder die
  use ieee.numeric_std.all;
aber NIEMALS beide zusammen!


Und dann noch der Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"


Flasche Sensitivliste:
1
test : process (clk)    -- clk wird nicht gebraucht
2
begin
3
  if taster= '1' then   -- taster fehlt in der sensitivliste
4
    ledtest1<='0';
5
  else
6
    ledtest1<='1';
7
  end if;
8
end process test;


Unvollständige Sensitivlisten:
1
HCounter : process (clk)
2
begin
3
  if reset = '0' then               -- reset fehlt in der Sensitivliste!
4
    Hcount <= (others=> '0');
5
    ledtest2<='1';
6
  elsif  (clk'event and clk = '1') then
7
    ...
8
9
VCounter: process (clk)
10
begin
11
  if reset = '0' then                -- reset fehlt in der Sensitivliste!
12
    Vcount <= (others=> '0');
13
  elsif (clk'event and clk = '1') then
14
    ...


Warum brauchst du bei sowas wie einem VGA-Interface, wo sich immer 
wieder alles wiederholt, überhaupt einen Reset?

von Ralf R. (rrascher)


Lesenswert?

Abgesehen von Lothars Bemerkungen.
Dein Timing laeuft intern mit 50 MHz.
Du gibt aber einen VGA Clock von 25 MHz aus.
Irgendwas passt da nicht zusammen...

Ralf

von Takter (Gast)


Lesenswert?

Nimm einen VGA-scheme mit 50MHz - eh besser.

von Mike (Gast)


Lesenswert?

@lothar

Sorry für meine doch sehr grobe Fehlerbeschreibung. Also der Bildschirm 
bekommt kein Signal, das ist mein Hauptproblem.

Ich hab mich nun durch verschiedene VHDL-Code-Versionen für die 
Ansteuerung eines VGA-Signals durchgearbeiten und habe dabei bei der 
Signalübertragung verschiedene Versionen gesehen.

In meinem Code wird zu allererst vor der Übertragung der 
Farbeinformationen das HSync und HBack_Porch "gesetzt" bevor dann die 
Farbinformation übertragen wird.

Beispiel_V1:
h_Sync(96)-->h_back_porch(48)-->Farbübertragung(640)...

In einer anderen Version aus dem Netz wurde sofort die 
RGB-Farbinformation übertragen und dann mit dem Counter soweit bis zur 
Ende des aktiven Pixelbereichs hochgezählt und dann erst die 
Synchronisation realisiert.
In diesem Fall hat wenigstens der LCD ein "Out of Range" rausgegeben. 
Immerhin kam was an, daher vermute ich, dass diese Version richtig 
ist...

Beispiel_V2:
Farbübertragung(640)-->HFront_Porch(16)-->h_Sync(96)-->h_back_porch(48). 
..


Wenn mir das jemand mitteilen könnte, würde das wohl mein 
(Verständis-)Problem lösen...

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


Lesenswert?

Diese Timings sind erstmal ziemlich unwichtig. Schlimmstenfalls ist dein 
Bild auf dem Schirm leicht verschoben...

Mike schrieb:
> der Bildschirm bekommt kein Signal, das ist mein Hauptproblem.
Und was sagt die Simulation?
Gerade ein VGA-Interface lässt sich bildhübsch simulieren...

Mein (uralter) Code dafür sieht so aus:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity VGA is
6
    Port ( CLK       : in std_logic;
7
           Line      : out integer range 0 to 480;
8
           Column    : out integer range 0 to 640;
9
           RedIn     : in  std_logic;
10
           GreenIn   : in  std_logic;
11
           BlueIn    : in  std_logic;
12
           Hsync     : out std_logic;
13
           Vsync     : out std_logic;
14
           RedOut    : out std_logic;
15
           GreenOut  : out std_logic;
16
           BlueOut   : out std_logic);
17
end VGA;
18
19
architecture Behavioral of VGA is
20
signal pixelclk   : std_logic := '0';
21
signal inScreen   : std_logic := '0';
22
signal dispHorizontal  : std_logic := '0';
23
signal dispVertical    : std_logic := '0';
24
signal syncH      : std_logic := '1';
25
signal syncV      : std_logic := '1';
26
signal aktHorizontal : integer range 0 to 800; -- horizontal counter: 800 * 40ns = 320us -> 31,25kHz
27
signal aktVertical   : integer range 0 to 521; -- vertical counter: 521 * 320us = 320us -> 31,25kHz
28
signal aktLine    :  integer range 0 to 480;
29
signal aktColumn  :  integer range 0 to 640;
30
31
begin
32
   process begin
33
      wait until (rising_edge(CLK)); -- 50MHz
34
      pixelclk <= not pixelclk;      -- 25MHz = 40ns
35
      if(pixelclk='1') then
36
         aktHorizontal <= aktHorizontal+1;
37
         if (aktHorizontal = 799) then
38
            aktHorizontal <= 0;
39
            aktVertical <= aktVertical+1;
40
            if (aktVertical = 520) then
41
               aktVertical <= 0;
42
            end if;
43
         end if;
44
      end if;
45
46
      if    (aktHorizontal=0)  then syncH <= '0';
47
      elsif (aktHorizontal=96) then syncH <= '1';
48
      else                          syncH <= syncH;
49
      end if;
50
51
      if    (aktVertical=0)    then syncV <= '0';
52
      elsif (aktVertical=2)    then syncV <= '1';
53
      else                          syncV <= syncV;
54
      end if;
55
56
      if    (aktHorizontal=0)  then dispHorizontal <= '0';
57
      elsif (aktHorizontal=144)then dispHorizontal <= '1';
58
      elsif (aktHorizontal=784)then dispHorizontal <= '0';
59
      else                          dispHorizontal <= dispHorizontal;
60
      end if;
61
62
      if    (aktVertical=0)    then dispVertical <= '0';
63
      elsif (aktVertical=31)   then dispVertical <= '1';
64
      elsif (aktVertical=511)  then dispVertical <= '0';
65
      else                          dispVertical <= dispVertical;
66
      end if;
67
   end process;
68
   
69
   inScreen  <= dispVertical and dispHorizontal;
70
71
   aktColumn <= aktHorizontal-144 when dispHorizontal='1' else 0;
72
   aktLine   <= aktVertical-31    when dispVertical='1' else 0;
73
   Line      <= aktLine;
74
   Column    <= aktColumn;
75
76
   RedOut    <= RedIn   when inScreen='1' else '0';
77
   GreenOut  <= GreenIn when inScreen='1' else '0';
78
   BlueOut   <= BlueIn  when inScreen='1' else '0';
79
   Hsync     <= syncH;
80
   Vsync     <= syncV;
81
82
end Behavioral;

von Mike (Gast)


Lesenswert?

@lothar

Ich danke dir für den Code, werde ihn (wenn alle Stricke reissen) auch 
einmal ausprobieren.

Habe den Code nun soweit umgeschrieben, dass in der Simulation 
eigentlich alles passen solle. Leider gibt der LCD-M. immer noch kein 
Signal aus.

Daher 2 konkrete Fragen:

1. Ich habe in meinem Code angenommen, dass das blank-Signal low-active 
ist. Ist das richtig?

2. Ich arbeite mit 25 Mhz. In meiner Simulation dauert die horizontale 
Synchronisation 3,88 us. Als Standart ist aber 3,813 us definiert, da 
die clk mit  25.175 Mhz arbeitet. Könnte das ein Problem sein?

Liebe Grüße

Mike

von Rene B. (themason) Benutzerseite


Lesenswert?

@Mike

Wenn in der Simulation alles soweit passt und gut aussieht, und es dann 
immer noch nicht funzt kannst du nur mit einem Scope gucken ob die 
Signale auch so ankommen.
Wenn VSync und HSync erstmal passen und die RGB Infos nur während der 
Display-Active-Time "zappeln" dann passts bzw sollte was zu sehen sein.
Aber ich kann mich nur Lothar anschließen : Ein VGA-Signal zu simulieren 
bzw erzeugen ist (bei normalem Std-VGA) kein Problem.


zu 2) :
25MHz statt 25.1irgendwas MHz sind kein Problem. Man kann den HSync ja 
ein/zwei Impulse kürzer machen. Aber i.d.r sollte kein Monitor ein 
Problem damit haben. Ich hab damals auch mit 25MHz gearbeitet, kein 
Thema, lief auf anhieb.

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


Lesenswert?

Mike schrieb:
> 2. Ich arbeite mit 25 Mhz. In meiner Simulation dauert die horizontale
> Synchronisation 3,88 us. Als Standart ist aber 3,813 us definiert, da
> die clk mit  25.175 Mhz arbeitet. Könnte das ein Problem sein?
Nein. Aktuelle Monitore können sich auch bei sehr großen Abweichungen 
noch synchronisieren...

> Ich danke dir für den Code, werde ihn (wenn alle Stricke reissen) auch
> einmal ausprobieren.
Aber du kannst ihn vorher schon einfach mal anschauen, der lief bei mir 
als VGA Timingenerator für das legendäre Pong... ;-)

von Mike (Gast)


Lesenswert?

unglaublich, es läuft nun...;-) Ich danke Lothar, Ralf, Takter und Rene 
B. für die hilfreichen Kommentare.

@lothar: werde ich machen. Nur weil es läuft, heißt es ja nicht, das der 
Code so in dem Zustand stabil ist. ;-)

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


Lesenswert?

Mike schrieb:
> unglaublich, es läuft nun...
Und: was war letztlich das Problem?

von Mike (Gast)


Lesenswert?

Durch die Simulation bemerkte ich einige Fehler im Code z.B. dass das 
RGB-Signal immer noch online war, während ich die Synchronisation 
durchführte und nicht über das blank-Signal ausgeschaltet wurde...

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.