Lo que intento hacer es crear un controlador VGA a partir de un CPLD Lattice MachXO en Verilog.
El problema
Estoy intentando mostrar el color rojo con una resolución de 640x480 @ 60Hz usando un reloj interno de 25.175 MHz para el CPLD; sin embargo, cuando conecto el CPLD a un monitor, aparece el mensaje "Fuera de rango"; ningún monitor que pruebo puede entender qué resolución me gustaría.
lo que he probado
He simulado el código en ModelSim (imágenes incluidas), y todo parece verse bien excepto por un problema. Cuando cuento la cantidad de pasos de tiempo que han ocurrido durante la zona de visualización de V-Sync (cuando H-Sync está dibujando) y lo divido por la frecuencia de H-Sync, obtengo 479 pulsos, uno menos que los 480 líneas que debería estar dibujando. No entiendo de dónde podría provenir esto, ya que he verificado mis tiempos muchas veces y sospecho que esto puede ser un síntoma del problema, pero no estoy seguro.
Los números que estoy usando para generar mis números para los tiempos son de Tiny VGA: tinyvga.com/vga-timing/640x480@60Hz En lugar de contar líneas para V_SYNC, estoy contando pulsos de reloj, sin embargo, los números deben ser equivalentes (es decir, 2 800 líneas de conteo = 1600 pulsos). Puedo cambiar este comportamiento al conteo de líneas más tarde.
A continuación se muestra mi código y las imágenes de los tiempos de 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
Debe mantener la salida H_SYNC incluso cuando V_SYNC está activo.
Finalmente me he concentrado en mi problema. En la documentación del CPLD y según las sugerencias de mis profesores, pensé que el reloj interno del CPLD era configurable. Resulta que lo que estaba leyendo era el margen de error del reloj, no la programabilidad. Mi problema es que el oscilador interno no ha estado funcionando a 25,175 MHz como pensaba.
En caso de que algún otro alma busque esto en Google, que se sepa que el Lattice MachXO 2280 no se puede usar para la salida VGA debido al valor aleatorio y la falta de programación del reloj sin usar un oscilador externo.
EnojadoEE
gestión
Jon.H