Desigualdad fuera del proceso (¿en qué momento?) (VHDL)

0

Estoy reescribiendo un controlador VGA en (espero) una mejor manera; Tengo una señal "en blanco" lo que significa que el píxel actual está fuera del área visible, y tengo la sensación de que sería mejor dividir esa señal fuera del proceso de "procesamiento de píxeles" (¿condiciones de carrera?).

Estoy intentando traducir algo como esto:

-- Horizontal procedure:
h_proc : process(pix_clk) 
begin
    if(rising_edge(pix_clk)) then
        -- counts the pixel clocks
        h_cnt <= h_cnt + 1; 
        -- updates the blank signal (whether in visible area or not)
        if(h_cnt <= HRES and v_cnt <= VRES) then
            blank <= false;
        -- generates synchronisation signals
        else
            blank <= true;
            if(h_cnt > HRES+HFP and h_cnt < HRES+HFP+HSP) then
                h_sync <= '0';
            else
                h_sync <= '1';
            end if;
        end if;
    end if;
end process;

En esto:

blank <= false when h_cnt <= HRES and v_cnt <= VRES, else false;
-- And while I'm at it
h_sync <= '0' when h_cnt > HRES+HFP and h_cnt < HRES+HFP+HSP, else '1';

Pero acabo con un error de sintaxis. ¿No hay alguna forma de derivar la prueba en desigualdades tales como mayor o menor que fuera de los procesos?

Código modificado Dentro de la arquitectura:

-- blank is true outside of the visible area (where synchronisation pulses are sent and black is needed)
blank <= false when h_cnt <= HRES and v_cnt <= VRES else true;

-- Address of the pixel (block of memory containing the color of the pixel)
buffer_addr <= std_logic_vector(to_unsigned(h_cnt+v_cnt*HRES, buffer_addr'length)) 
                   when blank = false else (others => '0');

-- Colors returned correspond to the aimed pixel, but black if out of the visible area
R <= buffer_data(RDEPTH+GDEPTH+BDEPTH-1 downto GDEPTH+BDEPTH) when blank = false else (others => '0');
G <= buffer_data(GDEPTH+BDEPTH-1 downto BDEPTH) when blank = false else (others => '0');
B <= buffer_data(BDEPTH-1 downto 0) when blank = false else (others => '0');

-- Synchronisation pulses
h_sync <= '0' when h_cnt > HRES+HFP and h_cnt < HRES+HFP+HSP else '1';
v_sync <= '0' when v_cnt > VRES+VFP and v_cnt < VRES+VFP+VSP else '1';

-- Counter update procedure:
h_proc : process(pix_clk) 
begin
    if(rising_edge(pix_clk)) then
        -- counts the pixel clocks, update the line counts and reset the counters when appropriate
        if(h_cnt = HRES+HFP+HSP+HBP) then
            h_cnt <= 0;
            if(v_cnt = VRES+VFP+VSP+VBP) then
                v_cnt <= 0;
            else
                v_cnt <= v_cnt + 1; 
            end if;
        else
            h_cnt <= h_cnt + 1; 
        end if;
    end if;
end process;
    
pregunta Mister Mystère

1 respuesta

4

Su enfoque es perfectamente legal. Las comas no son, sin embargo. Deshacerse de ellos debería resolver su problema, a menos que haya otros problemas que no estén claros en el código que publicó.

Sin embargo, tenga en cuenta que hay efectos secundarios al mover su código de un proceso cronometrado, aunque el valor de blank cambiará 1 reloj antes y su rendimiento de sincronización será peor. Asegúrese de que su diseño pueda sostener estos cambios.

Tenga en cuenta también que la lógica para h_sync no es equivalente (aunque esto puede ser una mejora): en el proceso cronometrado, a h_sync no se le asigna un valor en cada rama del bloque if, y parece que podría atascarse en '0' para ciertos valores de HFP , etc. En la asignación concurrente, su valor siempre se asigna explícitamente.

breve tutorial sobre asignación de señal secuencial

Consulte ¿Cómo funciona la asignación de señales en un proceso?

La forma canónica de pensar acerca de los procesos VHDL es que las señales no se actualizan hasta que el proceso se suspende (que, para un proceso cronometrado, se encuentra al final del proceso). Puede ser útil darse cuenta de que los procesos sincronizados están destinados a representar registros físicos y la propagación de la señal real. De cualquier manera, si está asignando múltiples señales interdependientes en procesos cronometrados, el valor solo puede "avanzar" una señal a la vez en cada borde del reloj.

Así que considera el siguiente código:

(A )

process (clk)
  if rising_edge(clk) then
    foo <= foo + 1; -- if value is becoming N this clock cycle...
    if foo = N then -- value is still N-1 here - signal has not updated yet
      bar <= '1';
    else
      bar <= '0';
    end if;
  end if;
end process;

(B )

process (clk)
  if rising_edge(clk) then
    foo <= foo + 1; -- if value is becoming N this clock cycle...
  end if;
end process;

bar <= '1' when foo = N else '0'; -- assigned concurrently, so value is already N here

En (A), foo no se actualiza hasta el final del proceso. En el ciclo del reloj cuando foo se convierte en N , no se ha actualizado cuando se realiza la verificación "if", por lo que el valor de bar no cambiará. bar cambiará 1 reloj más tarde, ya que en esa iteración del proceso, foo se habrá actualizado para que sea igual a N .

En (B), bar no se asigna en un proceso cronometrado y, por lo tanto, se actualizará tan pronto como foo cambie (después de algunos retrasos lógicos en el mundo real, por supuesto).

¿Eso ayuda?

    
respondido por el fru1tbat

Lea otras preguntas en las etiquetas