Controlador VGA en pantallas VHDL solo negras

Objetivo y datos Estoy tratando de hacer un controlador VGA en un Spartan 6 (placa Micro Mojo integrada) para mostrar algo simple como la bandera francesa en un monitor LCD, en 640x480 8 colores. Vivo en Europa y el monitor es 16:10 si es importante.

Cableado Conecté hsync y vsync a mi monitor siguiendo este diagrama y, para empezar, conecté las señales RG y B a una fuente de alimentación de 0,7 V. Supongo que el voltaje es el máximo (mucha gente dice que es al menos), dando blanco.

Síntomas Al iniciar el siguiente código aparece una pantalla negra. No aparece el mensaje "Fuera de rango [31kHz 40Hz]" (como sucedió cuando tuve un error de tiempo), y si hago un mal contacto con el 0.7V en cualquier pin de color (es decir, temblando un poco), rayas aleatorias de el color correspondiente aparece muy brevemente; si el contacto es bueno, la pantalla se vuelve completamente negra nuevamente.

Pregunta Creo que tengo una idea de por qué no funciona, en mi opinión es el hecho de que los colores nunca vuelven a cambiar a negro al final del período como sugiere el protocolo. Si tengo razón (si no la tengo, ¿por qué?), ¿por qué es necesario eso para formar una imagen? A mi modo de ver, solo se trata de aplicar los colores en el momento adecuado y restablecer la rampa de placas verticales/horizontales en el momento adecuado...

Código

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;

lo que yo entiendo

Y podría estar equivocado, vea la siguiente imagen. En base a esto, la relación de aspecto y la frecuencia de actualización vertical de resolución completa no son importantes ahora, ¿verdad (dado que con una imagen más pequeña, la frecuencia de actualización es mayor)?ingrese la descripción de la imagen aquí

Hay 3 PLL en monitores LCD/TV. V, H y borde de píxeles mín. intervalo. Puede haber docenas de proporciones aceptables, pero sus tarifas estaban fuera de rango. Si la tasa de píxeles es de 25 MHz y H es de 31k, entonces P/H=806 (800 reales), entonces se espera que la tasa de V sea de 525 relojes H +\-10%, pero no fue así. H/V fue 775
Entonces, ¿me está diciendo que se debe escanear toda el área de los monitores, de lo contrario, el monitor rechazará la señal? Por lo tanto, si mantengo los mismos porches traseros/delanteros y cambio mi Vcounter para que se reinicie en 775, ¿funcionará (lo siento, no puedo intentarlo ahora...)? En ese caso, ¿por qué mi monitor no dice "Fuera de rango", como lo hizo cuando tuve otro error? ¿O por qué se muestran los colores cuando la conexión en las líneas RGB no es estable?
A veces, las pantallas utilizan los niveles de señal fuera de la pantalla para establecer el 'nivel de negro'. Si el 'nivel de negro' corresponde al color que desea mostrar, todo lo que obtiene es negro. Ahora, no tengo idea si esta pantalla en particular establece el nivel de negro así o no, pero recomendaría seguir el protocolo exactamente.
Los televisores LCD como los monitores de PC pueden manejar una amplia variedad de modos, lo ideal es el modo nativo que usa la misma cantidad de píxeles en la misma relación de aspecto. Pero también las tasas heredadas más antiguas y las tasas más altas aceptarán las entradas analógicas. El nivel de video después de la sincronización se usa para la fijación del nivel de negro llamado porche trasero. No hay una regla establecida, pero 800x600 es universal, en muchos casos también lo es 640x480, pero esta resolución muy baja de 307,2 k píxeles para un HDTV que admite 1920x1080 = 2,07 Mpix, ya sea 1080p o 1080i, por lo que no existe una regla que todos los televisores deben admitir VGA. .
¿Puedo preguntar por qué comentaste todas las partes del código que cambia el valor del píxel? Dado que no tiene un controlador para las señales R, G y B, están optimizadas y la herramienta P&R las establecerá en sus valores predeterminados y eso explica por qué aparece todo negro en la pantalla.
Además, noté que la señal azul (b) tiene solo dos bits de ancho, por lo que sus asignaciones a b deben ajustarse en consecuencia.
@FarhadA: Los comenté porque aún no tengo los valores de resistencia correctos para hacer un DAC adecuado, así que sujeté todas las entradas RGB a la luminancia máxima (0.7V). Si el porche trasero se usa para registrar negro, eso explicaría por qué solo obtengo negro ... Pero dado que asumo que el ADC interno debe ser de al menos 8 bits, esperaba un poco de ruido para probarlo.
No entiendo lo que estás diciendo aquí.

Respuestas (2)

La velocidad del reloj de píxeles debe ajustarse para lograr velocidades Vsync y velocidades Hsync que sean aceptables para su monitor multisync.

Dado que 40 Hz no es una frecuencia Vsync común, pruebe con 30, 50 o 60 o más.

640*480 * 40 Hz = 12,3 MHz, por lo que parece que los píxeles se expulsan a la mitad de la frecuencia de reloj de 25 MHz

La temporización NTSC para V Sync, porche delantero (480~494), Hsync, porche trasero (495~525) de la siguiente manera usando 25MHz ingrese la descripción de la imagen aquíHsync se puede variar tanto con períodos anteriores como posteriores siempre que la suma sea la misma. Algunos monitores tienen una tolerancia del 10 % según el diseño.

Gracias por tu respuesta. Ese código ya está configurado para proporcionar un reloj de píxeles de 25 MHz, una velocidad de sincronización vertical de 60 Hz, lo que da una velocidad de sincronización horizontal de 31,5 kHz. Me sorprendió ver 40 Hz en esa pantalla, pero supongo que tiene algo que ver con la relación de aspecto (el monitor no es 4:3 sino 16:10). La imagen resultante debe ser más pequeña que los bienes inmuebles disponibles, pero aun así debe mostrarse, ¿verdad?
Las tasas de sincronización no son las que esperabas, cambia el modo TV a 4x3 o estira. Verifique la frecuencia de sincronización. parece que la tasa de píxeles es de solo 12,3 MHz. Sin embargo, la relación H / V no es 640. ¿Cuántos píxeles se asignan para sincronización H y sincronización V?
Verifique la tasa de píxeles con alcance. Algo anda mal aquí
Gracias por el diagrama, siempre valen más que mil palabras. Por esta razón, subí un diagrama de lo que entiendo, porque todavía no sé por qué los 40 Hz y la relación de aspecto son un problema. Probaré con 4/3 el martes, no tengo el rig a mano (solo la tabla). Sin embargo, simulé el diseño con ISim y todas las señales son correctas (reloj de 25 MHz y todos los tiempos según las especificaciones).

@alex.forencich dio la respuesta correcta en los comentarios: el color negro se registró fuera del área visible, y dado que para mi configuración de prueba había conectado todas las entradas analógicas a la luminancia máxima (0,7 V), el negro se registró como la misma señal que fue enviado en la región activa => negro. Medí la impedancia de entrada del monitor (aparentemente, estos 100 ohmios son estándar) y agregué las resistencias apropiadas (4R, 2R, R, donde 7R hace un divisor de voltaje con la resistencia de entrada) en R (0 a 2) G (0 a 2) B (0 a 2) para obtener el voltaje adecuado. Sin cambiar nada de los contadores, logré imprimir mi bandera francesa. Gracias, si publicas una respuesta la aceptaré.