Translate

Friday, December 21, 2012

Blinking a LED at different intervals




       Hello and welcome to today's post. Now that we have some background in VHDL and different I/O ports of a FPGA I was thinking of doing a small circuit that might come in handy: I want to make a LED blink at a frequency and when I push a button I want that frequency to change and so on. 4 frequencies should suffice.
       The 4 frequencies that I want to use are:
       -  1 HZ (1 second)
       -  2 HZ (0.5 seconds)
       -  5 HZ (0.2 seconds)
       -  10 HZ (0.1 seconds)
       From this it is clear that we will need 4 clock dividers in order to generate the 4 frequencies. A circuit to distribute those frequencies is needed also. O course this will be a 4 to 1 multiplexer.
       Now what should be used for the selections of the mux? I already said that I want the frequency to change when I push a button so how could a button generate a 2 bit value? Very simple: first we connect a debouncing circuit to the button. If you don't know what that is please visit my post: Debouncing push buttons where you will find the code for this circuit. Also the clock divider has been covered in: Synchronization in sequential circuits (clock dividers). Now that the button is debounced, we need a counter that counts from 0 to 3 (the 2 bit combinations needed to select the multiplexer's inputs). Theory about counter circuits can be found at: A simple counter. The code used for the counter is a little different in this example so I will give he code here, don't use the counter in the A simple counter post.
       Ok. Now we only need a simple circuit that drives the LED. When a clk period has passed the value will be inverted.
       The final circuit will look like this (click on the picture to see it at it's full size):
     
       Now for the code. Most of the circuits you already have. I have covered multiplexers in one of my earlier posts: Concurrent statements. Implement a 4 to 1 mux using the with...select statement presented at the end of the post.

       The code for the counter:
              library IEEE;
              use IEEE.STD_LOGIC_1164.ALL;
              use IEEE.std_logic_unsigned.ALL;

              entity counter is
              Port ( clk : in STD_LOGIC;
                 reset : in STD_LOGIC;
                 sel : out STD_LOGIC_VECTOR (1 downto 0));
              end counter;

              architecture Behavioral of counter is
                 signal cnt:std_logic_vector(1 downto 0);
              begin

                 sel<=cnt;
                 process(clk,reset)
                 begin
                    if(reset='1') then
                       cnt<=(others=>'0');
                    elsif(clk'event and clk='1') then
                       if(cnt=3) then
                         cnt<=(others=>'0');
                       else
                          cnt<=cnt+1;
                       end if;
                    end if;
                 end process;
              end Behavioral;


       The code for the LED driver is:

              library IEEE;
              use IEEE.STD_LOGIC_1164.ALL;

              entity led_driver is
              Port ( clk : in STD_LOGIC;
                 led : out STD_LOGIC;
                 reset : in STD_LOGIC);
              end led_driver;

              architecture Behavioral of led_driver is
                 signal ledsig:std_logic;
              begin
                 led<=ledsig;
                 process(clk)
                 begin
                    if(clk'event and clk='1') then
                       if(reset='1') then
                          ledsig<='0';
                       else
                          ledsig<=not ledsig;
                       end if;
                    end if;
                 end process;
              end Behavioral;

       Now the primary circuit is just a structural description uniting these other circuits. I will leave you to make the code. Th entity should look like this:

     
              entity blinking_led is
              Port ( clk : in STD_LOGIC;
                 reset : in STD_LOGIC;
                 button : in STD_LOGIC;
                 led : out STD_LOGIC);
              end blinking_led;


       Thank you for reading. If you have any questions please email me at: fpgatutorials@gmail.com

No comments:

Post a Comment