www.mikrocontroller.net

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


Important 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.
Autor: Mike (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity vga_control is
port (
reset, taster           : in std_logic;
clk                     : in std_logic; 

VGA_CLK,                                    -- Should be 25.125 MHz VGA_CLK,  Dot clock to DAC
VGA_HS,                                     -- Active Low Horizontal Sync
VGA_VS,                                     -- Active Low Vertical Sync
VGA_BLANK,                                   -- Active Low DAC blanking control
VGA_SYNC         : out std_logic;                -- Active Low DAC Sync on Green
VGA_R, VGA_G, VGA_B   : out std_logic_vector(7 downto 0);
ledtest1, ledtest2, ledtest3           : out std_logic := '0'
);

end vga_control;

architecture rtl of vga_control is

-- Video parameters

constant HTOTAL           : integer := 800;
constant HSYNC           : integer := 96;
constant HBACK_PORCH       : integer := 48; 
constant HACTIVE           : integer := 640;
constant HFRONT_PORCH       : integer := 16;
constant VTOTAL           : integer := 525;
constant VSYNC           : integer := 2;
constant VBACK_PORCH       : integer := 33;
constant VACTIVE           : integer := 480;
constant VFRONT_PORCH       : integer := 10;
constant RECTANGLE_HSTART     : integer := 100;
constant RECTANGLE_HEND     : integer := 540;
constant RECTANGLE_VSTART     : integer := 100;
constant RECTANGLE_VEND     : integer := 380;

signal Hcount             : std_logic_vector(9 downto 0):= "0000000000"; -- Horizontal position (0 - 800)
signal Vcount             : std_logic_vector(9 downto 0):= "0000000000";  -- Vertical position (0 - 524)
signal EndOfLine, EndOfField   : std_logic :='0';
signal vga_hblank, vga_hsync,
vga_vblank, vga_vsync       : std_logic;                     -- Sync. signals

signal rectangle_h, rectangle_v, rectangle : std_logic;        -- rectangle area

begin

test : process (clk)
begin

  if taster= '1' then
    ledtest1<='0';
  else
    ledtest1<='1';
  end if;

end process test;


 
HCounter : process (clk)
begin

  if reset = '0' then
    Hcount <= (others=> '0');
    ledtest2<='1';
    elsif  (clk'event and clk = '1') then
     ledtest2<='0';
   if EndOfLine = '1' then
    Hcount <= (others=> '0');
  else
    Hcount <= Hcount + 1;
  
  end if; 
  end if;

end process;


VCounter: process (clk)
begin

  if reset = '0' then
    Vcount <= (others=> '0');

  elsif (clk'event and clk = '1') then
      if EndOfLine = '1' then
      if  EndOfField = '1' then
        Vcount <= (others=> '0');
      
      else
        Vcount <= Vcount + 1;
      end if;
      end if;
  end if;
end process VCounter;


 HSyncGen : process (clk)
begin
  if reset = '1' then
    vga_hsync <= '1';
  elsif clk'event and clk = '1' then
    if EndOfLine = '1' then
      vga_hsync <= '1';
    elsif Hcount = HSYNC - 1 then 
        vga_hsync <= '0';
      end if;
  end if;
end process HSyncGen;

HBlankGen : process (clk)
begin

  if reset='1' then 
  vga_hblank <= '1';

  elsif clk'event and clk='1' then
  
      if Hcount = HSYNC + HBACK_PORCH then
        vga_hblank <= '0';
      elsif Hcount = HSYNC + HBACK_PORCH + HACTIVE then
          vga_hblank <= '1';
      end if;
      
  end if;
end process HBlankGen;



VSyncGen : process (clk)
begin

  if reset='1' then
    vga_vsync <= '1';
  elsif clk'event and clk = '1' then
    if EndOfLine ='1' then
    if EndOfField = '1' then
      vga_vsync <= '1';
  elsif Vcount = VSYNC - 1 then
      vga_vsync <= '0';
    end if;
    end if;
  end if;
end process VSyncGen;


VBlankGen : process (clk)
begin

  if reset = '1' then
    vga_vblank <= '1';
  elsif clk'event and clk = '1' then
    if EndOfLine = '1' then
    if Vcount = VSYNC + VBACK_PORCH - 1 then
      vga_vblank <= '0';
    elsif Vcount = VSYNC + VBACK_PORCH + VACTIVE - 1 then
        vga_vblank <= '1';
    end if;
    end if;
  end if;
end process VBlankGen;


RectangleHGen : process (clk)
begin

  if reset = '1' then
    rectangle_h <= '1';
  elsif clk'event and clk = '1' then
    if Hcount = HSYNC + HBACK_PORCH + RECTANGLE_HSTART then
      rectangle_h <= '1';
    elsif Hcount = HSYNC + HBACK_PORCH + RECTANGLE_HEND then
        rectangle_h <= '0';
    end if;
  end if;
end process RectangleHGen;


RectangleVGen : process (clk)
begin
  if reset = '1' then
  rectangle_v <= '0';
  elsif clk'event and clk = '1' then
    if EndOfLine = '1' then
    if Vcount = VSYNC + VBACK_PORCH - 1 + RECTANGLE_VSTART then
      rectangle_v <= '1';
  elsif Vcount = VSYNC + VBACK_PORCH - 1 + RECTANGLE_VEND then
      rectangle_v <= '0';

    end if;
    end if;
  end if;
end process RectangleVGen;

rectangle <= rectangle_h and rectangle_v;



VideoOut: process (clk)
begin
  
  if reset = '1' then
    VGA_R <= "00000000";
    VGA_G <= "00000000";
    VGA_B <= "00000000";
  elsif clk'event and clk = '1' then

  if rectangle = '1' then
    VGA_R <= "11111111";
    VGA_G <= "11111111";
    VGA_B <= "11111111";
  elsif vga_hblank = '0' and vga_vblank ='0' then
      VGA_R <= "00000000";
      VGA_G <= "00000000";
      VGA_B <= "11111111";
  else
    VGA_R <= "00000000";
    VGA_G <= "00000000";
    VGA_B <= "00000000";
  end if;
  end if;
end process VideoOut;


vga_clk_gen : PROCESS(clk)--devides 50MHz clock in 2, making it a 25MHz clock
       VARIABLE count : INTEGER := 0;
    BEGIN

       IF rising_edge(clk) THEN
          IF count = 0 THEN
              VGA_CLK <= '1';   --1 period of 50MHz high
              count := 1;
          ELSIF count = 1 THEN
              VGA_CLK <= '0';    
              count := 0;
       END IF; 
     END IF;
    END PROCESS vga_clk_gen;



VGA_HS <= not vga_hsync;
VGA_VS <= not vga_vsync;
VGA_SYNC <='0';
VGA_BLANK <= not (vga_hsync or vga_vsync);

end rtl;



Autor: Mike (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite Flattr this
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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:
test : process (clk)    -- clk wird nicht gebraucht
begin
  if taster= '1' then   -- taster fehlt in der sensitivliste
    ledtest1<='0';
  else
    ledtest1<='1';
  end if;
end process test;


Unvollständige Sensitivlisten:
HCounter : process (clk)
begin
  if reset = '0' then               -- reset fehlt in der Sensitivliste!
    Hcount <= (others=> '0');
    ledtest2<='1';
  elsif  (clk'event and clk = '1') then
    ...

VCounter: process (clk)
begin
  if reset = '0' then                -- reset fehlt in der Sensitivliste!
    Vcount <= (others=> '0');
  elsif (clk'event and clk = '1') then
    ...


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

Autor: Ralf R. (rrascher)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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

Autor: Takter (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Nimm einen VGA-scheme mit 50MHz - eh besser.

Autor: Mike (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite Flattr this
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity VGA is
    Port ( CLK       : in std_logic;
           Line      : out integer range 0 to 480;
           Column    : out integer range 0 to 640;
           RedIn     : in  std_logic;
           GreenIn   : in  std_logic;
           BlueIn    : in  std_logic;
           Hsync     : out std_logic;
           Vsync     : out std_logic;
           RedOut    : out std_logic;
           GreenOut  : out std_logic;
           BlueOut   : out std_logic);
end VGA;

architecture Behavioral of VGA is
signal pixelclk   : std_logic := '0';
signal inScreen   : std_logic := '0';
signal dispHorizontal  : std_logic := '0';
signal dispVertical    : std_logic := '0';
signal syncH      : std_logic := '1';
signal syncV      : std_logic := '1';
signal aktHorizontal : integer range 0 to 800; -- horizontal counter: 800 * 40ns = 320us -> 31,25kHz
signal aktVertical   : integer range 0 to 521; -- vertical counter: 521 * 320us = 320us -> 31,25kHz
signal aktLine    :  integer range 0 to 480;
signal aktColumn  :  integer range 0 to 640;

begin
   process begin
      wait until (rising_edge(CLK)); -- 50MHz
      pixelclk <= not pixelclk;      -- 25MHz = 40ns
      if(pixelclk='1') then
         aktHorizontal <= aktHorizontal+1;
         if (aktHorizontal = 799) then
            aktHorizontal <= 0;
            aktVertical <= aktVertical+1;
            if (aktVertical = 520) then
               aktVertical <= 0;
            end if;
         end if;
      end if;

      if    (aktHorizontal=0)  then syncH <= '0';
      elsif (aktHorizontal=96) then syncH <= '1';
      else                          syncH <= syncH;
      end if;

      if    (aktVertical=0)    then syncV <= '0';
      elsif (aktVertical=2)    then syncV <= '1';
      else                          syncV <= syncV;
      end if;

      if    (aktHorizontal=0)  then dispHorizontal <= '0';
      elsif (aktHorizontal=144)then dispHorizontal <= '1';
      elsif (aktHorizontal=784)then dispHorizontal <= '0';
      else                          dispHorizontal <= dispHorizontal;
      end if;

      if    (aktVertical=0)    then dispVertical <= '0';
      elsif (aktVertical=31)   then dispVertical <= '1';
      elsif (aktVertical=511)  then dispVertical <= '0';
      else                          dispVertical <= dispVertical;
      end if;
   end process;
   
   inScreen  <= dispVertical and dispHorizontal;

   aktColumn <= aktHorizontal-144 when dispHorizontal='1' else 0;
   aktLine   <= aktVertical-31    when dispVertical='1' else 0;
   Line      <= aktLine;
   Column    <= aktColumn;

   RedOut    <= RedIn   when inScreen='1' else '0';
   GreenOut  <= GreenIn when inScreen='1' else '0';
   BlueOut   <= BlueIn  when inScreen='1' else '0';
   Hsync     <= syncH;
   Vsync     <= syncV;

end Behavioral;

Autor: Mike (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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

Autor: Rene B. (themason) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite Flattr this
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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... ;-)

Autor: Mike (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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. ;-)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite Flattr this
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Mike schrieb:
> unglaublich, es läuft nun...
Und: was war letztlich das Problem?

Autor: Mike (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht 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...

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




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 erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net