Einfarbige Anzeige auf VGA funktioniert nicht

Ich versuche, VGA mit Verilog auf meinem Altera DE0-Board zum Laufen zu bringen, hatte aber nicht viel Glück. Es hat die gleichen Pins wie eine normale VGA-Schnittstelle, außer dass Rot, Grün und Blau jeweils 4 Bit sind. Hier ist die Logik, die ich zu verwenden versucht habe, um eine Volltonfarbe anzuzeigen:

module solid_color (clk, vga_h_sync, vga_v_sync, R, G, B);

input clk;
output vga_h_sync;
output vga_v_sync;
output [3:0] R;
output [3:0] G;
output [3:0] B;

reg [9:0] CounterX;
reg [8:0] CounterY;
wire CounterXmaxed = (CounterX==767);

always @(posedge clk)
if(CounterXmaxed)
  CounterX <= 0;
else
  CounterX <= CounterX + 1;

always @(posedge clk)
if(CounterXmaxed)
    CounterY <= CounterY + 1;

reg vga_HS, vga_VS;
always @(posedge clk)
begin
  vga_HS <= (CounterX[9:4]==0);   // active for 16 clocks
  vga_VS <= (CounterY==0);   // active for 768 clocks
end

assign vga_h_sync = ~vga_HS;
assign vga_v_sync = ~vga_VS;

assign R = 15;
assign G = 15;
assign B = 15;

endmodule

Wenn ich versuche, es auszuführen, erhalte ich nur eine Meldung auf dem Monitor, die besagt, dass dieser Anzeigemodus nicht unterstützt wird.

Dies ist angepasst von http://www.fpga4fun.com/PongGame.html . Diese Version behauptet jedoch, für 640 x 480-Displays ausgelegt zu sein, während mein Monitor 1280 x 1024 ist. Ist das das Problem? Wenn ja, wie würde ich dies an die erhöhte Monitorgröße anpassen? (die Uhr, die ich verwende, ist 50 MHz)

BEARBEITEN: Ich habe ein Taktteilermodul wie folgt hinzugefügt, um das anfängliche Taktsignal auf 25 MHz zu ändern:

module divide_clock_by_two(in_clk, out_clk);

input in_clk;
output out_clk;
reg out_clk;

always @(posedge in_clk)
out_clk <= ~out_clk;

endmodule

Allerdings zeigt der Monitor jetzt nur noch einen schwarzen Bildschirm, keine Meldung über einen falschen Modus.

Auf dieser Seite steht "Using a 25MHz clock", also müssen Sie den Takt halbieren oder alle Ihre Timings verdoppeln.
Der clk-Eingang zu diesem Modul ist ein "Pixel"-Takt, kein Systemtakt. Sie müssen den richtigen Frequenztakt für die von Ihnen verwendete Auflösung bereitstellen.
Ich habe versucht, CounterX==767auf CounterX==1535und CounterX[9:4]zu zu wechseln CounterX[9:5], um die Timings zu verdoppeln, aber das hat nicht funktioniert.
Majenko, würde das bedeuten, die Timings zu ändern oder den Eingangstakt selbst zu ändern? Laut dieser Seite mit Pixeltakt-Timings: tinyvga.com/vga-timing bräuchte ich mindestens einen 108-MHz-Takt, um mein Display anzusteuern, aber das kann nicht korrekt sein, da ich gesehen habe, dass die Platine das Display antreibt nur sein 50-MHz-Takt in Demos.
Ich weiß nicht, was Sie lesen, aber ich sehe: "VGA 640x480@60 Hz Industriestandard (Pixeltakt 25,175 MHz)" - das ist die Taktgeschwindigkeit, die Sie an clk übergeben sollten - oder so ungefähr (die meisten Monitore erlauben a etwas Spielraum).
Ich lese den Abschnitt unter 1280 x 1024, das ist der Monitor, den ich habe.
Das ist die native Auflösung Ihres Monitors und nicht die einzige Auflösung, mit der Sie ihn ausführen können. Es unterstützt viele, viele Auflösungen unterhalb dieser Auflösung, z. B. wenn Sie Ihren Computer zum ersten Mal einschalten und er im Modus 640 x 400 (oder ähnlich) läuft. Wenn Sie mit einer höheren Auflösung laufen möchten (was Sie nicht brauchen), müssen Sie große Änderungen an Ihrem Timing vornehmen.
Ich habe gerade einen Taktteiler hinzugefügt, siehe die Bearbeitung für Details.
Ich nehme an, Sie haben keinen Bereich, um zu überprüfen, wie Ihre Synchronisierung aussieht?

Antworten (1)

Die meisten VGA-Monitore „kalibrieren den DC-Offset heraus“, wenn Sie die RGB-Signale außerhalb des sichtbaren Bereichs treiben.

Obwohl dies möglicherweise nicht Ihr einziges oder sogar schwerwiegendstes Problem ist, scheint dies ein Problem in Ihrer Implementierung zu sein (Sie steuern Konstanten). Versuchen Sie also, Logik hinzuzufügen, um Ihre Farbsignale auf Schwarz zu treiben, wenn sie sich außerhalb des beabsichtigten Anzeigerechtecks ​​befinden.

Ich wollte gerade anmerken, dass RG und B während aller Austastperioden "aus" sein müssen, dh auf schwarz eingestellt sein müssen. Dann habe ich deine Antwort gelesen :P
Das war das Problem. Ich habe die Zuordnungen von R, G und B geändert und jetzt habe ich ein Muster. Auch Majenko sei der 25-MHz-Takt zu verdanken, da dieser auch nötig war.
Wie würde ich dies jedoch für eine konstante Farbanzeige ändern? Mit anderen Worten, wie würde ich mit diesen Zählern anhand der Taktsignale erkennen, dass ich das Ansteuern von RGB-Signalen stoppen soll?
Verwenden Sie Logik für jeden Zählwert, um zu bestimmen, wann sich diese Achse innerhalb des Anzeigebereichs befindet.
Aber wie bestimme ich, was der Anzeigebereich ist? Ich hatte den Eindruck, dass die x- und y-Zähler dies bereits erledigt haben, indem sie zurückgeschleift wurden, wenn sie den Maximalwert erreichten.
Sie sollten sich ein Zeitdiagramm der tatsächlichen Videosignale ansehen, aber kurz gesagt, der Strahl ist nur einen Teil der Zeit auf dem Display - den Rest ist es über das Scannen oder Zurückverfolgen, und Sie sollten schwarz fahren. Wenn Sie einige "Moduszeilen"-Werte aus einer X-Window-Konfiguration für Linux erhalten, sehen Sie die Zeiten in Form möglicher Punktuhren für X und Zeilen für Y - anstatt diese in VGA-Register zu laden, die Sie benötigen etwas ähnliches für Ihr Design. Ihre aktuelle Logik sieht etwas unvollständig aus.
Um darauf zurückzukommen, bin ich mir immer noch nicht sicher, wie ich genau bestimmen kann, wann der Anzeigeteil der Zeit ist. Ich dachte zuerst, dass es sein könnte, wenn hsync und vsync nicht aktiv sind, aber das scheint nicht der Fall zu sein.
Sie müssen sich einige Wellenformen aus dem Handbuch eines älteren Qualitätsmonitors ansehen. Oder schauen Sie sich, wie bereits vorgeschlagen, einige X11-Modelines an. Sogar die Dokumentation eines Fernsehsignals würde Ihnen einen Anfang zum Verständnis geben, da die Konzepte, obwohl die Werte unterschiedlich sind, im Grunde gleich sind.