VGA-Treiber in VHDL zeigt nur schwarz an

Ziel & Daten Ich versuche, einen VGA-Treiber auf einem Spartan 6 (Embedded Micro Mojo Board) zu erstellen, um etwas Einfaches wie die französische Flagge auf einem LCD-Monitor in 640x480 8 Farben anzuzeigen. Ich lebe in Europa und der Monitor ist 16:10, wenn es wichtig ist.

Verkabelung Ich habe hsync&vsync nach diesem Diagramm mit meinem Monitor verkabelt und die RG- und B-Signale zunächst mit einer 0,7-V-Stromversorgung verbunden. Ich gehe davon aus, dass die Spannung das Maximum ist (viele Leute sagen zumindest, dass es weiß ist).

Symptome Beim Starten des folgenden Codes wird ein schwarzer Bildschirm angezeigt. Es erscheint keine Meldung „Außerhalb des Bereichs [31kHz 40Hz]“ (wie bei einem Timing-Fehler), und wenn ich einen schlechten Kontakt mit den 0,7 V an einem beliebigen Farbstift herstelle (was bedeutet, dass ich ein bisschen zittere), erscheinen zufällige Streifen die entsprechende Farbe erscheint ganz kurz - bei gutem Kontakt wird der Bildschirm wieder pechschwarz.

Frage Ich glaube, ich habe eine Idee, warum es nicht funktioniert, meiner Meinung nach ist es die Tatsache, dass die Farben am Ende der Periode nie wieder auf Schwarz umgestellt werden, wie es das Protokoll vorschlägt. Wenn ich Recht habe (wenn nicht, warum dann?), warum ist das notwendig, um ein Bild zu bilden? So wie ich das sehe, geht es nur darum, die Farben zum richtigen Zeitpunkt aufzutragen und die vertikale/horizontale Plattenrampe zum richtigen Zeitpunkt zurückzusetzen ...

Code

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;

entity main is
    Port ( 
              clk : in  STD_LOGIC;
           hsync : out  STD_LOGIC;
           vsync : out  STD_LOGIC;
           r : out  STD_LOGIC_VECTOR (2 downto 0) := "000";
           g : out  STD_LOGIC_VECTOR (2 downto 0) := "000";
           b : out  STD_LOGIC_VECTOR (1 downto 0) := "000"
            );
end main;

architecture Behavioral of main is
    signal hcounter : integer := 0;
    signal vcounter : integer := 0;
    signal tick : STD_LOGIC := '0';
begin

    clk_process : process(clk)
    begin
        if(rising_edge(clk)) then
            tick <= not tick;
            if(tick = '1') then         -- Happens at 25MHz (50MHz / 2)

                -- Reset the counter if column/line finished or increment it
                if(hcounter = 799) then
                    hcounter <= 0;
                    if vcounter = 524 then
                        vcounter <= 0;
                    else
                        vcounter <= vcounter + 1;
                    end if;
                else
                    hcounter <= hcounter + 1;
                end if;

                -- Send a pulse of vsync to start a new column
                if vcounter >= 490 and vcounter < 492 then
                    vsync <= '0';
                else
                    vsync <= '1';
                end if;

                -- Send a pulse of hsync to start a new line
                if hcounter >= 656 and hcounter < 752 then
                    hsync <= '0';
                else
                    hsync <= '1';
                end if;

                -- If pixel time, draw something
                if hcounter < 640 and vcounter < 480 then
                    --display a colour on the RGB signals once I have opamps to get them through
                    --if hcounter < 213 then
                        -- Blue line
                        --b <= "111";
                        --r <= "000";
                        --g <= "000";
                    --elsif hcounter < 426 then
                       -- White line
                        --r <= "111";
                        --g <= "111";
                        --b <= "111";
                    --else
                        -- Red line
                        -- r <= "111";
                        -- g <= "000";
                        -- b <= "000";
                    --end if;
                else
                    --display black colour on the RGB signals
                    -- b <= "000";
                    -- r <= "000";
                    -- g <= "000";
                end if;
            end if;
        end if;
    end process;

end Behavioral;

Was ich verstehe

Und könnte falsch sein, siehe folgendes Bild. Ausgehend davon ist das Seitenverhältnis und die vertikale Bildwiederholfrequenz bei voller Auflösung jetzt nicht wichtig (da bei einem kleineren Bild die Bildwiederholfrequenz höher ist) ?Geben Sie hier die Bildbeschreibung ein

