---------------------------------------------------------------------------------- -- Company: ETH Zurich, Institute for Particle Physics -- Engineer: Patrick Vogler -- -- Create Date: March 11 2011 -- Design Name: -- Module Name: FTM Timing counter -- Project Name: -- Target Devices: -- Tool versions: -- Description: 48 bit counter for time stamping and on-time counting -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- -- -- modifications: -- -- April 12 2011 by Patrick Vogler -- -- May 18 2011 by Patrick Vogler -- -- May 20, 2011, by Q. Weitzel -- counting was wrong by one clock cycle (1 us) -- -- May 23, 2011, by Q. Weitzel -- counter reset changed from async to sync reset -- reset, enable and read_counter removed from sensitity lists -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.NUMERIC_STD.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; library ftm_definitions; USE ftm_definitions.ftm_array_types.all; USE ftm_definitions.ftm_constants.all; entity Timing_counter is port( -- Clock ------------------------------------------------------------------------------- clk : in STD_LOGIC; -- 50 MHz system clock enable : in STD_LOGIC; -- enable counter reset : in Std_LOGIC; -- reset counter -- handshake signal read_counter : in STD_LOGIC; -- read counter reading_started : out STD_LOGIC; reading_valid : out STD_LOGIC; -- counter reading at output ready -- counter reading counter_reading : out std_logic_vector (TC_WIDTH - 1 downto 0) ); end Timing_counter; architecture Behavioral of Timing_counter is type type_read_counter_state is (IDLE, COPY, SET_VALID, RESET_STARTED); signal read_counter_state : type_read_counter_state := IDLE; signal counting : std_logic_vector (TC_WIDTH - 1 downto 0) := (others => '0'); signal counter_reading_sig : std_logic_vector (TC_WIDTH - 1 downto 0) := (others => '0'); signal precounting : std_logic_vector (PRECOUNT_WIDTH - 1 downto 0) := (others => '0'); begin -- counting ------------------------------------------------------------------------------- count : process (clk) begin if rising_edge(clk) then if (reset = '1') then counting <= (others => '0'); precounting <= (others => '0'); elsif enable = '1' then precounting <= precounting + 1; if (precounting = (PRECOUNT_DIVIDER - 1)) then counting <= counting + 1; precounting <= (others => '0'); end if; end if; end if; end process count; -- read counter ------------------------------------------------------------------------------- readout_counter : process (clk) begin if rising_edge(clk) then case read_counter_state is when IDLE => if read_counter = '1' then reading_valid <= '0'; reading_started <= '1'; read_counter_state <= COPY; end if; when COPY => counter_reading_sig <= counting; read_counter_state <= SET_VALID; when SET_VALID => read_counter_state <= RESET_STARTED; when RESET_STARTED => if read_counter = '0' then reading_started <= '0'; reading_valid <= '1'; read_counter_state <= IDLE; end if; end case; end if; end process readout_counter; counter_reading <= counter_reading_sig; end Behavioral;