Ich versuche, einen VGA-Controller aus einem Lattice MachXO CPLD in Verilog zu erstellen.
Das Problem
Ich versuche, die Farbe Rot mit einer Auflösung von 640 x 480 bei 60 Hz anzuzeigen, indem ich einen CPLD-internen 25,175-MHz-Takt verwende. Wenn ich jedoch das CPLD an einen Monitor anschließe, erhalte ich die Meldung „Außer Reichweite“. Kein Monitor, den ich versuche, kann verstehen, welche Auflösung ich möchte.
Was ich versucht habe
Ich habe den Code in ModelSim simuliert (Bilder enthalten), und bis auf ein Problem scheint alles gut auszusehen. Wenn ich die Anzahl der Zeitschritte zähle, die während der V-Sync-Anzeigezone aufgetreten sind (wenn H-Sync zeichnet) und sie durch die H-Sync-Frequenz dividiere, erhalte ich 479 Impulse – einer weniger als 480 Linien, die ich zeichnen sollte. Ich verstehe nicht, woher das kommen könnte, da ich meine Timings viele Male überprüft habe, und ich vermute, dass dies ein Symptom des Problems sein könnte , aber ich bin mir nicht sicher.
Die Zahlen, die ich verwende, um meine Zahlen für Timings zu generieren, stammen von Tiny VGA: tinyvga.com/vga-timing/640x480@60Hz Anstatt Zeilen für V_SYNC zu zählen, zähle ich jedoch Taktimpulse. Die Zahlen sollten jedoch gleichwertig sein (dh. 2 800 Zählstriche = 1600 Impulse). Ich kann dieses Verhalten später in Zeilenzählung ändern.
Unten ist mein Code und Bilder der Timings von ModelSim.
module Top(RESET, H_SYNC, V_SYNC, RED);
input wire RESET;
output wire H_SYNC;
output wire V_SYNC;
output wire RED;
wire rgb_en;
/*** Test Bench Code ***/
//reg osc_clk, reset;
//initial begin
//#0 reset = 0;
//#0 osc_clk = 0;
//#2 reset = 1;
//end
//always #1 osc_clk = ~osc_clk;
OSCC OSCC_1 (.OSC(osc_clk)); /*< IP clock module for Lattice CPLD >*/
Controller CNTRL(.NRST(RESET), .CLK(osc_clk), .H_SYNC(H_SYNC), .V_SYNC(V_SYNC), .RGB_EN(rgb_en));
assign RED = (rgb_en ? 1:1'bz);
endmodule
module Controller(CLK, NRST, H_SYNC, V_SYNC, RGB_EN);
input wire CLK; /*< CLK input from Top module >*/
input wire NRST; /*< Reset input from Top module >*/
output reg H_SYNC; /*< Goes to VGA Horizontal Sync >*/
output reg V_SYNC; /*< Goes to VGA Verical Sync >*/
output reg RGB_EN ; /*< Enables RGB values durning display time on H_SYNC >*/
reg [9:0] h_counter; /*< Tracks amount of pulses from CLK >*/
reg [18:0] v_counter; /*< Tracks amount of pulses from H_SYNC >*/
`define H_SYNC_PULSE 10'd96 /*< Length of Sync Pulse >*/
`define H_BACK_PORCH_END 10'd144 /*< Pulse len + Porch Len >*/
`define H_FRONT_PORCH_STRT 10'd784 /*< Front Porch Len - Max >*/
`define H_COUNT_MAX 10'd799 /*< Max line pulses for resolution >*/
`define V_SYNC_PULSE 19'd1600 /*< 2 H_SYNC lines >*/
`define V_BACK_PORCH_END 19'd28000 /*< 33+2 H_SYNC lines >*/
`define V_FRONT_PORCH_STRT 19'd412000 /*< 525-10 H_SYNC lines >*/
`define V_COUNT_MAX 19'd419999 /*< 525 H_SYNC lines >*/
/*** Logic for H_SYNC ***/
always @(*) begin
if (h_counter < `H_SYNC_PULSE) begin
H_SYNC = 0;
RGB_EN = 0;
end
/* If H_Sync is in the display zone, enable RGB */
else if (h_counter > `H_BACK_PORCH_END && h_counter < `H_FRONT_PORCH_STRT) begin
H_SYNC = 1;
RGB_EN = 1;
end
/* During the Front Porch period, disable RGB */
else begin
H_SYNC = 1;
RGB_EN = 0;
end
end
/*** Logic for V_SYNC ***/
always @(*) begin
if (v_counter < `V_SYNC_PULSE) begin
V_SYNC = 0;
end
else begin
V_SYNC = 1;
end
end
/*** Counter logic ***/
always @(posedge CLK) begin
if (h_counter >= `H_COUNT_MAX || !NRST) begin
h_counter <= 11'b00;
end
else begin
h_counter <= h_counter + 1;
end
end
always @(posedge CLK) begin
if (v_counter >= `V_COUNT_MAX || !NRST) begin
v_counter <= 11'b00;
end
else begin
v_counter <= v_counter + 1;
end
end
endmodule
Sie müssen den H_SYNC-Ausgang auch dann aufrecht erhalten, wenn V_SYNC aktiv ist.
Endlich habe ich mein Problem eingekreist. In der Dokumentation für das CPLD und gemäß den Vorschlägen meiner Professoren dachte ich, dass die interne Uhr des CPLD konfigurierbar sei. Es stellt sich heraus, dass ich die Fehlerspanne auf der Uhr gelesen habe, nicht die Programmierbarkeit. Mein Problem ist, dass der interne Oszillator nicht mit 25,175 MHz läuft, wie ich dachte.
Falls eine andere Seele dies googelt, lassen Sie es wissen, dass der Lattice MachXO 2280 nicht für die VGA-Ausgabe verwendet werden kann, da der Zufallswert und die Unprogrammierbarkeit der Uhr ohne die Verwendung eines externen Oszillators erfolgen.
WütendEE
mng
Jon.H