Es gibt 3 PLLs in LCD-Monitoren/TVs. V, H und Pixelrand min. Intervall. Es mag Dutzende von akzeptablen Verhältnissen geben, aber Ihre Raten lagen außerhalb des Bereichs. Wenn die Pixelrate 25 MHz und H 31k ist, also P/H=806 (800 tatsächlich), dann erwartet es eine V-Rate von 525 H-Takten +\-10%, aber das war es nicht. H/V war 775
Sie sagen mir also, dass der gesamte Monitorbereich gescannt werden muss, sonst weist der Monitor das Signal zurück? Wenn ich also die gleichen hinteren/vorderen Veranden behalte und meinen Vcounter auf 775 zurücksetze, wird es funktionieren (sorry, ich kann es jetzt nicht versuchen ...)? Warum zeigt mein Monitor in diesem Fall nicht "Außerhalb des Bereichs" an, wie es bei einem anderen Fehler der Fall war? Oder warum werden die Farben irgendwie angezeigt, wenn die Verbindung über RGB-Leitungen nicht stabil ist?
Manchmal verwenden Displays die Signalpegel außerhalb des Bildschirms, um den „Schwarzpegel“ einzustellen. Wenn der „Schwarzwert“ der Farbe entspricht, die Sie anzeigen möchten, erhalten Sie nur Schwarz. Nun, ich habe keine Ahnung, ob dieses spezielle Display den Schwarzwert so einstellt oder nicht, aber ich würde empfehlen, das Protokoll genau zu befolgen.
LCD-Fernseher können wie PC-Monitore mit einer Vielzahl von Modi umgehen, ideal ist der native Modus mit der gleichen Anzahl von Pixeln im gleichen Seitenverhältnis. Aber auch ältere Legacy-Tarife und höhere Tarife akzeptieren die analogen Eingänge. Der Videopegel nach der Synchronisation wird für die Schwarzpegel-Klemmung verwendet, die als hintere Schwarzschulter bezeichnet wird. Es gibt keine feste Regel, aber 800 x 600 ist universell, in vielen Fällen gilt dies auch für 640 x 480, aber diese sehr niedrige Auflösung von 307,2 k Pixel für einen HDTV, der 1920 x 1080 = 2,07 Mpix unterstützt, sei es 1080p oder 1080i, daher gibt es keine Regel, dass alle Fernseher VGA unterstützen müssen .
Darf ich fragen, warum Sie alle Teile des Codes kommentiert haben, die den Pixelwert ändern? Da Sie keinen Treiber für R-, G- und B-Signale haben, sind sie optimiert und werden vom P&R-Tool auf ihre Standardwerte gesetzt, und das erklärt, warum Sie auf Ihrem Bildschirm schwarz erscheinen.
Außerdem stelle ich fest, dass das blaue Signal (b) nur zwei Bit breit ist, sodass Ihre Zuweisungen an b entsprechend angepasst werden sollten.
@FarhadA: Ich habe diese kommentiert, da ich noch nicht die richtigen Widerstandswerte habe, um einen richtigen DAC herzustellen, also habe ich alle RGB-Eingänge auf maximale Leuchtdichte (0,7 V) geklemmt. Wenn die hintere Veranda tatsächlich zum Registrieren von Schwarz verwendet wird, würde das erklären, warum ich nur Schwarz bekomme ... Aber da ich davon ausgehe, dass der interne ADC mindestens 8 Bit haben muss, hatte ich ein bisschen Rauschen erwartet, um es zu beweisen.
Ich verstehe nicht, was Sie hier sagen.

Antworten (2)

Die Pixeltaktrate muss angepasst werden, um Vsync-Raten und Hsync-Raten zu erreichen, die für Ihren Multisync-Monitor akzeptabel sind.

Da 40 Hz keine übliche Vsync-Rate ist, versuchen Sie es mit 30, 50 oder 60 oder höher.

640 * 480 * 40 Hz = 12,3 MHz, so dass es scheint, als würden Pixel mit der halben Taktrate von 25 MHz ausgegeben

Das NTSC-Timing für V Sync, Front Porch (480~494), Hsync, Back Porch (495~525) wie folgt unter Verwendung von 25 MHz Geben Sie hier die Bildbeschreibung einHsync kann so lange mit vorher nachher Perioden variiert werden, solange die Summe gleich ist. Einige Monitore haben je nach Design eine Toleranz von 10 %.

Danke für deine Antwort. Dieser Code ist bereits so eingerichtet, dass er einen Pixeltakt von 25 MHz und eine vertikale Synchronisierungsrate von 60 Hz bereitstellt, was eine horizontale Synchronisierungsrate von 31,5 kHz ergibt. Ich war überrascht, 40 Hz auf diesem Bildschirm zu sehen, aber ich nehme an, dass es etwas mit dem Seitenverhältnis zu tun hat (der Monitor hat nicht 4:3, sondern 16:10). Das resultierende Bild sollte kleiner als die verfügbaren Immobilien sein, aber trotzdem angezeigt werden, oder?
Die Sync-Raten sind nicht wie erwartet, ändern Sie den TV-Modus auf 4x3 oder dehnen Sie. Überprüfen Sie die Sync-Frequenz. Es scheint, dass die Pixelrate nur 12,3 MHz beträgt. Das H / V-Verhältnis beträgt jedoch nicht 640, wie viele Pixel für H-Sync und V-Sync zugewiesen sind
Überprüfen Sie die Pixelrate mit dem Oszilloskop. Hier stimmt etwas nicht
Danke für das Diagramm, sie sagen immer mehr als tausend Worte. Aus diesem Grund habe ich ein Diagramm hochgeladen, das zeigt, was ich verstehe, weil ich immer noch nicht weiß, warum die 40 Hz und das Seitenverhältnis ein Problem sind. Ich werde es am Dienstag mit 4/3 versuchen, ich habe das Rig nicht zur Hand (nur das Brett). Ich habe das Design jedoch mit ISim simuliert und alle Signale sind korrekt (25-MHz-Takt und alle Timings gemäß den Spezifikationen).

@alex.forencich hat in den Kommentaren die richtige Antwort gegeben: Die schwarze Farbe wird außerhalb des sichtbaren Bereichs registriert, und da ich für meinen Testaufbau jeden analogen Eingang auf maximale Leuchtdichte (0,7 V) verdrahtet hatte, wurde das Schwarz als dasselbe Signal registriert die im aktiven Bereich gesendet wurde => schwarz. Ich habe die Eingangsimpedanz des Monitors gemessen (anscheinend sind diese 100 Ohm Standard) und an den R (0 bis 2) G (0 bis 2) B (0 bis 2), um die entsprechende Spannung zu erhalten. Ohne etwas an den Zählern zu ändern, habe ich es geschafft, meine französische Flagge zu drucken. Danke, wenn Sie eine Antwort posten, werde ich sie akzeptieren.