0
\$\begingroup\$

I am writing a code for my FPGA that sends a signal 10 us wide every 2 ms. The code is working great, and now I am trying to implement some new code that will allow me to change the pulse width and delay using 4 different buttons on the FPGA. What I have seems to work when using modelsim, but not in testing on the FPGA with an oscilloscope. Here is the 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;

There is a little more code after, but it isn't necessary.

Like I said before, this code runs properly in modelsim, but nothing seems to work when I press any of the keys on the board. I've rewritten the first process several different ways, but to no avail. I have gotten it to work with one button, where process(KEY) is the sensitivity list and the if condition is if (rising_edge(KEY(0))), but there will always be an error if I have multiple rising edges from the different keys.

Am I just going about this the wrong way? What would be the proper way to change the variables using 4 different keys on the FPGA?

\$\endgroup\$
2
\$\begingroup\$

By using the key press signal in an if risingedge check you are treating it as a clock, and making registers for all of the signals inside the if statement that depend on that clock. The key press signal however does not have the perfect clock transitions that you expect, for instance the buttons that drive it have some bounce to them which will trigger multiple executions of the hardware inside the if statement. Also it is very bad practice to use a signal as a clock that is not on the special FPGA clock network.

I understand that you want to perform this key press action once every key press. For this you will need 2 things: something to debounce each individual key press so that each press has a clean on off transition and something to make a pulse for one clock cycle when the debounced key press transitions from on to off.

Here are some resources: Debouncing buttons: https://youtu.be/8ISfNm9zv18 Single clock pulse: https://youtu.be/GHheNH1-S1Y

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Okay, I have watched this videos and they are helpful. So why is it very bad practice to use a signal as a clock that is not on the special FPGA clock network? \$\endgroup\$ – Cody495 Oct 7 '16 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.