La señal de que los cambios (dependiendo de las diferentes pulsaciones de teclas) no funciona

Estoy escribiendo un código para mi FPGA que envía una señal de 10 us de ancho cada 2 ms. El código funciona muy bien, y ahora estoy tratando de implementar un código nuevo que me permitirá cambiar el ancho de pulso y el retraso usando 4 botones diferentes en el FPGA. Lo que tengo parece funcionar cuando uso modelsim, pero no en pruebas en el FPGA con un osciloscopio. Aquí está el código:

library ieee;
use ieee.std_logic_1164.all;


entity GPIO_Voltage_Test is

port(
    CLOCK_50:in     std_logic;
    GPIO_1  :out    std_logic_vector(35 downto 0);
    KEY     :IN     STD_LOGIC_VECTOR(3 DOWNTO 0)
);

end GPIO_Voltage_Test;


architecture arch of GPIO_Voltage_Test is

shared variable PhaseShift      :integer := 0;
shared variable Period          :integer := 100000; -- *20 ns, Period is 2 ms
shared variable PulseWidth      :integer := 500;    -- *20 ns, PulseWidth is 10 us
shared variable count           :integer := 0;      -- one count for every rising edge of 50 MHz clock (20 ns)
signal          KEYPRESS        :std_logic;

begin


KEYPRESS <= KEY(0) or KEY(1) or KEY(2) or KEY(3);


process(KEYPRESS)

begin

    if (rising_edge(KEYPRESS))then

        if (KEY(0)='1')then
            PhaseShift := PhaseShift+500; -- Increase PhaseShift by 500*20 ns
            PulseWidth := PulseWidth+1000;-- Increase PulseWidth by 1000*20 ns 

        elsif (KEY(1)='1')then
            PhaseShift := PhaseShift+250; -- and so on
            PulseWidth := PulseWidth+500;

        elsif (KEY(2)='1')then
            PhaseShift := PhaseShift-250;
            PulseWidth := PulseWidth-500;

        elsif (KEY(3)='1')then
            PhaseShift := PhaseShift-500;
            PulseWidth := PulseWidth-1000;

        end if;
    end if;
end process;




process(Clock_50)

begin

    if (rising_edge(Clock_50))then

    -- Begin by setting the output pulse to 1
        if (count=0)then
        GPIO_1(16)  <= '1';
        GPIO_1(17)  <= '1';
        GPIO_1(18)  <= '1';
        GPIO_1(19)  <= '1';
        end if;

    -- Increase the count by one every time there is a rising edge on the 50MHz clock
        count   := count+1;

    -- Each pin is triggered once the count reaches a certain time delay, set by PhaseShift
        if(count=1+PhaseShift)then
        GPIO_1(16)  <= '0';
        GPIO_1(17)  <= '0';
        GPIO_1(18)  <= '0';
        GPIO_1(19)  <= '0';
        end if;

    -- Once the pulse has reached a set amount of time PulseWidth, the pulse is then turned back to 1.
        if(count=1+PhaseShift+PulseWidth)then
        GPIO_1(16)  <= '1';
        GPIO_1(17)  <= '1';
        GPIO_1(18)  <= '1';
        GPIO_1(19)  <= '1';
        end if;

    -- Once the pulse has finished its period, the count is reset and the process begins again.
        if(count=Period)then
        count   := 0;
        end if;

    end if;
end process;
end arch;

Hay un poco más de código después, pero no es necesario.

Como dije antes, este código se ejecuta correctamente en modelsim, pero nada parece funcionar cuando presiono cualquiera de las teclas en el tablero. He reescrito el primer proceso de varias maneras diferentes, pero fue en vano. Logré que funcione con un botón, donde el proceso (CLAVE) es la lista de sensibilidad y la condición si es si (rising_edge (CLAVE (0))), pero siempre habrá un error si tengo múltiples flancos ascendentes desde el claves diferentes.

¿Estoy haciendo esto de la manera incorrecta? ¿Cuál sería la forma correcta de cambiar las variables usando 4 teclas diferentes en el FPGA?

Respuestas (1)

Al utilizar la señal de pulsación de tecla en una comprobación de flanco ascendente de if, lo está tratando como un reloj y está creando registros para todas las señales dentro de la instrucción if que dependen de ese reloj. Sin embargo, la señal de pulsación de tecla no tiene las transiciones de reloj perfectas que espera, por ejemplo, los botones que la activan tienen algunos rebotes que desencadenarán múltiples ejecuciones del hardware dentro de la instrucción if. También es una muy mala práctica usar una señal como reloj que no está en la red especial de relojes FPGA.

Entiendo que desea realizar esta acción de presionar una tecla una vez cada vez que presione una tecla. Para esto, necesitará 2 cosas: algo para eliminar el rebote de cada pulsación de tecla individual para que cada pulsación tenga una transición limpia de encendido y apagado y algo para hacer un pulso durante un ciclo de reloj cuando la pulsación de tecla rebotada pasa de encendido a apagado.

Aquí hay algunos recursos: Botones antirrebote: https://youtu.be/8ISfNm9zv18 Pulso de reloj único: https://youtu.be/GHheNH1-S1Y

Bien, he visto estos videos y son útiles. Entonces, ¿por qué es una mala práctica usar una señal como reloj que no está en la red especial de relojes FPGA?