creating a blinker for fpga project in vhdl - Page 1
Forum section: electronics / beginners

author: hekk_tech
author_rank: Newbie
timestamp: April 10, 2020, 07:25:56 pm
content: 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 isPort ( clk : in std_logic;button_left : in std_logic:= '1';led0: out std_logic);end blinking_while_pressed;architecture behavioral of blinking_while_pressed issignal q: std_logic_vector (26 downto 0);beginprocess (clk)beginif(rising_edge (clk)) thenq <= q + 1;end if;end process;led0 <= '1' when q(25) = '1' and button_left = '1' else'0';end behavioral;

author: rstofer
author_rank: Super Contributor
timestamp: April 10, 2020, 07:46:58 pm
content: 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 MachineIn 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.

author: rstofer
author_rank: Super Contributor
timestamp: April 10, 2020, 09:44:36 pm
content: 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:library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.NUMERIC_STD.ALL;entity Blinker isPort ( 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 isconstant CounterMax : integer := 3554431; -- 2^25 - 1signal 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;beginBlink <= '1' when BlinkCounter > ( (CounterMax + 1) / 2 ) else '0';LeftLED <= Blink and LeftSw;RightLED <= Blink and RightSw;Tone <= ToneInt;FSM : process (clk)beginif rising_edge(clk) thenif Reset = '1' thenBlinkCounter <= 0;LoopCOunt <= 0;State <= Home;elsecase (State) iswhen Home => if (LeftSw or RightSw) = '1' thenLoopCount <= 3;BlinkCounter <= CounterMax;State <= CountBlinks;end if;when CountBlinks => if BlinkCounter = 0 thenif LoopCount = 1 then -- LoopCount is about to go to 0if (LeftSw or RightSw) = '0' then -- both switches offState <= Home;end if;elseLoopCount <= LoopCount - 1;BlinkCounter <= CounterMax;end if;elseBlinkCounter <= BlinkCounter - 1;end if;end case;end if;end if;end process;TONE_GEN : process(clk)beginif rising_edge(clk) thenif Reset = '1' thenToneCounter <= 0;ToneInt <= '0';elseif ToneCounter = 0 thenToneInt <= not ToneInt;ToneCounter <= ToneCount;elseToneCounter <= ToneCounter - 1;end if;end if;end if;end process;end Behavioral;