LIBRARY ieee;
USE ieee.std_logic_1164. all;
USE ieee.numeric_std.all;
 
ENTITY event_trigger_generator IS
	GENERIC (
		INT_GEN	:	BOOLEAN	:=	FALSE
	);

	PORT (
    TBCLK		: 	IN std_logic;
	 
	 CTRU_CMPA	:	IN std_logic;
	 CTRD_CMPA	:	IN std_logic;	 
	 CTRU_CMPB	:	IN std_logic;
	 CTRD_CMPB	:	IN std_logic;	 
	 CTR_zero	:  IN std_logic;
	 CTR_prd 	:  IN std_logic;
	 
	 ETSEL		:	IN std_logic_vector(2 DOWNTO 0);
	 ETFRC		:	IN	std_logic;
	 ETPS			:	IN std_logic_vector(1 DOWNTO 0);
	 ETSEN		:	IN	std_logic;
	 ETCLR		:	IN	std_logic;
	 
	 ETCNT		:	OUT std_logic_vector(1 DOWNTO 0);
	 
	 OUTPUT		:	OUT std_logic;
	 ETFLG		:	OUT std_logic
	);
END event_trigger_generator;
 

ARCHITECTURE Behavioral OF event_trigger_generator IS
	
	SIGNAL INPUT			:	std_logic := '0';
	SIGNAL SIG				:	std_logic := '0';
	SIGNAL GEN_E			:	std_logic := '0';
	SIGNAL CNT_OUT			:	std_logic := '0';
	
	SIGNAL PULSE_OUT		:  std_logic := '0';
	SIGNAL iETFLG           :  std_logic := '0';
BEGIN


	-- source signal select
	
	PROCESS (ETSEL, CTR_zero, CTR_prd, CTRU_CMPA, CTRD_CMPA, CTRU_CMPB, CTRD_CMPB) IS
	BEGIN
		CASE ETSEL IS		
			WHEN "000" => 	INPUT <= '0';								
			WHEN "001" => 	INPUT <= CTR_zero;								
			WHEN "010" => 	INPUT <= CTR_prd;
			WHEN "011" => 	INPUT <= '0';
			WHEN "100" =>	INPUT <= CTRU_CMPA;
			WHEN "101" =>	INPUT <= CTRD_CMPA;
			WHEN "110" =>	INPUT <= CTRU_CMPB;	
			WHEN "111" =>	INPUT <= CTRD_CMPB;
			WHEN OTHERS => NULL;	
		END CASE;	
	END PROCESS;
	
	SIG <= INPUT WHEN ETFRC = '1' ELSE '0';
	
	
	PROCESS (SIG)
		VARIABLE cnt : unsigned(1 DOWNTO 0) := (OTHERS => '0');
	BEGIN
		IF rising_edge(SIG) THEN
			IF (PULSE_OUT = '1') THEN
				cnt := (OTHERS => '0');
				CNT_OUT <= '0';		
			ELSIF(cnt = unsigned(ETPS)) THEN
				IF(ETSEN = '1') THEN
					CNT_OUT <= '1';
				END IF;
			ELSE
				cnt := cnt + 1;
				CNT_OUT <= '0';
			END IF;
		END IF;
		ETCNT <= std_logic_vector(cnt);
	END PROCESS;
	
	INTERRUPT_SIG: IF INT_GEN = TRUE GENERATE
		GEN_E <= CNT_OUT WHEN iETFLG = '0' ELSE '0';
	END GENERATE INTERRUPT_SIG;

	EVENT_SIG: IF INT_GEN = FALSE GENERATE
		GEN_E <= CNT_OUT;
	END GENERATE EVENT_SIG;
	
	PROCESS (TBCLK)
		VARIABLE cnt : unsigned(5 DOWNTO 0) := (OTHERS => '0');
	BEGIN
		IF rising_edge(TBCLK) THEN
			IF (GEN_E = '1') THEN
				cnt := (OTHERS => '0');
				PULSE_OUT <= '1';
			ELSIF (cnt = "111") THEN
				PULSE_OUT <= '0';
			ELSE				
				cnt := cnt + 1;
				PULSE_OUT <= '1';
			END IF;
		END IF;
	END PROCESS;
	
	ETFLG <= '0' WHEN ETCLR = '1'ELSE iETFLG;

	INTERRUPT_OUT: IF INT_GEN = TRUE GENERATE
		OUTPUT <= NOT PULSE_OUT;
	END GENERATE INTERRUPT_OUT;

	EVENT_OUT: IF INT_GEN = FALSE GENERATE
		OUTPUT <= PULSE_OUT;
	END GENERATE EVENT_OUT;	
	
END Behavioral;