-------------------------------------------------------------------------------
-- Title      : Digital Filter
-------------------------------------------------------------------------------
-- File       : dig_sch_trig.vhd
-- Author     : Pavan Marisetti
-- Company    : Microsemi Corporation
-- Device     : SmartFusion
-- Standard   : VHDL
-------------------------------------------------------------------------------
-- Description: This code implementes the digital filter. The noise around the 
--              rising and falling edges of the tacho signal.
-------------------------------------------------------------------------------
-- Copyright (c) 2011   Microsemi Corporation
--                      All rights reserved.
-------------------------------------------------------------------------------
-- Revisions  : V1.0
-------------------------------------------------------------------------------

library ieee;
library std;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity dig_sch_trig is
	port (	PRESETN              : IN STD_LOGIC;
		    PCLK                 : IN STD_LOGIC;
		    Tach_input           : IN STD_LOGIC;
		    Tach_input_sc_trig   : OUT STD_LOGIC
        );
end dig_sch_trig;

architecture dig_sch_trig of dig_sch_trig is
    
    signal Tach_input_sync, Tach_input_sync1, Tach_input_sync2 : std_logic;
	signal raise_count : std_logic_vector(8 downto 0);
	signal count_enable      : std_logic;
    type   sch_trig_fsm is (idle, high1,high2,low1);
  	signal sch_trig_current_state : sch_trig_fsm ;

 
 begin

    tach_ip_sync_proc: process(PCLK, PRESETN)
      begin
        if(PRESETN = '0' ) then
          Tach_input_sync <= '0';
          Tach_input_sync1 <= '0';
          Tach_input_sync2 <= '0';
        elsif(PCLK = '1' and PCLK'event) then
           Tach_input_sync  <= Tach_input;
           Tach_input_sync1 <= Tach_input_sync;
           Tach_input_sync2 <= Tach_input_sync1;
        end if;
    end process; 

	dig_sch_trig_process: process (PCLK, PRESETN)
		begin
			if (PRESETN = '0')  then
				sch_trig_current_state <= idle;		
                Tach_input_sc_trig <= '0';
                count_enable <= '0';				
            elsif (PCLK = '1' and PCLK'event) then   
   			  case sch_trig_current_state is					
				when idle =>

                  if(Tach_input_sync1 = '1' and Tach_input_sync2 = '0') then
                    count_enable <= '1';
                    sch_trig_current_state <= high1;               	
			      else
                    sch_trig_current_state <= idle;
                     count_enable <= '0';
				  end if;

                when high1 =>
                  if(Tach_input_sync1 = '0' and Tach_input_sync2 = '1') then
                    count_enable <= '0';
                    sch_trig_current_state <= idle;
                  elsif(raise_count = "111110100") then
                    sch_trig_current_state <= high2;
                    count_enable <= '0';
                    Tach_input_sc_trig <= '1';
                  else 
                    sch_trig_current_state <= high1;
                  end if;

                when high2 =>
                  if(Tach_input_sync1 = '0' and Tach_input_sync2 = '1') then
                    count_enable <= '1';
                    sch_trig_current_state <= low1;   
			      else
                    sch_trig_current_state <= high2;
                  end if;
                when low1 =>
                  if(Tach_input_sync1 = '1' and Tach_input_sync2 = '0') then
                    sch_trig_current_state <= high2;
                    count_enable <= '0';
                  elsif(raise_count = "111110100") then
                    sch_trig_current_state <= idle;
                    count_enable <= '0';
                    Tach_input_sc_trig <= '0';	
                  else
                    sch_trig_current_state <= low1;
                  end if;
                end case;
			end if;
      end process;

counter_proc: process(PCLK,PRESETN)
   begin
      if(PRESETN = '0') then
         raise_count <= "000000000";
      elsif(PCLK = '1' and PCLK'event) then
         if(count_enable = '1') then
           raise_count <= raise_count + 1;
         else
           raise_count <= "000000000";
         end if;
      end if;
end process;


end dig_sch_trig;