--======================================================================================= -- TITLE : Trigger ID generator -- DESCRIPTION : Generates ID each time a counter happen and increment counter -- FILE : trigger_ID_count.vhd -- COMPANY : Micro-Cameras & Space Exploration SA --======================================================================================= -- CREATION -- DATE AUTHOR PROJECT REVISION -- 23/03/2011 JGi 110323a --======================================================================================= -- MODIFICATION HISTORY -- DATE AUTHOR PROJECT REVISION COMMENTS -- 23/03/2011 JGi 110323a Description --======================================================================================= -- Library Definition library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- Entity Definition entity trigger_ID_count is port( --clock clk_250MHz : in std_logic; --control start_run : in std_logic; stop_run : in std_logic; maj_coinc_n_phys : in std_logic_vector(5 downto 0); maj_coinc_n_calib : in std_logic_vector(5 downto 0); --triggers trigger : in std_logic_vector(8 downto 0); phys_trigger : in std_logic; calib_trigger : in std_logic; internal_trigger : in std_logic_vector(1 downto 0); external_trigger : in std_logic_vector(1 downto 0); --outputs trigger_ID_done : out std_logic; trigger_ID : out std_logic_vector(55 downto 0)); end trigger_ID_count; -- Architecture Definition architecture RTL of trigger_ID_count is type t_reg is record -- Internal register declaration start_run : std_logic; stop_run : std_logic; reset_counter : std_logic; counter : std_logic_vector(31 downto 0); counter_0_done : std_logic; counter_1_done : std_logic_vector(1 downto 0); counter_2_done : std_logic_vector(1 downto 0); counter_3_done : std_logic_vector(1 downto 0); counter_4_done : std_logic_vector(2 downto 0); counter_5_done : std_logic_vector(2 downto 0); counter_6_done : std_logic_vector(2 downto 0); triggers_delay : std_logic_vector(5 downto 0); trigger_type_1 : std_logic_vector(7 downto 0); trigger_type_2 : std_logic_vector(7 downto 0); -- Ouput register declaration trigger_ID_done : std_logic_vector(1 downto 0); trigger_ID : std_logic_vector(55 downto 0); end record; signal i_next_reg : t_reg := (start_run => '0', stop_run => '0', reset_counter => '0', counter => (others => '0'), counter_0_done => '0', counter_1_done => (others => '0'), counter_2_done => (others => '0'), counter_3_done => (others => '0'), counter_4_done => (others => '0'), counter_5_done => (others => '0'), counter_6_done => (others => '0'), triggers_delay => (others => '0'), trigger_type_1 => (others => '0'), trigger_type_2 => (others => '0'), trigger_ID_done => (others => '0'), trigger_ID => (others => '0')); signal i_reg : t_reg := (start_run => '0', stop_run => '0', reset_counter => '0', counter => (others => '0'), counter_0_done => '0', counter_1_done => (others => '0'), counter_2_done => (others => '0'), counter_3_done => (others => '0'), counter_4_done => (others => '0'), counter_5_done => (others => '0'), counter_6_done => (others => '0'), triggers_delay => (others => '0'), trigger_type_1 => (others => '0'), trigger_type_2 => (others => '0'), trigger_ID_done => (others => '0'), trigger_ID => (others => '0')); begin -- Component instantiation -- Combinatorial logic process(start_run, stop_run, trigger, phys_trigger, calib_trigger, internal_trigger, external_trigger, maj_coinc_n_phys, maj_coinc_n_calib, i_reg) variable v_reg : t_reg := (start_run => '0', stop_run => '0', reset_counter => '0', counter => (others => '0'), counter_0_done => '0', counter_1_done => (others => '0'), counter_2_done => (others => '0'), counter_3_done => (others => '0'), counter_4_done => (others => '0'), counter_5_done => (others => '0'), counter_6_done => (others => '0'), triggers_delay => (others => '0'), trigger_type_1 => (others => '0'), trigger_type_2 => (others => '0'), trigger_ID_done => (others => '0'), trigger_ID => (others => '0')); begin v_reg := i_reg; --=================================================================================== --=================================================================================== -- Trigger counter management --=================================================================================== -- Register inputs v_reg.start_run := start_run; v_reg.stop_run := stop_run; -- Reset counter when run is started or stopped v_reg.reset_counter := (start_run and not(i_reg.start_run)) or (stop_run and not(i_reg.stop_run)); -- Reset counter when starting or stopping run if i_reg.reset_counter = '1' then v_reg.counter := (others => '0'); -- Count when trigger is activated -- 32-bits Counter is splitted on 8 4-bits counter with enables else if trigger(0) = '1' then v_reg.counter(3 downto 0) := std_logic_vector(unsigned(i_reg.counter(3 downto 0))+1); end if; if trigger(1) = '1' then if i_reg.counter_0_done = '1' then v_reg.counter(7 downto 4) := std_logic_vector(unsigned(i_reg.counter(7 downto 4))+1); end if; end if; if trigger(2) = '1' then if i_reg.counter_1_done(1) = '1' then v_reg.counter(11 downto 8) := std_logic_vector(unsigned(i_reg.counter(11 downto 8))+1); end if; end if; if trigger(3) = '1' then if i_reg.counter_2_done(1) = '1' then v_reg.counter(15 downto 12) := std_logic_vector(unsigned(i_reg.counter(15 downto 12))+1); end if; end if; if trigger(4) = '1' then if i_reg.counter_3_done(1) = '1' then v_reg.counter(19 downto 16) := std_logic_vector(unsigned(i_reg.counter(19 downto 16))+1); end if; end if; if trigger(5) = '1' then if i_reg.counter_4_done(2) = '1' then v_reg.counter(23 downto 20) := std_logic_vector(unsigned(i_reg.counter(23 downto 20))+1); end if; end if; if trigger(6) = '1' then if i_reg.counter_5_done(2) = '1' then v_reg.counter(27 downto 24) := std_logic_vector(unsigned(i_reg.counter(27 downto 24))+1); end if; end if; if trigger(7) = '1' then if i_reg.counter_6_done(2) = '1' then v_reg.counter(31 downto 28) := std_logic_vector(unsigned(i_reg.counter(31 downto 28))+1); end if; end if; end if; -- Manage splitted counters done signals if i_reg.counter(3 downto 0) = "1111" then v_reg.counter_0_done := '1'; else v_reg.counter_0_done := '0'; end if; if i_reg.counter(7 downto 4) = "1111" then v_reg.counter_1_done(0) := '1'; else v_reg.counter_1_done(0) := '0'; end if; if i_reg.counter(11 downto 8) = "1111" then v_reg.counter_2_done(0) := '1'; else v_reg.counter_2_done(0) := '0'; end if; if i_reg.counter(15 downto 12) = "1111" then v_reg.counter_3_done(0) := '1'; else v_reg.counter_3_done(0) := '0'; end if; if i_reg.counter(19 downto 16) = "1111" then v_reg.counter_4_done(0) := '1'; else v_reg.counter_4_done(0) := '0'; end if; if i_reg.counter(23 downto 20) = "1111" then v_reg.counter_5_done(0) := '1'; else v_reg.counter_5_done(0) := '0'; end if; if i_reg.counter(27 downto 24) = "1111" then v_reg.counter_6_done(0) := '1'; else v_reg.counter_6_done(0) := '0'; end if; -- Enables are splitted to use only 4-bits LUT -- Delay between two trigger is long enough to allow delay on enables v_reg.counter_1_done(1) := i_reg.counter_0_done and i_reg.counter_1_done(0); v_reg.counter_2_done(1) := i_reg.counter_0_done and i_reg.counter_1_done(0) and i_reg.counter_2_done(0); v_reg.counter_3_done(1) := i_reg.counter_0_done and i_reg.counter_1_done(0) and i_reg.counter_2_done(0) and i_reg.counter_3_done(0); v_reg.counter_4_done(1) := i_reg.counter_0_done and i_reg.counter_1_done(0) and i_reg.counter_2_done(0) and i_reg.counter_3_done(0); v_reg.counter_4_done(2) := i_reg.counter_4_done(1) and i_reg.counter_4_done(0); v_reg.counter_5_done(1) := i_reg.counter_0_done and i_reg.counter_1_done(0) and i_reg.counter_2_done(0) and i_reg.counter_3_done(0); v_reg.counter_5_done(2) := i_reg.counter_5_done(1) and i_reg.counter_4_done(0) and i_reg.counter_5_done(0); v_reg.counter_6_done(1) := i_reg.counter_0_done and i_reg.counter_1_done(0) and i_reg.counter_2_done(0) and i_reg.counter_3_done(0); v_reg.counter_6_done(2) := i_reg.counter_6_done(1) and i_reg.counter_4_done(0) and i_reg.counter_5_done(0) and i_reg.counter_6_done(0); --=================================================================================== --=================================================================================== -- Trigger type management --=================================================================================== -- Register trigger types inputs v_reg.triggers_delay(0) := phys_trigger; v_reg.triggers_delay(1) := calib_trigger; v_reg.triggers_delay(2) := internal_trigger(0); v_reg.triggers_delay(3) := internal_trigger(1); v_reg.triggers_delay(4) := external_trigger(0); v_reg.triggers_delay(5) := external_trigger(1); v_reg.trigger_ID_done(0) := '0'; v_reg.trigger_ID_done(1) := i_reg.trigger_ID_done(0); -- If master trigger fires if trigger(8) = '1' then -- Manage trigger ready output v_reg.trigger_ID_done(0) := '1'; -- Manage trigger ID content -- If physics event if i_reg.triggers_delay(0) = '1' then v_reg.trigger_type_1(7 downto 2) := maj_coinc_n_phys; -- If calibration events elsif i_reg.triggers_delay(1) = '1' then v_reg.trigger_type_1(7 downto 2) := maj_coinc_n_calib; else v_reg.trigger_type_1(7 downto 2) := (others => '0'); end if; v_reg.trigger_type_2(7 downto 3) := (others => '0'); -- If not a physics event if i_reg.triggers_delay(0) = '0' then v_reg.trigger_type_1(1 downto 0) := i_reg.triggers_delay(5 downto 4); v_reg.trigger_type_2(2) := i_reg.triggers_delay(3); v_reg.trigger_type_2(1) := i_reg.triggers_delay(2); v_reg.trigger_type_2(0) := i_reg.triggers_delay(1); else v_reg.trigger_type_1(1 downto 0) := (others => '0'); v_reg.trigger_type_2(2 downto 0) := (others => '0'); end if; end if; --=================================================================================== --=================================================================================== -- Trigger ID management --=================================================================================== v_reg.trigger_ID(31 downto 0) := i_reg.counter; v_reg.trigger_ID(39 downto 32) := i_reg.trigger_type_1; v_reg.trigger_ID(47 downto 40) := i_reg.trigger_type_2; v_reg.trigger_ID(55 downto 48) := (others => '0'); --=================================================================================== --=================================================================================== -- Drive register input i_next_reg <= v_reg; --=================================================================================== -- Output assignation trigger_ID_done <= i_reg.trigger_ID_done(1); trigger_ID <= i_reg.trigger_ID; --=================================================================================== end process; -- Sequential logic process(clk_250MHz) begin if rising_edge(clk_250MHz) then i_reg <= i_next_reg; end if; end process; end RTL;