Nachdem ich viel darüber recherchiert hatte, wie man VGA-Signale erzeugt, und mir ein paar Codebeispiele angesehen hatte, versuchte ich, einen einfachen VGA-Signalgenerator zu schreiben, der nur eine einzelne Farbe auf dem Bildschirm anzeigt. Beim Betrachten der Simulation scheint das Timing korrekt zu sein. Beim Anschluss an einen Monitor erkennt der Monitor nicht einmal, dass ein Signal erzeugt wird. Das hat mich ratlos gemacht, jede Hilfe wäre dankbar.
Ich verwende Timing-Informationen, die hier zu finden sind: http://tinyvga.com/vga-timing/640x480@60Hz
Synchronimpulsgenerator:
module VGASyncPulseGenerator(
input clk, //50Mhz input clock
input rst,
output HS, VS, //Sync Pulses
output active //High when active area is being drawn
);
localparam HS_START = 16; // hSync start (end of front porch)
localparam HS_END = 16 + 96; // hSync end (start of back porch)
localparam HA_START = 16 + 96 + 48; // end of back porch
localparam LINE = 800; // Length of entire line;
localparam VS_START = 480 + 10; // vSync start (end of front porch)
localparam VS_END = 6480 + 10 + 2; // vSync end (start of back porck)
localparam VA_START = 0;
localparam FRAME = 525; // Length of entire frame
reg [10:0] hPos = 0;
reg [10:0] vPos = 0;
reg pixelStrobe = 0;
assign HS = ~((hPos >= HS_START) & (hPos < HS_END));
assign VS = ~((vPos >= VS_START) & (vPos < VS_END));
assign active = (hPos >= HA_START) & (vPos >= VA_START);
always @(posedge clk) begin //generate pixel clock at 25MHz
pixelStrobe = ~pixelStrobe;
end
always @(posedge clk) begin
if (pixelStrobe) begin
if (hPos == LINE) begin
hPos <= 0;
vPos <= vPos + 1;
end else hPos <= hPos + 1;
if (vPos == FRAME) vPos <= 0;
end
end
endmodule
Top-Modul:
module VGATest(
input clk, rst,
output HS, VS,
output [4:0] B,
output [5:0] R,
output [4:0] G
);
wire active;
assign R = (active) ? 5'd1 : 5'b0;
assign G = (active) ? 4'd16 : 4'b0;
assign B = (active) ? 4'd1 : 4'b0;
VGASyncPulseGenerator pulseGen(clk, rst, HS, VS, active);
Endmodul
Probleme, die ich in Ihrem Code sehe:
640x480@60 verwendet einen Pixeltakt von 25,175 MHz, nicht 25 MHz. Der Unterschied kann ausreichen, um einige Monitore von der Synchronisierung abzuhalten. Erwägen Sie die Verwendung einer PLL, um den geeigneten Takt zu erzeugen (50 MHz x72÷143 ergibt 25,1748 MHz, was innerhalb von 9 ppm liegt), oder zielen Sie stattdessen auf 800x600@72 ab, was einen Pixeltakt von genau 50 MHz verwendet.
Die Polarität Ihrer Synchronimpulse ist falsch. 640x480@60 verwendet negative Synchronisationsimpulse – HS
und VS
muss während der Synchronisation niedrig sein, nicht hoch.
Es gibt einen Tippfehler in der Definition von VS_END
. Sie möchten wahrscheinlich die Konstante 480 verwenden, nicht 6480.
Mögliche Probleme außerhalb Ihres Codes:
Haben Sie eine entsprechende Constraints-Datei? Werden die Signale den richtigen Pins zugeordnet, um den DAC zu erreichen?
Stellen Sie sicher, dass Ihre Ebenen korrekt sind. R/G/B sind 0 bis 0,7 V; Sync-Spannungen sind nicht kritisch, sollten aber wahrscheinlich 3,3 V betragen.
Nachdem ich darauf zurückgekommen bin, scheint es, dass die UCF-Datei in meinem Projekt aus irgendeinem Grund nicht verwendet wurde. Das war der Grund, warum das Modul nicht funktionierte.
KH
Ale..chenski
HKOB
Chris Stratton
Nazar