--Michael Romkey
--993845110
--Shaun Coghlan
--991528410
--November 25, 2001
--VHDL Code for Bouncing Ball Timer

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity counter is
    port( clk: in std_logic;                                                                                --This is a square wave input
            Pressure_Sense, Ball_Release: in std_logic;                                        --These are the inputs from the external devices
                                                                                                                     --they indicate the state
            reset: in std_logic;                                                                              --Resets the values and puts the system in an idle state
            Solenoid: out std_logic; 
            Output_ds, Output_cs, Output_ms: out std_logic_vector(3 downto 0) --The Time outputs
           ); 
end counter;

architecture start of counter is

    type State_type is(idle, counting, display);             --setup of the different states
    signal state: State_type;                                         --this allows for the idle state to do the calculations.
                                                                                --signals for the counting
    signal Count_ds, Count_cs, Count_ms: std_logic_vector(3 downto 0);

begin
    process(clk)
    begin
        if clk'event and clk='1' then
            case state is
                when idle => 
                    if reset ='1' then                                 --Resets the values and puts the system in an idle state
                        state <= idle;
                        Solenoid <= '0'; 
                        Count_ds <= "0000";
                        Count_cs <= "0000";
                        Count_ms <= "0000"; 
                    elsif Ball_Release = '1' then             --this is the case where the ball is dropped by the Solenoid. 
                        Solenoid <= '1';
                        state <= counting;
                   end if; 
                when counting=>
                    if reset ='1' then                                 --Resets the values and puts the system in an idle state
                        state <= idle;
                        Solenoid <= '0';
                        Count_ds <= "0000";
                        Count_cs <= "0000";
                        Count_ms <= "0000"; 
                    else
                        if Pressure_Sense = '0' then             --this is the case when the ball is in flight and the system is counting 
                            if Count_cs = "1001" then           --when Count_cs - 10, rest Count_ms and Count_cs to zero and add one to Count_ds
                                Count_ds <= Count_ds + '1';
                                Count_cs <= "0000";
                                Count_ms <= "0000";
                            elsif Count_ms = "1001" then        --when Count_ms - 10, rest Count_ms add one to Count_cs
                                Count_cs <= Count_cs + '1';
                                Count_ms <= "0000";
                           else
                                Count_ms <= Count_ms + '1'; --add one to Count_ms
                           end if;
                        elsif Pressure_Sense = '1' then             --This is the case where the ball has hit the Pressure Pad.
                            state <= display;
                        end if;
                    end if; 
                when display =>
                    if reset ='1' then             --Resets the values and puts the system in an idle state
                        state <= idle;
                        Solenoid <= '0';
                        Count_ds <= "0000";
                        Count_cs <= "0000";
                        Count_ms <= "0000";
                        Output_ds <= "0000";
                        Output_cs <= "0000";
                        Output_ms <= "0000"; 
                    else
                        --display time on the seven segment displays
                        Output_ds <= Count_ds;
                        Output_cs <= Count_cs;
                        Output_ms <= Count_ms;
                    end if;
                when others => 
                    state<=idle; 
                end case;
            end if;
        end process;
end start;