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

0

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 está funcionando bien, y ahora estoy tratando de implementar un nuevo código que me permita cambiar el ancho del pulso y la demora usando 4 botones diferentes en el FPGA. Lo que tengo parece funcionar cuando utilizo modelsim, pero no en las 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 he dicho 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 sin éxito. Lo he hecho funcionar con un botón, donde proceso (KEY) es la lista de sensibilidad y la condición if es if (rising_edge (KEY (0))), pero siempre habrá un error si tengo varios flancos ascendentes desde el teclas diferentes.

¿Simplemente estoy haciendo esto de manera incorrecta? ¿Cuál sería la forma correcta de cambiar las variables utilizando 4 claves diferentes en el FPGA?

    
pregunta Cody495

1 respuesta

2

Al utilizar la señal de pulsación de tecla en una comprobación de aumento de la cobertura, lo está tratando como un reloj y está registrando todas las señales dentro de la sentencia 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 lo impulsan tienen algún rebote que activará múltiples ejecuciones del hardware dentro de la declaración if. También es una muy mala práctica usar una señal como un reloj que no está en la red especial de reloj FPGA.

Comprendo que desea realizar esta acción de pulsación de tecla una vez que presione cada tecla. Para esto, necesitará 2 cosas: algo para rebotar cada vez que se presione una tecla para que cada presión tenga una transición de encendido y apagado y algo para hacer un pulso durante un ciclo de reloj cuando la tecla de rebote presione transiciones de encendido a apagado.

Aquí hay algunos recursos: Botones de rebote: enlace Pulso de un solo reloj: enlace

    
respondido por el Lincoln

Lea otras preguntas en las etiquetas