Author Topic: creating a blinker for fpga project in vhdl  (Read 1594 times)

0 Members and 1 Guest are viewing this topic.

Offline hekk_techTopic starter

  • Newbie
  • Posts: 1
  • Country: de
creating a blinker for fpga project in vhdl
« on: April 10, 2020, 07:25:56 pm »
Hello everyone I need some tech advice maybe someone is kind enough to help me, "a complete noob", with sharing his/her knowledge and pointing on my mistakes.

What I want to do is to write a simple program in VHDL which will make an led0 blink 3 times if I short-press a button_left and will blink continuously if the button_left is kept pushed.
The same must be valid for a led1 and button_right just like in a signal blinker in a car.
The case when both buttons are simultaneously pressed must be excluded.

If I turn on a switch0 the blinking of led0 must be doubled in speed, the same is for switch1 and led1.

The last thing is the blinking of led0 and led1 must be accompanied with a 1khz tone.

What I have accomplished already is to make buttons blink while they are continuously pressed.
I did it first only with one button, later on I can do the same for the other buttons too.
I also learned today that I need to debounce the buttons, which I did not do yet, but I think I know how to do it.

My biggest problem sofar is to make the led blink 3 times upon a short-press of a button, can someone explain to me how to do it correctly and easy as I am a beginner.
I use a XILINX board NEXYS4DDR with 100MHz clock.
This is what I wrote in VHDL until now:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity blinking_while_pressed is
   Port ( clk : in std_logic;
         button_left : in std_logic:= '1';
         led0: out std_logic);
end blinking_while_pressed;

architecture behavioral of blinking_while_pressed is
signal q: std_logic_vector (26 downto 0);

begin
   process (clk)
      begin
         if(rising_edge (clk)) then
            q <= q + 1;
         end if;
   end process;

led0 <= '1' when q(25) = '1' and button_left = '1' else
                 '0';
end behavioral;

 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9891
  • Country: us
Re: creating a blinker for fpga project in vhdl
« Reply #1 on: April 10, 2020, 07:46:58 pm »
Does your blinking LED work?  If so, you have a proper contraints file and are well along the path.


It seems to me that you are going to wind up with a Finite State Machine
In the Home state you will look for a left or right button press and branch to states Left or Right accordingly.
Once in the Left or Right state, you will blink the appropriate LED (and sound the tone) 3 times (maybe you set a counter when you make the branch to Left or Right) and when the counter runs out, you branch to a Test(Left or Right) and look to see if the switch is still true.  If so, you can set the counter to one and branch back to the appropriate Left or Right state and blink the LED (and tone) one more time before branching back to the Test state and trying again.  If the button is released in the Test state, branch back to the Home state.

Actually blinking the LED or sounding the Tone will probably be a separate process that is started by the FSM and has a Complete signal that can be tested while looping in the Left or Right states.  Be careful that you start the process, see it go busy and then wait for not busy (or Complete, your choice).  This may take another state after for looping on the counter.  Then again, it might be easier to incorporate the blink logic inside the Left or Right states and loop so many times (3 or 1) over the blink loop.  As to the tone, generate 1kHz in a process and gate it with the Blink signals (probably an OR of the Left or Right blink outputs.

Be careful, you can't use an output signal on the right hand side of an expression.  So, you create a signal LeftBlinkInt and manipulate that as required and then you use a statement like LeftBlink <= LeftBlinkInt; to send the output to the actual output port.

You might get some inspiration at vhdlwhiz.com.  There are a number of tutorials written in VHDL.

If you have done any C programming, you can model the behavior with a switch() statement until you get the logic correct and then port the ideas to VHDL.
« Last Edit: April 10, 2020, 07:52:44 pm by rstofer »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9891
  • Country: us
Re: creating a blinker for fpga project in vhdl
« Reply #2 on: April 10, 2020, 09:44:36 pm »
This code synthesizes but I wouldn't bet on it working without some tweaks.  I didn't feel like writing a test bench and my Nexy4DDR is in use on another project.


Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity Blinker is
    Port ( Reset    : in  STD_LOGIC;
           Clk      : in  STD_LOGIC;
           LeftSw   : in  STD_LOGIC;
           RightSw  : in  STD_LOGIC;
           Tone     : out STD_LOGIC;
           LeftLED  : out STD_LOGIC;
           RightLED : out STD_LOGIC);
end Blinker;

architecture Behavioral of Blinker is

constant CounterMax : integer := 3554431; -- 2^25 - 1
signal BlinkCounter : integer range 0 to CounterMax;
signal Blink        : std_logic;
subtype loop_type   is integer range 0 to 3;
signal  LoopCount   : loop_type;
type   FSMtype    is (Home, COuntBlinks);
signal State        : FSMtype;
constant ToneCount  : integer := ((100000000 / 1000) / 2 ) -1;
signal  ToneCounter : integer range 0 to ToneCount;
signal ToneInt      : std_logic;

begin

  Blink    <= '1' when BlinkCounter > ( (CounterMax + 1) / 2 ) else '0';
  LeftLED  <= Blink and LeftSw;
  RightLED <= Blink and RightSw;
  Tone     <= ToneInt;

  FSM : process (clk)
  begin
    if rising_edge(clk) then
      if Reset = '1' then
        BlinkCounter <= 0;
        LoopCOunt    <= 0;
        State        <= Home;
      else
        case (State) is
          when Home        => if (LeftSw or RightSw) = '1' then
                                LoopCount <= 3;
                                BlinkCounter <= CounterMax;
                                State <= CountBlinks;
                              end if;
          when CountBlinks => if BlinkCounter = 0 then
                                if LoopCount = 1 then  -- LoopCount is about to go to 0
                                  if (LeftSw or RightSw) = '0' then -- both switches off
                                    State <= Home;
                                  end if;
                                else
                                  LoopCount <= LoopCount - 1;
                                  BlinkCounter <= CounterMax;
                                end if;
                              else
                                BlinkCounter <= BlinkCounter - 1;
                              end if;
        end case;
      end if;
    end if;
  end process;
 
  TONE_GEN : process(clk)
  begin
    if rising_edge(clk) then
      if Reset = '1' then
        ToneCounter <= 0;
        ToneInt     <= '0';
      else
        if ToneCounter = 0 then
          ToneInt <= not ToneInt;
          ToneCounter <= ToneCount;   
        else
          ToneCounter <= ToneCounter - 1;
        end if;
      end if;
    end if;
  end process;

end Behavioral;

[/font]
« Last Edit: April 10, 2020, 09:50:17 pm by rstofer »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf