El controlador VGA no funciona

En este momento estoy tratando de hacer un controlador vga para mi FPGA, pero algo no va bien, y parece que no puedo encontrar qué es lo que va mal...

El código se basa en este ejemplo de código: Ejemplo de controlador VGA

Aquí está mi código: (solo cambié la resolución y algunos nombres de variables, aparte de eso, debería ser exactamente igual).

    ----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 03/07/2016 08:53:44 AM
-- Design Name: 
-- Module Name: vga - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity vga is
    GENERIC(
            constant HR:integer:=640;--Horizontal Resolution
            constant HFP:integer:=16;--Horizontal Front Porch
            constant HBP:integer:=48;--Horizontal Back Porch
            constant HRet:integer:=96;--Horizontal retrace
            h_pol    :  STD_LOGIC := '0';   --horizontal sync pulse polarity (1 = positive, 0 = negative)

            constant VR:integer:=480;--Vertical Resolution
            constant VFP:integer:=10;--Vertical Front Porch
            constant VBP:integer:=33;--Vertical Back Porch
            constant VRet:integer:=2;--Vertical Retrace); 
            v_pol    :  STD_LOGIC := '0'  --vertical sync pulse polarity (1 = positive, 0 = negative)

            );
    Port ( clk : in STD_LOGIC;
           LED0: out std_logic;
           vga_r: out std_logic_vector(4 downto 0);
           vga_g: out std_logic_vector(5 downto 0);
           vga_b: out std_logic_vector(4 downto 0);
           vga_vs: out std_logic;
           vga_hs: out std_logic);
end vga;

architecture Behavioral of vga is
signal COUNT : integer range 0 to 100000000;
constant x_counter:  integer := HR + HFP + HBP + HRet;   
constant y_counter:  integer := VR + VFP + VBP + VRet;
signal newCounter: integer range 0 to 4 := 0;
signal newClk: std_logic; 
begin

alive: process(CLK)
    begin
        if rising_edge(CLK) then 
           COUNT  <= COUNT + 1;

           if COUNT = 100000000 then 
               COUNT <= 0; 
           end if;

           if COUNT < 100000000/2 then 
           --     LED0 <=  '1';
           else 
           --     LED0 <= '0';
           end if;           
        end if;
end process;

prescaler: process(clk)
begin
    if rising_edge(clk) then 
        newCounter <= newCounter +1; 
            if newCounter = 4  then 
                newClk <= ‘1’;
                newCounter <= 0;
            else    
                newClk <= ‘0’;  
            end if;
    end if; 
end process;




screen:process(newClk)
VARIABLE h_count  :  INTEGER RANGE 0 TO x_counter - 1 := 0;  --horizontal counter (counts the columns)
VARIABLE v_count  :  INTEGER RANGE 0 TO y_counter - 1 := 0;  --vertical counter (counts the rows)
begin
 -- Horizontal 640 
 -- Vertical 480
 if rising_edge(newClk) then
 -- Increase Horizontal counter
    if (h_count < x_counter - 1 ) then 
        h_count := h_count + 1;
    else 
        h_count := 0 ;    
        -- Increase Vertical counter   
        if (v_count < y_counter - 1 ) then 
            v_count := v_count + 1;
        else 
            v_count := 0 ;
        end if; 
    end if; 

     --horizontal sync signal
     IF(h_count < HR + HFP OR h_count > HR + HFP + HRet) THEN
        vga_hs <= NOT h_pol;    --deassert horiztonal sync pulse
        LED0 <= NOT h_pol; 
     ELSE
        vga_hs <= h_pol;        --assert horiztonal sync pulse
        LED0 <= h_pol;
     END IF;

     --vertical sync signal
     IF(v_count < VR + VFP OR v_count > VR + VFP + VRet) THEN
        vga_vs <= NOT v_pol;    --deassert vertical sync pulse
     ELSE
        vga_vs <= v_pol;        --assert vertical sync pulse
     END IF;       
 end if;
 end process;

 vga_r <= "11111";
 vga_g <= "000000";
 vga_b <= "00000";



end Behavioral;
"- ¿Lo que sucede?" "- No funciona."
Bueno... la pantalla se vuelve negra... Esperaría mostrarse en rojo ya que todos esos pines están altos
Suponiendo que haya verificado que la sincronización y la polaridad de H y V son correctas, es posible que su monitor se esté burlando de usted: muchos monitores modernos se niegan a mostrar una señal VGA que no tiene ningún espacio en blanco horizontal y vertical detectable en el canales de video analógicos.
El monitor funciona con señal VGA, lo probé con un archivo de bits que funcionaba... La frecuencia clk = 125 mhz El preescalador reduce el reloj a 25 mhz, que es la configuración (tenía la intención de usar) La resolución estoy tratando de recrear es 640 x 480
La señal utilizada para proporcionar supresión en el controlador VGA de ejemplo es disp_enala que le indica cuándo no está en supresión. Cuando disp_ena no es '1' en hw_image_generator.vhd, r,g yb son '0' (negro). En una pantalla analógica, el color se muestrea durante el intervalo de retroceso horizontal para determinar dónde se establece el negro.
¿Ha verificado realmente que hsync y vsync son correctos con un alcance?

