 

----------------------------------------------------------------------------------
-- Company: CNRS
-- Engineer: CC
-- 
-- Create Date:    12:12:16 10/11/2016 
-- Design Name: 
-- Module Name:   counters - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: counters & counters reset 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Revision 0.02 - use single cycle PPS, add extend pulse
-- Revision 0.02 - add counter enable signal
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity counters  is
  port
    (
     clk_i 				: in std_logic;
	  clk_ref_i 		: in std_logic;
     rst_i 				: in std_logic;
	  clk_sync_i		: in std_logic;
     busy_trig_i 		: in std_logic;
     event_trig_i 	: in std_logic;
     cnt_en_i			: in std_logic;
	  pps_csync_i 		: in std_logic;
     pps_i			 	: in std_logic;
--	  ack_event_flag_i: in std_logic;
--	  ack_busy_flag_i : in std_logic;
	  tdc_rst_o			: out std_logic;
	  cnt_en_ack_o		: out std_logic;
     ext_trig_o 		: out std_logic;
	  event_flag_o		: out std_logic;
	  busy_flag_o		: out std_logic;
     pps_cnt_o			: out std_logic_vector(15 downto 0);
     busy_cnt_o 		: out std_logic_vector(31 downto 0);
     event_cnt_o 		: out std_logic_vector(31 downto 0);
     clk_cnt_o			: out std_logic_vector(25 downto 0);
	  ---- debug ----
	  TRIG0 				: out std_logic_vector(31 downto 0)
    );
 end counters;
 
   
architecture rtl of counters  is


------- counters----

	----PPS counter
	COMPONENT pps_counter
		 Port (
			clk_i 			: in std_logic;		
			rst_i				: in std_logic;
			pps_i 			: in std_logic;
			--pps_detect_o	: out std_logic;
			pps_cnt_o		: out std_logic_vector(15 downto 0) -- 16bits => 12h 
		 );
	END COMPONENT;
	
	
	COMPONENT event_counter_flag is
    Port (
		clk_i				: in std_logic;
		rst_i				: in std_logic;
		event_i 			: in std_logic;
--		cnt_en_i			: in std_logic;
--		ack_flag_i		: in std_logic;
		flag_o			: out std_logic;
		event_cnt_o		: out std_logic_vector(31 downto 0) 
	 );
	END COMPONENT;
	---

	COMPONENT clk_counter is
    Port (
		clk_i				: in std_logic;
		pps_i				: in std_logic;
		event_i 			: in std_logic;
		event_cnt_o		: out std_logic_vector(25 downto 0) 
	 );
	END COMPONENT;

---------------end counters ----------------


---- reset counters state machine ---------

COMPONENT rst_cnt_fsm is
    Port (
		clk_i				: in std_logic;
		rst_i				: in std_logic;	
		cnt_en_i			: in std_logic;	
		pps_detect_i	: in std_logic;
		cnt_en_o 		: out std_logic;
		cnt_en_ack_o 	: out std_logic;
		tdc_rst_o		: out std_logic;
		ext_trig_o		: out std_logic
	 );
	END COMPONENT;
	
--	component gc_extend_pulse is
--	  generic (
--		 -- output pulse width in clk_i cycles
--		 g_width : natural := 1000
--		 );
--	  port (
--		 clk_i      : in  std_logic;
--		 rst_n_i    : in  std_logic;
--		 -- input pulse (synchronou to clk_i)
--		 pulse_i    : in  std_logic;
--		 -- extended output pulse
--		 extended_o : out std_logic
--		 );
--	end component;
--	
  signal cnt_en_ack, rst_cnt : std_logic;
  signal cnt_en	: std_logic;
  signal pps_wider	: std_logic;
  signal clk_cnt, clk_cnt_buf	: std_logic_vector(25 downto 0);
  signal pps_cnt : std_logic_vector(31 downto 0);		--, pps_cnt_buf
  
  begin 

	rst_cnt 			<= rst_i or (not cnt_en_ack);  
	cnt_en_ack_o	<= cnt_en_ack;
  
	---- PPS counter ------
	U_PPS_cnt : pps_counter
	 port map(
			clk_i	 		 => clk_ref_i,
			rst_i		 	 => rst_cnt,
			pps_i 		 => pps_csync_i,
			pps_cnt_o	 => pps_cnt(15 downto 0) 				-- 16bits => 12h pps_cnt 
			);

		
	---- Event counter -----
	U_event_cnt : event_counter_flag
    port map(
		clk_i			=> clk_i,
		rst_i			=> rst_cnt,
--		ack_flag_i	=> ack_event_flag_i,
		flag_o		=> event_flag_o,
		event_i 		=> event_trig_i,					
		event_cnt_o	=> event_cnt_o  
	 );
	 
	 ---- Busy counter ------
	U_busy_cnt : event_counter_flag
    port map(
		clk_i			=> clk_i,
		rst_i			=> rst_cnt,
--		ack_flag_i	=> ack_busy_flag_i,
		flag_o		=> busy_flag_o,
		event_i 		=> busy_trig_i,					
		event_cnt_o	=> busy_cnt_o   
	 );

	 ---- Clock counter ------
	U_clk_cnt : clk_counter		
    port map(
		clk_i				=> clk_sync_i,			--clk_i,
		pps_i				=> pps_i,
		event_i 			=> clk_sync_i,	
		event_cnt_o		=> clk_cnt  
	 );
  
	 U_rst_cnt_fsm : rst_cnt_fsm
    port map(
		clk_i				=> clk_i,
		rst_i				=> rst_i,
		cnt_en_i			=> cnt_en_i,	
		pps_detect_i	=> pps_i,			--pps_detect,
		cnt_en_o 		=> cnt_en,
		cnt_en_ack_o 	=> cnt_en_ack,
		tdc_rst_o		=> tdc_rst_o,
		ext_trig_o		=> ext_trig_o
	 );
 
   --- hold clock counter value
 sync_clk_cnt_proc: process(clk_i)
		BEGIN	
			if rising_edge(clk_i) then  
				clk_cnt_o  <= clk_cnt;  
			end if;
	 end process;

   --- sync different clock domains		-- use async FIFO ???
 sync_pps_cnt_proc: process(clk_i)
		BEGIN	
			if rising_edge(clk_i) then 
				pps_cnt(31 downto 16)  	<= pps_cnt(15 downto 0); 
				pps_cnt_o  					<= pps_cnt(31 downto 16);  
			end if;
  end process;
	 
	-------- debug  ----------
--	TRIG0(0) <= rst_cnt_n;
--	TRIG0(1) <= rstn_cnt;	
--	TRIG0(2) <= pps_detect;

end rtl;	
