From fd6771c95128faaf216745ad314d6076f5305e7e Mon Sep 17 00:00:00 2001 From: palka Date: Thu, 6 Aug 2009 18:33:35 +0000 Subject: [PATCH] new --- tdc_interfacev2.vhd | 887 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 887 insertions(+) create mode 100644 tdc_interfacev2.vhd diff --git a/tdc_interfacev2.vhd b/tdc_interfacev2.vhd new file mode 100644 index 0000000..bf55eb1 --- /dev/null +++ b/tdc_interfacev2.vhd @@ -0,0 +1,887 @@ +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; +library UNISIM; +use UNISIM.VComponents.all; +entity tdc_interfacev2 is + generic ( + ENABLE_DMA : positive; + NUMBER_OFF_ADD_DATA : natural; + TRBV2_TYPE : natural + ); + port ( + CLK : in std_logic; + TDC_CLK : in std_logic; -- for input clock should be + -- through clock buffer + RESET : in std_logic; + TDC_DATA_IN : in std_logic_vector (31 downto 0); + --data from TDC + START_TDC_READOUT : in std_logic; + --signal from rpc_trb_v2_fpga - trigger has arrived,one pulse (40MHz long) + --or 100MHz long - but make 25 ns from this !!! + A_TDC_READY : in std_logic; + B_TDC_READY : in std_logic; + C_TDC_READY : in std_logic; + D_TDC_READY : in std_logic; + A_TDC_ERROR : in std_logic; + B_TDC_ERROR : in std_logic; + C_TDC_ERROR : in std_logic; + D_TDC_ERROR : in std_logic; + SEND_TDC_TOKEN : out std_logic; + RECEIVED_TDC_TOKEN : in std_logic; + GET_TDC_DATA : out std_logic; --Signal to TDC chip + +--TDC state mechines has to cut data +--but this should be in FIFO entity and should goes to tdc_interfacev2.vhd ( +--to stop writing to fifo just finish read out) +--copyt to internal FIFO + + --add checking of reference time and checking the difference (<= 3) + + --add mem busy + + LVL2_READOUT_COMPLETED : out std_logic; + LVL1_TAG : in std_logic_vector(15 downto 0); + LVL1_RND_CODE : in std_logic_vector(7 downto 0); + LVL1_CODE : in std_logic_vector(3 downto 0); + LVL2_TAG : in std_logic_vector(7 downto 0); + HOW_MANY_ADD_DATA : in std_logic_vector(7 downto 0); + ADDITIONAL_DATA : in std_logic_vector(NUMBER_OFF_ADD_DATA*32-1 downto 0); + LVL2_TRIGGER : in std_logic;--_vector(1 downto 0); + TDC_DATA_OUT : out std_logic_vector (31 downto 0); --data to ETRAX (LVL2) + TDC_DATA_VALID : out std_logic; -- The TDC_DATA_OUT can be written + ETRAX_IS_READY_TO_READ : in std_logic; + ETRAX_IS_BUSY : in std_logic; + LVL1_BUSY : out std_logic; + LVL2_BUSY : out std_logic; + TDC_REGISTER_00 : out std_logic_vector(31 downto 0); + TDC_REGISTER_01 : out std_logic_vector(31 downto 0); + TDC_REGISTER_02 : out std_logic_vector(31 downto 0); + TDC_REGISTER_03 : out std_logic_vector(31 downto 0); + TDC_REGISTER_04 : out std_logic_vector(31 downto 0); + TDC_REGISTER_05 : in std_logic_vector(31 downto 0); + BUNCH_RESET : out std_logic; + EVENT_RESET : out std_logic; + DELAY_TRIGGER : in std_logic_vector(7 downto 0); + DELAY_TOKEN : in std_logic_vector(7 downto 0); + TDC_START : out std_logic; + TRIGGER_WITH_GEN_EN : in std_logic; + TRIGGER_WITH_GEN : in std_logic; + TRB_ID : in std_logic_vector(31 downto 0); + LVL1_FINISHED : out std_logic; + LVL2_FINISHED : out std_logic; + TRBNET_HEADER_BUILD : in std_logic + ); +end tdc_interfacev2; + +architecture tdc_interfacev2 of tdc_interfacev2 is + + component header_add_data_fifo_4kW + port ( + din : IN std_logic_VECTOR(33 downto 0); + rd_clk : IN std_logic; + rd_en : IN std_logic; + rst : IN std_logic; + wr_clk : IN std_logic; + wr_en : IN std_logic; + dout : OUT std_logic_VECTOR(33 downto 0); + empty : OUT std_logic; + full : OUT std_logic; + rd_data_count : OUT std_logic_VECTOR(11 downto 0); + wr_data_count : OUT std_logic_VECTOR(11 downto 0)); + end component; + + component lvl1_buffer_32kW + port ( + din : IN std_logic_VECTOR(33 downto 0); + rd_clk : IN std_logic; + rd_en : IN std_logic; + rst : IN std_logic; + wr_clk : IN std_logic; + wr_en : IN std_logic; + dout : OUT std_logic_VECTOR(33 downto 0); + empty : OUT std_logic; + full : OUT std_logic; + rd_data_count : OUT std_logic_VECTOR(14 downto 0); + wr_data_count : OUT std_logic_VECTOR(14 downto 0)); + end component; + + component up_down_counter + generic ( + NUMBER_OF_BITS : positive); + port ( + CLK : in std_logic; + RESET : in std_logic; + COUNT_OUT : out std_logic_vector(NUMBER_OF_BITS-1 downto 0); + UP_IN : in std_logic; + DOWN_IN : in std_logic); + end component; + + component edge_to_pulse + port ( + clock : in std_logic; + en_clk : in std_logic; + signal_in : in std_logic; + pulse : out std_logic); + end component; + + signal tdc_ready : std_logic; + signal add_data_counter : std_logic_vector(7 downto 0):=(others => '0'); + signal add_data_pulse : std_logic; + signal first_header : std_logic_vector(31 downto 0):=(others => '0'); + signal second_header : std_logic_vector(31 downto 0):=(others => '0'); + signal words_in_event : std_logic_vector(15 downto 0):=(others => '0'); + signal tdc_data_valid_i : std_logic; + + --signals to delay trigger + signal delay_up : std_logic; + signal delay_clr : std_logic; + signal delay_qout : std_logic_vector(7 downto 0); + signal lvl1_trigger_pulse_start : std_logic; + signal lvl1_trigger_pulse_delay : std_logic; + type DELAY_FSM_TRIGG is + (IDLE ,DELAY_1,DELAY_2); + signal delay_fsm_currentstate, delay_fsm_nextstate: DELAY_FSM_TRIGG; + + + --lvl1 + type LVL1_START_FSM is + (IDLE, WAIT_BEFORE_TRIGG, SEND_TRIGGER, WAIT_BEFORE_TOKEN, WAIT_FOR_TOKEN,SEND_AND_WAIT_FOR_TOKEN,SAVE_DATA_MARKER,SAVE_EB_HEADER_1,SAVE_EB_HEADER_2,SAVE_EB_HEADER_3,SAVE_EB_HEADER_4,SAVE_HEADER_1,SAVE_HEADER_2,SAVE_TRBNET_HEADER_1,SAVE_TRBNET_HEADER_2,SAVE_ADD_DATA,SAVE_HEADER_MARKER); + signal LVL1_START_fsm_currentstate, LVL1_START_fsm_nextstate : LVL1_START_FSM; + signal lvl1_busy_i : std_logic; + signal lvl1_busy_i_not : std_logic; + signal lvl1_memory_busy_i : std_logic; + signal lvl1_trigger_pulse : std_logic; + signal lvl1_tdc_trigg_i : std_logic; + signal lvl1_tdc_token_i : std_logic; + signal lvl1_buffer_in : std_logic_vector(31 downto 0); + signal lvl1_busy_end_pulse : std_logic; + signal test_counter_0 : std_logic_vector(7 downto 0); --lvl1 started + signal test_counter_1 : std_logic_vector(7 downto 0); --lvl` finished + --lvl2 + type LVL2_START_FSM is + (IDLE,WAIT_FOR_BUSY_END,READOUT_HEADER_MARKER_1,READOUT_HEADER_MARKER_2,SEND_HEADERS_AND_DATA,READOUT_DATA_MARKER_1,READOUT_DATA_MARKER_2,SEND_DATA); + signal LVL2_START_fsm_currentstate, LVL2_START_fsm_nextstate : LVL2_START_FSM; + signal lvl2_busy_i : std_logic; + signal not_lvl2_busy : std_logic; + signal lvl2_busy_end_pulse : std_logic; + signal test_counter_2 : std_logic_vector(7 downto 0); --lvl2 started + signal test_counter_3 : std_logic_vector(7 downto 0); --lvl2 finished + + --debug registers + signal trigger_register_00_i : std_logic_vector(5 downto 0); + signal add_data_i : std_logic_vector(31 downto 0); + + + + + + signal trigger_with_gen_pulse : std_logic; + signal lvl1_tag_minus1 : std_logic_vector(7 downto 0); + signal lvl2_debug : std_logic_vector(3 downto 0); + signal tdc_start_i : std_logic; + signal lvl2_busy_start_pulse : std_logic; + + signal lvl1_tdc_trigg_i_fsm : std_logic; + signal lvl1_tdc_token_i_fsm : std_logic; + + signal lvl1_busy_i_fsm : std_logic; + signal tdc_data_valid_i_fsm : std_logic; + signal lvl1_data_counter : std_logic_vector(15 downto 0):=(others => '0'); + signal trigger_counter : std_logic_vector(7 downto 0); + signal lvl1_code_i : std_logic_vector(3 downto 0); + + signal lvl2_trigger_pulse : std_logic; + + signal additional_data_i : std_logic_vector(NUMBER_OFF_ADD_DATA*32-1 downto 0); + signal reg_address : integer range 0 to 8 :=1; + signal event_number_cntr : std_logic_vector(23 downto 0); + signal full_event_size : std_logic_vector(31 downto 0); + signal lvl1_trigger_hades_or_not : std_logic; + signal lvl1_trigger_hades_or_not_pulse : std_logic; + +------------------------------------------------------------------------------- +-- new +------------------------------------------------------------------------------- +------------------------------------------------------------------------------- + +--data fifo + signal data_din_i : std_logic_VECTOR(33 downto 0); + signal data_rd_en_i : std_logic; + signal data_wr_en_i : std_logic; + signal data_dout_i : std_logic_VECTOR(33 downto 0):= (others => '0'); + signal data_empty_i : std_logic; + signal data_full_i : std_logic; + signal data_rd_data_count_i : std_logic_VECTOR(14 downto 0); + signal data_wr_data_count_i : std_logic_VECTOR(14 downto 0); + --in fsm + signal data_din_i_fsm : std_logic_VECTOR(33 downto 0); + signal data_rd_en_i_fsm : std_logic; + signal data_wr_en_i_fsm : std_logic; + +--headers and additional data fifo + signal hd_din_i : std_logic_VECTOR(33 downto 0); + signal hd_rd_en_i : std_logic; + signal hd_wr_en_i : std_logic; + signal hd_dout_i : std_logic_VECTOR(33 downto 0) := (others => '0'); + signal hd_empty_i : std_logic; + signal hd_full_i : std_logic; + signal hd_rd_data_count_i : std_logic_VECTOR(11 downto 0); + signal hd_wr_data_count_i : std_logic_VECTOR(11 downto 0); + --in fsm + signal hd_din_i_fsm : std_logic_VECTOR(33 downto 0); + signal hd_rd_en_i_fsm : std_logic; + signal hd_wr_en_i_fsm : std_logic; + + --TDC + signal received_tdc_token_i : std_logic; + signal lvl1_trigger_tdc : std_logic; + + --counters for token and trigger delay + signal wait_for_token_clr : std_logic; + signal wait_for_token_up : std_logic; + signal wait_for_token_cntr : std_logic_vector(7 downto 0); + signal wait_for_trigg_clr : std_logic; + signal wait_for_trigg_up : std_logic; + signal wait_for_trigg_cntr : std_logic_vector(7 downto 0); + +begin + + TDC_REGISTER : process (CLK, RESET) + begin + if rising_edge(CLK) then + TDC_REGISTER_00(0) <= A_TDC_ERROR; + TDC_REGISTER_00(1) <= B_TDC_ERROR; + TDC_REGISTER_00(2) <= C_TDC_ERROR; + TDC_REGISTER_00(3) <= D_TDC_ERROR; + TDC_REGISTER_00(13 downto 4) <= (others => '0'); + TDC_REGISTER_00(14) <= lvl1_busy_i; + TDC_REGISTER_00(15) <= lvl1_memory_busy_i; + TDC_REGISTER_00(30) <= hd_wr_en_i & hd_dout_i(32) & hd_rd_data_count_i & hd_full_i & hd_empty_i & data_wr_en_i & data_dout_i(32) & data_rd_data_count_i & data_full_i & data_empty_i; + TDC_REGISTER_00(31) <= lvl2_busy_i; + TDC_REGISTER_00(29 downto 16) <= (others => '0'); + TDC_REGISTER_01(27 downto 0) <= lvl2_debug & trigger_register_00_i(5 downto 2) & "00" & trigger_register_00_i(1 downto 0)& words_in_event(15 downto 0); + TDC_REGISTER_01(30 downto 28) <= (others => '0'); + TDC_REGISTER_01(31) <= ETRAX_IS_BUSY; + TDC_REGISTER_02(31 downto 0) <= (others => '0'); + TDC_REGISTER_03(31 downto 0) <= x"0"& LVL1_CODE & LVL1_TAG(7 downto 0) & x"0" & lvl1_code_i & lvl1_tag_minus1; + TDC_REGISTER_04(31 downto 0) <= test_counter_3 & test_counter_2 & test_counter_1 & test_counter_0; + end if; + end process TDC_REGISTER; + + + SYNC_TDC_DATA : process (TDC_CLK, RESET) + begin + if rising_edge(TDC_CLK) then + if RESET = '1' then + tdc_ready <= '0'; + lvl1_buffer_in <= (others => '0'); + received_tdc_token_i <= '0'; + else + tdc_ready <= A_TDC_READY or B_TDC_READY or C_TDC_READY or D_TDC_READY; + lvl1_buffer_in <= TDC_DATA_IN; + received_tdc_token_i <= RECEIVED_TDC_TOKEN; + end if; + end if; + end process SYNC_TDC_DATA; + + GET_TDC_DATA <= '1'; + + INTERNAL_TRIGGER_FOR_EVENT_BUILDER: up_down_counter + generic map ( + NUMBER_OF_BITS => 24) + port map ( + CLK => TDC_CLK, + RESET => RESET, + COUNT_OUT => event_number_cntr, + UP_IN => received_tdc_token_i, + DOWN_IN => '0'); + + SEND_BUNCH_RESET: process (TDC_CLK, RESET) + begin + if rising_edge(TDC_CLK) then + if RESET = '1' then + BUNCH_RESET <= '1'; + EVENT_RESET <= '1'; + else + EVENT_RESET <= '0'; + BUNCH_RESET <= received_tdc_token_i; + end if; + end if; + end process SEND_BUNCH_RESET; + + -- LVL1 logic + + SELECT_TRIGGER : process (CLK, RESET) + begin + if rising_edge(CLK) then + if RESET = '1' then + lvl1_trigger_hades_or_not <= '0'; + elsif TRIGGER_WITH_GEN_EN = '0' then + lvl1_trigger_hades_or_not <= START_TDC_READOUT; + else + lvl1_trigger_hades_or_not <= TRIGGER_WITH_GEN_EN and TRIGGER_WITH_GEN and (not lvl1_busy_i) and (not lvl2_busy_i); + end if; + end if; + end process SELECT_TRIGGER; + + LVL1_PULSER : edge_to_pulse + port map ( + clock => TDC_CLK, + en_clk => '1', + signal_in => lvl1_trigger_hades_or_not, + pulse => lvl1_trigger_hades_or_not_pulse); + + MAKE_CORRECT_LVL1_LENGHT : process (CLK, RESET) + begin + if rising_edge(CLK) then + if RESET = '1' or LVL1_START_fsm_currentstate = WAIT_BEFORE_TOKEN then + lvl1_trigger_tdc <= '0'; + elsif lvl1_trigger_hades_or_not_pulse = '1' then + lvl1_trigger_tdc <= '1'; + else + lvl1_trigger_tdc <= lvl1_trigger_tdc; + end if; + end if; + end process MAKE_CORRECT_LVL1_LENGHT; + + DELAY_FOR_TOKEN_CNTR: up_down_counter + generic map ( + NUMBER_OF_BITS => 8) + port map ( + CLK => TDC_CLK, + RESET => wait_for_token_clr, + COUNT_OUT => WAIT_FOR_TOKEN_cntr, + UP_IN => wait_for_token_up, + DOWN_IN => '0'); + + DELAY_FOR_TRIGGER_CNTR: up_down_counter + generic map ( + NUMBER_OF_BITS => 8) + port map ( + CLK => TDC_CLK, + RESET => wait_for_trigg_clr, + COUNT_OUT => wait_for_trigg_cntr, + UP_IN => wait_for_trigg_up, + DOWN_IN => '0'); + + LVL1_DATA_FIFO: lvl1_buffer_32kW + port map ( + din => data_din_i, + rd_clk => CLK, + rd_en => data_rd_en_i, + rst => RESET, + wr_clk => TDC_CLK, + wr_en => data_wr_en_i, + dout => data_dout_i, + empty => data_empty_i, + full => data_full_i, + rd_data_count => data_rd_data_count_i, + wr_data_count => data_wr_data_count_i); + + HEADER_DATA_FIFO: header_add_data_fifo_4kW + port map ( + din => hd_din_i, + rd_clk => CLK, + rd_en => hd_rd_en_i, + rst => RESET, + wr_clk => TDC_CLK, + wr_en => hd_wr_en_i, + dout => hd_dout_i, + empty => hd_empty_i, + full => hd_full_i, + rd_data_count => hd_rd_data_count_i, + wr_data_count => hd_wr_data_count_i); + + LVL1_START : process (TDC_CLK, RESET) + begin + if rising_edge(TDC_CLK) then + if RESET = '1' then + LVL1_START_fsm_currentstate <= IDLE; + lvl1_busy_i <= '0'; + lvl1_tdc_trigg_i <= '0'; + lvl1_tdc_token_i <= '0'; + data_wr_en_i <= '0'; + hd_wr_en_i <= '0'; + data_din_i <= (others => '0'); + hd_din_i <= (others => '0'); + else + LVL1_START_fsm_currentstate <= LVL1_START_fsm_nextstate; + lvl1_tdc_trigg_i <= lvl1_tdc_trigg_i_fsm; + lvl1_tdc_token_i <= lvl1_tdc_token_i_fsm; + lvl1_busy_i <= lvl1_busy_i_fsm; + data_wr_en_i <= data_wr_en_i_fsm; + hd_wr_en_i <= hd_wr_en_i_fsm; + data_din_i <= data_din_i_fsm; + hd_din_i <= hd_din_i_fsm; + end if; + end if; + end process LVL1_START; + + LVL1_START_FSM_PROC : process (LVL1_START_fsm_currentstate, received_tdc_token_i, trigger_with_gen_pulse, lvl1_trigger_pulse_start, add_data_counter, lvl1_data_counter, how_many_add_data, lvl1_code, trigger_with_gen_en, add_data_i, second_header, first_header,TDC_CLK) + begin + lvl1_tdc_trigg_i_fsm <= '0'; + lvl1_tdc_token_i_fsm <= '0'; + add_data_pulse <= '0'; + LVL1_START_fsm_nextstate <= IDLE; + lvl1_busy_i_fsm <= '1'; + data_wr_en_i_fsm <= '0'; + hd_wr_en_i_fsm <= '0'; + data_din_i_fsm <= (others => '0'); + hd_din_i_fsm <= (others => '0'); + wait_for_token_up <= '0'; + wait_for_token_clr <= '1'; + wait_for_trigg_up <= '0'; + wait_for_trigg_clr <= '1'; + + case (LVL1_START_fsm_currentstate) is + + when IDLE => + trigger_register_00_i(5 downto 2) <= x"1"; + lvl1_busy_i_fsm <= '0'; + if (lvl1_trigger_tdc = '1'and LVL1_CODE /= x"d") then + LVL1_START_fsm_nextstate <= WAIT_BEFORE_TRIGG; + else + LVL1_START_fsm_nextstate <= IDLE; + end if; + when WAIT_BEFORE_TRIGG => + trigger_register_00_i(5 downto 2) <= x"2"; + wait_for_trigg_up <= '1'; + wait_for_trigg_clr <= '0'; + if wait_for_trigg_cntr = DELAY_TRIGGER then + LVL1_START_fsm_nextstate <= SEND_TRIGGER; + else + LVL1_START_fsm_nextstate <= WAIT_BEFORE_TRIGG; + end if; + when SEND_TRIGGER => + trigger_register_00_i(5 downto 2) <= x"2"; + lvl1_tdc_trigg_i_fsm <= '1'; + LVL1_START_fsm_nextstate <= WAIT_BEFORE_TOKEN; + when WAIT_BEFORE_TOKEN => + trigger_register_00_i(5 downto 2) <= x"2"; + wait_for_token_up <= '1'; + wait_for_token_clr <= '0'; + if wait_for_token_cntr = DELAY_TOKEN then + LVL1_START_fsm_nextstate <= SEND_AND_WAIT_FOR_TOKEN; + else + LVL1_START_fsm_nextstate <= WAIT_BEFORE_TOKEN; + end if; + when SEND_AND_WAIT_FOR_TOKEN => + trigger_register_00_i(5 downto 2) <= x"3"; + lvl1_tdc_token_i_fsm <= '1'; + data_wr_en_i_fsm <= tdc_ready; + data_din_i_fsm <= "01" & lvl1_buffer_in; + if received_tdc_token_i = '1' then + LVL1_START_fsm_nextstate <= SAVE_DATA_MARKER; + else + LVL1_START_fsm_nextstate <= SEND_AND_WAIT_FOR_TOKEN; + end if; + + when SAVE_DATA_MARKER => + trigger_register_00_i(5 downto 2) <= x"4"; + data_wr_en_i_fsm <= '1'; + data_din_i_fsm <= (others => '0'); + if TDC_REGISTER_05(31) = '1' then + LVL1_START_fsm_nextstate <= SAVE_EB_HEADER_1; + elsif TRBNET_HEADER_BUILD = '1' then + LVL1_START_fsm_nextstate <= SAVE_TRBNET_HEADER_1; + else + LVL1_START_fsm_nextstate <= SAVE_HEADER_1; + end if; + + when SAVE_EB_HEADER_1 => + hd_wr_en_i_fsm <= '1'; + hd_din_i_fsm <= "01" & x"000" & "00" & words_in_event & "00" + 16; + trigger_register_00_i(5 downto 2) <= x"5"; + LVL1_START_fsm_nextstate <= SAVE_EB_HEADER_2; + + when SAVE_EB_HEADER_2 => + hd_wr_en_i_fsm <= '1'; + hd_din_i_fsm <= "01" & x"00020001"; + trigger_register_00_i(5 downto 2) <= x"6"; + LVL1_START_fsm_nextstate <= SAVE_EB_HEADER_3; + + when SAVE_EB_HEADER_3 => + hd_wr_en_i_fsm <= '1'; + hd_din_i_fsm <= "01" & TRB_ID; + trigger_register_00_i(5 downto 2) <= x"7"; + LVL1_START_fsm_nextstate <= SAVE_EB_HEADER_4; + + when SAVE_EB_HEADER_4 => + hd_wr_en_i_fsm <= '1'; + hd_din_i_fsm <= "01" & (event_number_cntr-1) & (lvl1_tag_minus1); + trigger_register_00_i(5 downto 2) <= x"8"; + if TRBNET_HEADER_BUILD = '1' then + LVL1_START_fsm_nextstate <= SAVE_TRBNET_HEADER_1; + else + LVL1_START_fsm_nextstate <= SAVE_HEADER_1; + end if; + + when SAVE_TRBNET_HEADER_1 => + hd_wr_en_i_fsm <= '1'; + trigger_register_00_i(5 downto 2) <= x"d"; + hd_din_i_fsm <= "01" & x"0" & lvl1_code_i & LVL1_RND_CODE & LVL1_TAG; + LVL1_START_fsm_nextstate <= SAVE_TRBNET_HEADER_2; + + when SAVE_TRBNET_HEADER_2 => + hd_wr_en_i_fsm <= '1'; + trigger_register_00_i(5 downto 2) <= x"e"; + hd_din_i_fsm <= "01" & words_in_event & x"0000"; + LVL1_START_fsm_nextstate <= SAVE_HEADER_2; + + when SAVE_HEADER_1 => + hd_wr_en_i_fsm <= '1'; + hd_din_i_fsm <= "01" & x"0" & lvl1_code_i & lvl1_tag_minus1 & words_in_event; + trigger_register_00_i(5 downto 2) <= x"9"; + LVL1_START_fsm_nextstate <= SAVE_HEADER_2; + + when SAVE_HEADER_2 => + hd_wr_en_i_fsm <= '1'; + hd_din_i_fsm <= "01" & TDC_REGISTER_05(15 downto 8) & x"0000" & HOW_MANY_ADD_DATA; + trigger_register_00_i(5 downto 2) <= x"a"; + if add_data_counter > 0 then + LVL1_START_fsm_nextstate <= SAVE_ADD_DATA; + else + LVL1_START_fsm_nextstate <= SAVE_HEADER_MARKER; + end if; + + when SAVE_ADD_DATA => + trigger_register_00_i(5 downto 2) <= x"b"; + hd_wr_en_i_fsm <= '1'; + hd_din_i_fsm <= "01" & add_data_i; + if add_data_counter = x"00" then -- adapt to fifo, memory (--external)? + LVL1_START_fsm_nextstate <= SAVE_HEADER_MARKER; + else + LVL1_START_fsm_nextstate <= SAVE_ADD_DATA; + end if; + + when SAVE_HEADER_MARKER => + trigger_register_00_i(5 downto 2) <= x"c"; + hd_wr_en_i_fsm <= '1'; + hd_din_i_fsm <= (others => '0'); + --here add memory busy + LVL1_START_fsm_nextstate <= IDLE; + + when others => + trigger_register_00_i(5 downto 2) <= x"0"; + LVL1_START_fsm_nextstate <= IDLE; + end case; + end process LVL1_START_FSM_PROC; + + TDC_TRIGGER_PULSER : edge_to_pulse + port map ( + clock => TDC_CLK, + en_clk => '1', + signal_in => lvl1_tdc_trigg_i, + pulse => TDC_START); + + TDC_TOKEN_PULSER : edge_to_pulse + port map ( + clock => TDC_CLK, + en_clk => '1', + signal_in => lvl1_tdc_token_i, + pulse => SEND_TDC_TOKEN); + + SAVE_DATA : process (CLK, RESET,lvl1_tdc_trigg_i) + begin + if rising_edge(CLK) then + if RESET = '1' then + additional_data_i <= (others => '1'); + elsif lvl1_tdc_trigg_i = '1' then + additional_data_i <= ADDITIONAL_DATA; + end if; + end if; + end process SAVE_DATA; + + CHOOSE_DATA : process (CLK, RESET, add_data_counter) + begin + if rising_edge(CLK) then + if RESET = '1' then + reg_address <= 1; + add_data_i <= x"00000000"; + elsif reg_address > 0 then + reg_address <= conv_integer(add_data_counter); + add_data_i <= additional_data_i(reg_address*32-1 downto 0); + else + reg_address <= 1; + add_data_i <= x"00000000"; + end if; + end if; + end process CHOOSE_DATA; + +-- add_data_pulse <= '1' when SAVE_ADD_DATA_3 = LVL1_START_fsm_nextstate else '0'; + + ADD_DATA_COUNTER_CONTROL : process (CLK,RESET,lvl1_tdc_trigg_i,add_data_pulse) + begin + if rising_edge(CLK) then + if RESET = '1' or lvl1_tdc_trigg_i = '1' then + add_data_counter <= x"0" & HOW_MANY_ADD_DATA(3 downto 0); + elsif add_data_pulse = '1' then + add_data_counter <= add_data_counter -1 ; + end if; + end if; + end process ADD_DATA_COUNTER_CONTROL; + + COUNT_WORDS_IN_EVENT : process (TDC_CLK, RESET, tdc_ready, lvl1_tdc_trigg_i) + begin + if rising_edge(TDC_CLK) then + if RESET = '1' or lvl1_tdc_trigg_i = '1' then + words_in_event <= x"0002" + HOW_MANY_ADD_DATA; + elsif tdc_ready = '1' then + words_in_event <= words_in_event + 1; + end if; + end if; + end process COUNT_WORDS_IN_EVENT; + + TRIGGER_COUNTER_PROC : process (CLK, RESET, LVL1_START_fsm_currentstate) + begin + if rising_edge(TDC_CLK) then + if RESET = '1' then + trigger_counter <= x"ff"; + elsif LVL1_START_fsm_currentstate = SAVE_DATA_MARKER then + trigger_counter <= trigger_counter + 1; + else + trigger_counter <= trigger_counter; + end if; + end if; + end process TRIGGER_COUNTER_PROC; + + SAVE_CODE_AND_TAG : process (CLK, RESET) + begin + if rising_edge(CLK) then + if RESET = '1' then + lvl1_tag_minus1 <= (others => '0'); + lvl1_code_i <= (others => '0'); + elsif TRIGGER_WITH_GEN_EN = '1' then + lvl1_tag_minus1 <= trigger_counter; + lvl1_code_i <= x"1"; + else + lvl1_tag_minus1 <= LVL1_TAG(7 downto 0) - 1; + lvl1_code_i <= LVL1_CODE; + end if; + end if; + end process SAVE_CODE_AND_TAG; + + ----------------------------------------------------------------------------- + ---------------------------------------------------------------------------- + -- LVL2 logic (only CLK domain) + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + + LVL2_START : process (CLK, RESET) + begin + if rising_edge(CLK) then + if RESET = '1' then + LVL2_START_fsm_currentstate <= IDLE; + tdc_data_valid_i <= '0'; + data_rd_en_i <= '0'; + hd_rd_en_i <= '0'; + else + tdc_data_valid_i <= tdc_data_valid_i_fsm; + LVL2_START_fsm_currentstate <= LVL2_START_fsm_nextstate; + data_rd_en_i <= data_rd_en_i_fsm; + hd_rd_en_i <= hd_rd_en_i_fsm; + end if; + end if; + end process LVL2_START; + + LVL2_TRIGG_PULSER : edge_to_pulse + port map ( + clock => CLK, + en_clk => '1', + signal_in => LVL2_TRIGGER, + pulse => lvl2_trigger_pulse); + + START_LVL2_FSM: process (LVL2_TRIGGER,LVL2_START_fsm_currentstate, LVL1_START_fsm_currentstate, ETRAX_IS_BUSY, ETRAX_IS_READY_TO_READ,hd_dout_i,data_dout_i,clk) + begin + lvl2_busy_i <= '1'; + lvl2_debug <= x"a"; + tdc_data_valid_i_fsm <= '0'; + LVL2_START_fsm_nextstate <= IDLE; + TDC_DATA_OUT <= (others => '0'); + data_rd_en_i_fsm <= '0'; + hd_rd_en_i_fsm <= '0'; + + case (LVL2_START_fsm_currentstate) is + when IDLE => + lvl2_debug <= x"1"; + lvl2_busy_i <= '0'; + if lvl2_trigger_pulse = '1' or (TRIGGER_WITH_GEN_EN ='1' and LVL1_START_fsm_currentstate = SAVE_HEADER_MARKER ) or ( LVL1_START_fsm_currentstate = SAVE_HEADER_MARKER and TRBV2_TYPE = 5)then + LVL2_START_fsm_nextstate <= WAIT_FOR_BUSY_END;--READOUT_WORD1;--SAVE_EVENT_SIZE; + else + LVL2_START_fsm_nextstate <= IDLE; + end if; + + when WAIT_FOR_BUSY_END => + lvl2_debug <= x"2"; + if ETRAX_IS_BUSY = '0' then + LVL2_START_fsm_nextstate <= READOUT_HEADER_MARKER_1; + else + LVL2_START_fsm_nextstate <= WAIT_FOR_BUSY_END; + end if; + + when READOUT_HEADER_MARKER_1 => + lvl2_debug <= x"3"; + if hd_dout_i(32) = '0' then + hd_rd_en_i_fsm <= '1'; + LVL2_START_fsm_nextstate <= READOUT_HEADER_MARKER_2; + else + hd_rd_en_i_fsm <= '0'; + LVL2_START_fsm_nextstate <= SEND_HEADERS_AND_DATA; + end if; + + when READOUT_HEADER_MARKER_2 => + lvl2_debug <= x"4"; + LVL2_START_fsm_nextstate <= READOUT_HEADER_MARKER_1; + + when SEND_HEADERS_AND_DATA => + lvl2_debug <= x"5"; + hd_rd_en_i_fsm <= ETRAX_IS_READY_TO_READ; + tdc_data_valid_i_fsm <= hd_dout_i(32); + TDC_DATA_OUT <= hd_dout_i(31 downto 0); + if hd_dout_i(32) = '0' then + LVL2_START_fsm_nextstate <= READOUT_DATA_MARKER_1; + else + LVL2_START_fsm_nextstate <= SEND_HEADERS_AND_DATA; + end if; + + when READOUT_DATA_MARKER_1 => + lvl2_debug <= x"6"; + if data_dout_i(32) = '0' then + data_rd_en_i_fsm <= '1'; + LVL2_START_fsm_nextstate <= READOUT_DATA_MARKER_2; + else + data_rd_en_i_fsm <= '0'; + LVL2_START_fsm_nextstate <= SEND_DATA; + end if; + + when READOUT_DATA_MARKER_2 => + lvl2_debug <= x"7"; + LVL2_START_fsm_nextstate <= READOUT_DATA_MARKER_1; + + when SEND_DATA => + lvl2_debug <= x"8"; + data_rd_en_i_fsm <= ETRAX_IS_READY_TO_READ; + tdc_data_valid_i_fsm <= data_dout_i(32); + TDC_DATA_OUT <= data_dout_i(31 downto 0); + if data_dout_i(32) = '0' then + LVL2_START_fsm_nextstate <= IDLE; + else + LVL2_START_fsm_nextstate <= SEND_DATA; + end if; + + when others => + lvl2_debug <= x"9"; + LVL2_START_fsm_nextstate <= IDLE; + + end case; + end process START_LVL2_FSM; + + + TDC_DATA_VALID <= tdc_data_valid_i; + not_lvl2_busy <= not lvl2_busy_i; + + LVL2_BUSY_END_PULSER : edge_to_pulse + port map ( + clock => CLK, + en_clk => '1', + signal_in => not_lvl2_busy, + pulse => lvl2_busy_end_pulse); + + LVL2_BUSY_START_PULSER : edge_to_pulse + port map ( + clock => CLK, + en_clk => '1', + signal_in => lvl2_busy_i, + pulse => lvl2_busy_start_pulse); + --set + --to + --max + --value + --!!!!!!! and cut data process should + --be implemented - with busy or max + --size or last event ? or both + LVL2_BUSY <= lvl2_busy_i; + LVL2_READOUT_COMPLETED <= lvl2_busy_end_pulse; + + LVL1_STARTED_CNTR: up_down_counter + generic map ( + NUMBER_OF_BITS => 8) + port map ( + CLK => TDC_CLK, + RESET => RESET, + COUNT_OUT => test_counter_0, + UP_IN => lvl1_tdc_trigg_i, + DOWN_IN => '0'); + + LVL1_FINISHED_CNTR: up_down_counter + generic map ( + NUMBER_OF_BITS => 8) + port map ( + CLK => TDC_CLK, + RESET => RESET, + COUNT_OUT => test_counter_1, + UP_IN => received_tdc_token_i, + DOWN_IN => '0'); + + lvl1_busy_i_not <= not lvl1_busy_i; + LVL1_BUSY_END_PULSER : edge_to_pulse + port map ( + clock => CLK, + en_clk => '1', + signal_in => lvl1_busy_i_not, + pulse => lvl1_busy_end_pulse); + + LVL1_FINISHED <= lvl1_busy_end_pulse; + + LVL2_STARTED_CNTR: up_down_counter + generic map ( + NUMBER_OF_BITS => 8) + port map ( + CLK => CLK, + RESET => RESET, + COUNT_OUT => test_counter_2, + UP_IN => lvl2_busy_start_pulse, + DOWN_IN => '0'); + + LVL2_FINISHED_CNTR: up_down_counter + generic map ( + NUMBER_OF_BITS => 8) + port map ( + CLK => CLK, + RESET => RESET, + COUNT_OUT => test_counter_3, + UP_IN => lvl2_busy_end_pulse, + DOWN_IN => '0'); + + LVL2_FINISHED <= lvl2_busy_end_pulse; + + LVL1_MEMOMRY_BUSY_PROC : process (CLK, RESET) + begin + if rising_edge(CLK) then + if RESET = '1' then + lvl1_memory_busy_i <= '0'; + elsif (data_wr_data_count_i(14 downto 13)= "11") or (hd_wr_data_count_i(11 downto 1) = "11111111111") then + lvl1_memory_busy_i <= '1'; + else + lvl1_memory_busy_i <= '0'; + end if; + end if; + end process LVL1_MEMOMRY_BUSY_PROC; + + + + REGISTERING_SIGNALS: process (CLK, RESET) + begin + if rising_edge(CLK) then -- rising clock edge + if RESET = '1' then + LVL1_BUSY <= '0'; + else + LVL1_BUSY <= lvl1_busy_i or lvl1_memory_busy_i;--lvl1_busy_i or lvl1_memory_busy_i;--lvl1_or_lvl2_is_busy;--lvl1_busy_i; --here + end if; + end if; + end process REGISTERING_SIGNALS; + +end tdc_interfacev2; -- 2.43.0