Respuestas (2)

Asigna valores constantes a sus líneas de color VGA, lo que no funcionará.

Un monitor VGA analógico espera ver un nivel de "negro" de referencia durante parte de la duración del seguimiento fuera de la pantalla. Si maneja un valor sustancialmente distinto de cero allí, se adaptará a la idea de que este voltaje significa negro, y no obtendrá el rectángulo de color esperado (en algunos monitores, es posible que obtenga un breve destello de color al conectarse, antes yendo a todo negro).

Deberá alternar sus líneas de color entre el color deseado y el negro durante los períodos de tiempo en los que deberían señalar el color en el área activa o la referencia negra fuera de ella.

Dos herramientas muy útiles serán un diagrama de tiempo de cómo debería verse VGA y, si es posible, un osciloscopio que compare su señal con la de una configuración de tarjeta VGA para generar algo similar (¿salvapantallas a todo color?)

Así que... No estoy seguro de entender bien cuándo quieres que cambie el color de un estado a otro.
El enfoque más simple es hacer que las líneas se vuelvan negras siempre que el trazo no esté dentro del rectángulo de la pantalla que está tratando de pintar de rojo. Es un poco más fácil si solo pinta un rectángulo de 640x480 y no intenta colorear el overscan, aunque con más atención a un diagrama de tiempo VGA que puede (?) ser posible.

Como ya mencionaron Chris Stratton et.al., debe establecer el color en negro durante los intervalos de supresión. Esto se logró mediante la señal disp_enaen el diseño de ejemplo vinculado en su pregunta.

Para agregar dicho comportamiento a su diseño, debe:

1) Agregue una nueva señal disp_enaen la parte de declaración de arquitectura:

signal disp_ena : std_logic;

2) Establezca esta señal sincronizada con el reloj en '1' cuando se muestra la imagen y en '0' en caso contrario (durante el borrado).

screen:process(newClk)
-- ... existing code
begin
  if rising_edge(newClk) then
     -- ... existing code

     --set display-enable control signal
     IF(h_count < HR and v_count < VR) THEN
        disp_ena <= '1';
     ELSE
        disp_ena <= '0';
     end IF;
  end if;
end process;

3) Establezca el color en rojo solo cuando la visualización esté habilitada ( disp_ena = '1'), de lo contrario, en negro. Por lo tanto, cambie las líneas existentes a:

vga_r <= "11111" when disp_ena = '1' else (others => '0');
vga_g <= "000000" when disp_ena = '1' else (others => '0');
vga_b <= "00000" when disp_ena = '1' else (others => '0');

Estás generando una nueva señal de reloj usando un contador. Esta no es una buena práctica de diseño. Debería usar uno de los PLL en el FPGA en su lugar. Puede crear una instanciación adecuada a través de Xilinx IP Core Generator.

Si quieres quedarte con el contador, entonces tienes dos opciones:

1) Use un BUFGcomponente para minimizar el sesgo en la red del reloj newclk. Para usar este componente, debe incluir:

library unisim;
use unisim.vcomponents.all;

Luego crea una instancia de la BUFGvía:

newclk_bufg: BUFG (I => newclk, O => newclk2);

Luego use newclk2para manejar los registros.

2) Utilizar newclkcomo señal de activación de reloj en lugar de señal de reloj. Luego, el screenproceso se activará CLK, pero la carga de los nuevos valores de registro ocurrirá solo si newclkes alto:

screen:process(CLK)
-- ... existing code
begin
  if rising_edge(CLK) then
     if newclk = '1' then   -- newclk used as clock-enable here
        -- ... existing code
     end if;
  end if;
end process;

Compruebe también si ha especificado las restricciones de tiempo correctas para el reloj CLKen el archivo UCF (ISE) o el archivo XDC (Vivado).

sigue sin funcionar..
@dfh la generación de newclkpodría ser un problema como se discute ahora en mi respuesta extendida.
Bueno... el código publicado arriba no muestra nada correctamente. La pantalla dice que la entrada no es compatible.
¿ Para qué solución newclkhas probado? ¿La pantalla dice algo sobre una frecuencia incorrecta? ¿Está seguro de que la frecuencia de entrada de su FPGA es de 125 MHz?