Monday, 19 June 2017

VHDL debounce FSM finite state machine design circuit implementation and code and files Xilinx spartan 3


FILES DOWNLOAD

 library ieee;  
 use ieee.std_logic_1164.all;  
 use ieee.numeric_std.all;  
 entity debounce_test is  
 --Verification circuit for a debouncing circuit  
 port (  
 clk: in std_logic;  
 btn: in std_logic_vector (3 downto 0) ;  
 an: out std_logic_vector ( 3 downto 0) ;  
 sseg: out std_logic_vector (7 downto 0)  
 ) ;  
 end debounce_test ;  
 architecture arch of debounce_test is  
 signal q1_reg , q1_next : unsigned ( 7 downto 0) ;  
 signal q0_reg, q0_next : unsigned ( 7 downto 0) ;  
 signal b_count , d_count : std_logic_vector (7 downto 0 ) ;  
 signal btn_reg : std_logic;  
 signal db_tick , btn_tick , clr : std_logic;  
 begin  
 -- in s t a n t i a t e d e b o u n c in g c i r c u i t  
 db_unit : entity work.debounce(exp_fsmd_arch)  
 port map(  
 clk=>clk, reset=>'0', sw=>btn(1) ,  
 db_level=> open , db_tick=>db_tick  
 );  
 --in s t a n t i a t e h e x d is p l a y t i m e -mu1 t i p l x in g c i r c u i t  
 disp_unit : entity work.disp_hex_mux  
 port map(  
 clk=>clk , reset=>'0',  
 hex3=>b_count (7 downto 4), hex2=>b_count (3 downto 0 ) ,  
 hex1=>d_count ( 7 downto 4), hex0=>d_count ( 3 downto 0 ) ,  
 dp_in=>"1011", an=>an, sseg=>sseg  
 );  
 process(clk)  
 begin  
 if (clk'event and clk='1' ) then  
 btn_reg <= btn(1);  
 end if ;  
 end process ;  
 btn_tick <= (not btn_reg) and btn(1);  
 -- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  
 -- t w o c o u n t e r s  
 clr <= btn(0);  
 --. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  
 process (clk)  
 begin  
 if (clk'event and clk='1' ) then  
 q1_reg <= q1_next;  
 q0_reg <= q0_next;  
 end if ;  
 end process ;  
 -- n e x t - s t a t e logic f o r t h e c o u n t e r  
 q1_next <= ( others => '0' ) when clr='1' else  
 q1_reg + 1 when btn_tick='1' else  
 q1_reg ;  
 q0_next <= ( others => '0' ) when clr='1' else  
 q0_reg + 1 when db_tick='1' else  
 q0_reg;  
 --c o u n t e r o u t p u t  
 b_count <= std_logic_vector(q1_reg);-- input that can be fake  
 d_count <= std_logic_vector(q0_reg);-- real input  
 end arch;  

 library ieee;  
 use ieee.std_logic_1164.all;  
 use ieee.numeric_std.all;  
 entity debounce is  
 port(  
 clk,reset : in std_logic;  
 sw:in std_logic;  
 db_level, db_tick: out std_logic  
 );  
 end debounce ;  
 architecture exp_fsmd_arch of debounce is--20ms is typically used to debounce --666.7hz  
 constant N : integer := 5; -- f i l t e r of (2 ^ N) * 1.49 ms = 40ms debounce interval -------1.49ms is the period of my clock with frequency 666.7 ----1/666.7=1.49ms (2^X) * 1.49ms =40ms ----2^X = 40ms/1.49ms--- 2^X= 27.97----- log2 (27.97)= X --- X= 4.80--- 2^5 * 1.49ms= 40ms   
 type state_type is ( zero , wait0 , one , wait1); --the signals below we create can have 4 states  
 signal state_reg , state_next : state_type;  -- these signals  
 signal q_reg , q_next : unsigned ( N-1 downto 0 ) ;   
 signal q_load , q_dec , q_zero : std_logic ; --we use these signals as markers to go to the next stage in the design  
 begin  
 -- FSMD s t a t e C? d a t a r e g is t e r s  
 process (clk ,reset)  
 begin  
 if reset = '1' then -- if we reset we clear everything and wait for inputs  
 state_reg <= zero ; -- this is the state of the input  
 q_reg <= ( others => '0' ) ; --this is the state of the design which will progress depending of what happens with the input   
 elsif( clk'event and clk = '1' ) then --if rising edge of the clock   
 state_reg <= state_next ; -- state_next which is the signal that will be changing goes to the signal that wont change for the moment and that will be used for display until updated   
 q_reg <= q_next ; -- we update state of the design in q reg (nosrmally anything that is _next is the one that changes and stored in the one that doesnt change)  
 end if ;  
 end process ;  
 -- FSMD d a t a p a t h ( c o u n t e r ) n e x t - s t a t e  
 q_next<= (others => '1') when q_load = '1' else ---we decremetnt the states of the FSM if conditions met  
 q_reg - 1 when q_dec = '1' else  
 q_reg ;  
 q_zero<= '1' when q_next = 0 else '0' ;  
 --FSMD c o n t r o l p a t h n e x t - s t a t e  
 process ( state_reg ,sw,q_zero)  
 begin  
 q_load <= '0' ; --load the value of actual voltage state  
 q_dec <= '0' ; --decrement states  
 db_tick <= '0' ;-- if there has been a debounce 1  
 state_next <= state_reg ;  
 case state_reg is  
 --from 0 to 1  
 when zero => -- when is a 0   
                     db_level <= '0' ; --voltage level is 0 transition to 1 below  
                     if ( sw = '1') then -- if there is an input   
                               state_next <= wait1; --wait some time until 1 hs been there for a while   
                               q_load <= '1'; --load a 1  
                     end if ;  
 when wait1=>  
                     db_level <= '0' ; -- voltage level 0 as there has not been a real input  
                     if ( sw = '1' ) then  
                               q_dec <= '1';   -- decrement states  
                               if ( q_zero = '1' ) then    
                                    state_next <= one ;  
                                    db_tick <= '1'; -- debounced   
                               end if ;  
                          else -- sw = '0'  
                          state_next<= zero ; -- --REMAIN AS 0  
                     end if ;  
 -- from 1 to 0  
 when one =>  --transition from 1 to 0  
                     db_level <= '1'; -- if voltage level is 1 then wait until 0 is confirmed  
                     if ( sw = '0' ) then  
                          state_next <= wait0 ;  
                          q_load <= '1';  
                     end if ;  
 when wait0 =>  
                     db_level <= '1'; -- voltage level set as 1 as input has been stable for a while  
                     if ( sw = '0' ) then  
                          q_dec <= '1';       
                          if( q_zero = '1' ) then  
                               state_next<= zero ;  
                          end if ;  
                      else   
                      state_next<= one ;  
                     end if ;  
 end case ;  
 end process ;  
 end exp_fsmd_arch ;  


 library ieee;  
 use ieee.std_logic_1164.all;  
 use ieee.numeric_std.all ;  
 entity disp_hex_mux is  
 port(  
 clk, reset: in std_logic;  
 hex3, hex2, hex1 ,hex0 : in std_logic_vector (3 downto 0 ) ;  
 dp_in : in std_logic_vector (3 downto 0) ;  
 an: out std_logic_vector (3 downto 0) ;  
 sseg : out std_logic_vector ( 7 downto 0)  
 );  
 end disp_hex_mux ;  
 architecture arch of disp_hex_mux is  
 -- each 7 - s e g l e d enabled ( 2 ^ 3 / 4 ) * 2 . 5 n s   
 constant N: integer :=3;-- time we want the display to hold on visible  
 signal q_reg , q_next : unsigned (N-1 downto 0) ;  
 signal sel : std_logic_vector (1 downto 0) ;  
 signal hex: std_logic_vector (3 downto 0) ;  
 signal dp: std_logic;  
 begin  
 -- register to switch between cathodes  
 process (clk , reset)  
 begin  
 if reset='1' then  
 q_reg <= ( others => '0' ) ;  
 elsif (clk'event and clk='1') then  
 q_reg <= q_next;  
 end if ;  
 end process;  
 -- n e x t - s t a t e l o g i c for t h e c o u n t e r  
 q_next <= q_reg + 1 ;  
 -- 2 MSBs o f c o u n t e r t o c o n t r o l 4 - t o - l m u l t i p l e x in g  
 sel <= std_logic_vector (q_reg(N-1 downto N-2)) ;  
 process (sel , hex0 , hex1 , hex2, hex3, dp_in)  
 begin --seven segment display multiplexed  
 case sel is  
 when "00" =>  
 an <= "0001" ;  
 hex <= hex0;  
 dp <= dp_in(0);  
 when "01" =>  
 an <= "0010" ;  
 hex <= hex1;  
 dp <= dp_in(1);  
 when "10" =>  
 an <= "0100" ;  
 hex <= hex2;  
 dp <= dp_in(2);  
 when others =>  
 an <= "1000" ;  
 hex <= hex3;  
 dp <= dp_in(3);  
 end case ;  
 end process;  
 --hex - t o - 7- s e g in e IZ t I e d decoding  
 -- Use a with-select statement to light up relevant LEDs   
      -------------------------------------------------  
      -- Encoder   
      -------------------------------------------------  
      -- HEX-to-seven-segment decoder   
      -- segment encoding   
      --   0   
      --   ---   
      -- 5 |  | 1  
      --   --- <------6  
      -- 4 |  | 2  
      --   ---   
      --   3  
 with hex select --6542130  
 sseg(6 downto 0)<=  
                               "1111001" when "0000",--0  
                               "0100100" when "0001",--1  
                               "0101000" when "0010",--2  
                               "0100100" when "0011",--3  
                               "0011001" when "0100",--4  
                               "0010010" when "0101",--5  
                               "0000010" when "0110",--6  
                               "1111000" when "0111",--7  
                               "0000000" when "1000",--8  
                               "0010000" when "1001",--9  
                               "0001000" when "1010",--a  
                               "0000011" when "1011",--b  
                               "1000110" when "1100",--c  
                               "0100001" when "1101",--d  
                               "0000110" when "1110",--e  
                               "0001110"  when others;--f  

 --d e c i m a l p o in t  
 sseg(7) <= dp;  
 end arch;  

 NET "clk" LOC = "P54" ;  
 #8I/Os_2 (Input)  
 NET "btn[0]" LOC = "p94" ;  
 NET "btn[1]" LOC = "p93" ;  
 NET "btn[2]" LOC = "p92" ;  
 NET "btn[3]" LOC = "p91" ;  
 #8I/Os_2 (Input)  
 NET "an[0]" LOC = "p71" ;  
 NET "an[1]" LOC = "p75" ;  
 NET "an[2]" LOC = "p77" ;  
 NET "an[3]" LOC = "p82" ;  
 #16I/Os_2  
 NET "sseg[7]" LOC = "p60"  ;  
 NET "sseg[6]" LOC = "p63"  ;  
 NET "sseg[5]" LOC = "p67" ;  
 NET "sseg[4]" LOC ="p70"  ;  
 NET "sseg[3]" LOC ="p74" ;  
 NET "sseg[2]" LOC = "p76" ;  
 NET "sseg[1]" LOC = "p81"  ;  
 NET "sseg[0]" LOC = "p83" ;  


TUTORIAL ON HOW TO ADD CLOCK TIMING CONSTRAINTS IN A MODULE

No comments:

Post a Comment