Signal, das sich ändert (abhängig von verschiedenen Tastendrücken) funktioniert nicht

Ich schreibe einen Code für mein FPGA, das alle 2 ms ein Signal mit einer Breite von 10 us sendet. Der Code funktioniert großartig, und jetzt versuche ich, einen neuen Code zu implementieren, der es mir ermöglicht, die Impulsbreite und Verzögerung mit 4 verschiedenen Tasten auf dem FPGA zu ändern. Was ich habe, scheint bei der Verwendung von Modelsim zu funktionieren, aber nicht beim Testen auf dem FPGA mit einem Oszilloskop. Hier ist der Code:

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;

Danach folgt etwas mehr Code, der jedoch nicht erforderlich ist.

Wie ich bereits sagte, läuft dieser Code in Modelsim ordnungsgemäß, aber nichts scheint zu funktionieren, wenn ich eine der Tasten auf der Platine drücke. Ich habe den ersten Prozess auf verschiedene Weise umgeschrieben, aber ohne Erfolg. Ich habe es mit einer Schaltfläche zum Laufen gebracht, wobei process(KEY) die Empfindlichkeitsliste und die if-Bedingung if (rising_edge(KEY(0))) ist, aber es wird immer ein Fehler auftreten, wenn ich mehrere steigende Flanken von habe verschiedene Schlüssel.

Gehe ich das einfach falsch an? Was wäre der richtige Weg, um die Variablen mit 4 verschiedenen Tasten auf dem FPGA zu ändern?

Antworten (1)

Indem Sie das Tastendrucksignal in einer Prüfung auf steigende Flanke verwenden, behandeln Sie es wie eine Uhr und erstellen Register für alle Signale innerhalb der if-Anweisung, die von dieser Uhr abhängen. Das Tastendrucksignal hat jedoch nicht die perfekten Taktübergänge, die Sie erwarten, zum Beispiel haben die Tasten, die es ansteuern, einen gewissen Sprung, der mehrere Ausführungen der Hardware innerhalb der if-Anweisung auslöst. Außerdem ist es sehr schlecht, ein Signal als Takt zu verwenden, das nicht auf dem speziellen FPGA-Taktnetzwerk ist.

Ich verstehe, dass Sie diese Tastendruckaktion einmal bei jedem Tastendruck ausführen möchten. Dazu benötigen Sie 2 Dinge: etwas, um jeden einzelnen Tastendruck zu entprellen, so dass jeder Druck einen sauberen Ein-Aus-Übergang hat, und etwas, um einen Impuls für einen Taktzyklus zu erzeugen, wenn der entprellte Tastendruck von Ein nach Aus übergeht.

Hier sind einige Ressourcen: Entprellungstasten: https://youtu.be/8ISfNm9zv18 Einzeltakt: https://youtu.be/GHheNH1-S1Y

Okay, ich habe mir diese Videos angesehen und sie sind hilfreich. Warum ist es also sehr schlecht, ein Signal als Takt zu verwenden, das sich nicht im speziellen FPGA-Taktnetzwerk befindet?