From: Ludwig Maier Date: Sun, 3 Nov 2013 18:04:29 +0000 (+0100) Subject: nxyter new adc reset handler X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=33ff706c767225d7e9436591ad4777e28f877b43;p=trb3.git nxyter new adc reset handler --- diff --git a/nxyter/source/nx_data_receiver.vhd b/nxyter/source/nx_data_receiver.vhd index 7db0342..291a15b 100644 --- a/nxyter/source/nx_data_receiver.vhd +++ b/nxyter/source/nx_data_receiver.vhd @@ -112,6 +112,28 @@ architecture Behavioral of nx_data_receiver is signal adc_clk_ok_last : std_logic; signal adc_reset_s : std_logic; signal adc_reset_ctr : unsigned(11 downto 0); + + -- Reset Handler + signal r_wait_timer_init : unsigned(27 downto 0); + signal r_wait_timer_done : std_logic; + signal reset_adc_handler : std_logic; + + type R_STATES is (R_IDLE, + R_PLL_RESET, + R_PLL_WAIT_UNLOCK, + R_PLL_WAIT_LOCK, + R_WAIT_RESET_ADC, + R_WAIT_ADC_SETTLED, + R_WAIT_RESET_DATA_HANDLER + ); + signal R_STATE : R_STATES; + + signal sampling_clk_reset_p : std_logic; + signal sampling_clk_reset : std_logic; + signal adc_reset_p : std_logic; + signal adc_reset : std_logic; + signal data_handler_reset_p : std_logic; + signal data_handler_reset : std_logic; ----------------------------------------------------------------------------- -- CLK_IN Domain @@ -146,10 +168,6 @@ architecture Behavioral of nx_data_receiver is ----------------------------------------------------------------------------- -- ADC Handler - signal adc_reset_r : std_logic; - signal adc_reset_l : std_logic; - signal adc_reset : std_logic; - signal adc_data : std_logic_vector(11 downto 0); signal test_adc_data : std_logic_vector(11 downto 0); signal adc_data_valid : std_logic; @@ -195,7 +213,8 @@ architecture Behavioral of nx_data_receiver is signal reset_parity_error_ctr : std_logic; signal fifo_reset_r : std_logic; signal debug_adc : std_logic_vector(1 downto 0); - signal pll_adc_sampling_clk_reset_r :std_logic; + signal reset_adc_handler_r : std_logic; + begin PROC_DEBUG_MULT: process(debug_adc, @@ -225,43 +244,41 @@ begin case debug_adc is when "01" => DEBUG_OUT(0) <= CLK_IN; - DEBUG_OUT(1) <= NX_TIMESTAMP_CLK_IN; + DEBUG_OUT(1) <= '0'; DEBUG_OUT(2) <= TRIGGER_IN; DEBUG_OUT(3) <= adc_data_valid; DEBUG_OUT(15 downto 4) <= adc_data; when "10" => DEBUG_OUT(0) <= CLK_IN; - DEBUG_OUT(1) <= NX_TIMESTAMP_CLK_IN; + DEBUG_OUT(1) <= '0'; DEBUG_OUT(2) <= TRIGGER_IN; DEBUG_OUT(3) <= adc_data_valid; - DEBUG_OUT(7 downto 4) <= (others => '0'); - DEBUG_OUT(15 downto 8) <= counter_nx_diff; - --DEBUG_OUT(15 downto 4) <= test_adc_data; + DEBUG_OUT(15 downto 4) <= test_adc_data; when "11" => - DEBUG_OUT(0) <= NX_TIMESTAMP_CLK_IN; - DEBUG_OUT(1) <= CLK_IN; + DEBUG_OUT(0) <= CLK_IN; + DEBUG_OUT(1) <= reset_adc_handler; DEBUG_OUT(2) <= TRIGGER_IN; DEBUG_OUT(3) <= adc_clk_ok; DEBUG_OUT(4) <= adc_clk_ok_last; DEBUG_OUT(5) <= adc_clk_skip; - DEBUG_OUT(6) <= adc_reset_r; - DEBUG_OUT(7) <= adc_reset_l; - DEBUG_OUT(8) <= adc_reset_s; - DEBUG_OUT(9) <= adc_reset; + DEBUG_OUT(6) <= sampling_clk_reset; + DEBUG_OUT(7) <= adc_reset; + DEBUG_OUT(8) <= r_wait_timer_done; + DEBUG_OUT(9) <= reset_adc_handler_r; DEBUG_OUT(10) <= nx_new_frame; DEBUG_OUT(11) <= nx_data_clock_ok; - DEBUG_OUT(12) <= '0'; --adc_sampling_clk; - DEBUG_OUT(13) <= pll_adc_sampling_clk_lock; - DEBUG_OUT(14) <= pll_adc_sampling_clk_o; + DEBUG_OUT(12) <= data_handler_reset; + DEBUG_OUT(13) <= pll_adc_not_lock; + DEBUG_OUT(14) <= '0'; DEBUG_OUT(15) <= '0'; --DEBUG_OUT(15 downto 11) <= adc_reset_ctr(4 downto 0) ; when others => DEBUG_OUT(0) <= CLK_IN; - DEBUG_OUT(1) <= NX_TIMESTAMP_CLK_IN; + DEBUG_OUT(1) <= '0'; --NX_TIMESTAMP_CLK_IN; DEBUG_OUT(2) <= TRIGGER_IN; DEBUG_OUT(3) <= nx_fifo_full; DEBUG_OUT(4) <= nx_fifo_write_enable; @@ -314,6 +331,8 @@ begin -- ADC CLK DOMAIN ----------------------------------------------------------------------------- + pll_adc_sampling_clk_reset <= sampling_clk_reset; + pll_adc_sampling_clk_2: pll_adc_sampling_clk port map ( CLK => adc_sampling_clk, @@ -332,18 +351,7 @@ begin LOCK => pll_adc_sampling_clk_lock ); - pulse_to_level_2: pulse_to_level - generic map ( - NUM_CYCLES => 10 - ) - port map ( - CLK_IN => CLK_IN, - RESET_IN => RESET_IN, - PULSE_IN => pll_adc_sampling_clk_reset_r, - LEVEL_OUT => pll_adc_sampling_clk_reset - ); - - pulse_async_trans_1: pulse_async_trans + signal_async_to_pulse_1: signal_async_to_pulse port map ( CLK_IN => CLK_IN, RESET_IN => RESET_IN, @@ -400,17 +408,129 @@ begin DEBUG => open ); - adc_reset <= adc_reset_s or adc_reset_l or RESET_IN; + nx_timer_1: nx_timer + generic map ( + CTR_WIDTH => 28 + ) + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + TIMER_START_IN => r_wait_timer_init, + TIMER_DONE_OUT => r_wait_timer_done + ); + + reset_adc_handler <= '0'; - pulse_to_level_1: pulse_to_level + PROC_RESET_HANDLER: process(CLK_IN) + begin + if (rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + sampling_clk_reset_p <= '0'; + adc_reset_p <= '0'; + data_handler_reset_p <= '0'; + r_wait_timer_init <= x"00f_4240"; -- 1ms to settle down + R_STATE <= R_PLL_RESET; + else + sampling_clk_reset_p <= '0'; + adc_reset_p <= '0'; + data_handler_reset_p <= '0'; + r_wait_timer_init <= (others => '0'); + + case R_STATE is + when R_IDLE => + if (reset_adc_handler = '1' or + reset_adc_handler_r = '1' or + pll_adc_not_lock = '1') then + r_wait_timer_init <= x"00f_4240"; -- 1ms to settle down + R_STATE <= R_PLL_RESET; + else + R_STATE <= R_IDLE; + end if; + + when R_PLL_RESET => + if (r_wait_timer_done = '0') then + R_STATE <= R_WAIT_RESET_ADC; + else + sampling_clk_reset_p <= '1'; + R_STATE <= R_PLL_WAIT_UNLOCK; + end if; + + when R_PLL_WAIT_UNLOCK => + if (pll_adc_not_lock = '0') then + R_STATE <= R_PLL_WAIT_UNLOCK; + else + R_STATE <= R_PLL_WAIT_LOCK; + end if; + + when R_PLL_WAIT_LOCK => + if (pll_adc_not_lock = '1') then + R_STATE <= R_PLL_WAIT_LOCK; + else + r_wait_timer_init <= x"2fa_f080"; -- 50ms + R_STATE <= R_WAIT_RESET_ADC; + end if; + + when R_WAIT_RESET_ADC => + if (r_wait_timer_done = '0') then + R_STATE <= R_WAIT_RESET_ADC; + else + adc_reset_p <= '1'; + r_wait_timer_init <= x"2fa_f080"; -- 50ms + R_STATE <= R_WAIT_ADC_SETTLED; + end if; + + when R_WAIT_ADC_SETTLED => + if (r_wait_timer_done = '0') then + R_STATE <= R_WAIT_ADC_SETTLED; + else + data_handler_reset_p <= '1'; + r_wait_timer_init <= x"00f_4240"; -- 1ms + R_STATE <= R_WAIT_RESET_DATA_HANDLER; + end if; + + when R_WAIT_RESET_DATA_HANDLER => + if (r_wait_timer_done = '0') then + R_STATE <= R_WAIT_RESET_DATA_HANDLER; + else + R_STATE <= R_IDLE; + end if; + + end case; + end if; + end if; + end process PROC_RESET_HANDLER; + + pulse_to_level_3: pulse_to_level generic map ( - NUM_CYCLES => 7 + NUM_CYCLES => 10 ) port map ( - CLK_IN => CLK_IN, - RESET_IN => RESET_IN, - PULSE_IN => adc_reset_r, - LEVEL_OUT => adc_reset_l + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + PULSE_IN => sampling_clk_reset_p, + LEVEL_OUT => sampling_clk_reset + ); + + pulse_to_level_4: pulse_to_level + generic map ( + NUM_CYCLES => 5 + ) + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + PULSE_IN => adc_reset_p, + LEVEL_OUT => adc_reset + ); + + pulse_to_level_5: pulse_to_level + generic map ( + NUM_CYCLES => 5 + ) + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + PULSE_IN => data_handler_reset_p, + LEVEL_OUT => data_handler_reset ); ----------------------------------------------------------------------------- @@ -562,7 +682,7 @@ begin Full => nx_fifo_full ); - nx_fifo_reset <= RESET_IN or fifo_reset_r; + nx_fifo_reset <= RESET_IN or data_handler_reset or fifo_reset_r; PROC_NX_CLK_ACT: process(NX_TIMESTAMP_CLK_IN) begin @@ -864,69 +984,6 @@ begin end if; end process PROC_OUTPUT_HANDLER; - - ----------------------------------------------------------------------------- - -- Reset Handler CLK_IN Domain - ----------------------------------------------------------------------------- - - -- Check NX Data Clock - -- Johnson Counter 2 - --PROC_NX_DATA_CLOCK_TEST: process(NX_TIMESTAMP_CLK_IN) - --begin - -- if (rising_edge(NX_TIMESTAMP_CLK_IN)) then - -- if (RESET_IN = '1') then - -- nx_data_clock_test_0 <= '0'; - -- nx_data_clock_test_1 <= '0'; - -- else - -- nx_data_clock_test_0 <= not nx_data_clock_test_1; - -- nx_data_clock_test_1 <= nx_data_clock_test_0; - -- end if; - -- end if; - --end process PROC_NX_DATA_CLOCK_TEST; - -- - --signal_async_trans_2: signal_async_trans - -- generic map ( - -- NUM_FF => 2 - -- ) - -- port map ( - -- CLK_IN => CLK_IN, - -- RESET_IN => RESET_IN, - -- SIGNAL_A_IN => nx_data_clock_test_0, - -- SIGNAL_OUT => nx_data_clock - -- ); - -- - --PROC_CHECK_NX_DATA_CLOCK: process(CLK_IN) - --begin - -- if (rising_edge(CLK_IN)) then - -- if( RESET_IN = '1' ) then - -- nx_data_clock_state <= (others => '0'); - -- nx_data_clock_ok <= '0'; - -- else - -- if (nx_data_clock_state = "1111" or - -- nx_data_clock_state = "0000" or - -- - -- nx_data_clock_state = "1110" or - -- nx_data_clock_state = "0111" or - -- - -- nx_data_clock_state = "1100" or - -- nx_data_clock_state = "0011" or - -- - -- nx_data_clock_state = "1000" or - -- nx_data_clock_state = "0001" - -- ) then - -- nx_data_clock_ok <= '0'; - -- else - -- nx_data_clock_ok <= '1'; - -- end if; - -- - -- nx_data_clock_state(0) <= nx_data_clock; - -- nx_data_clock_state(1) <= nx_data_clock_state(0); - -- nx_data_clock_state(2) <= nx_data_clock_state(1); - -- nx_data_clock_state(3) <= nx_data_clock_state(2); - -- end if; - -- end if; - --end process PROC_CHECK_NX_DATA_CLOCK; - ----------------------------------------------------------------------------- -- TRBNet Slave Bus ----------------------------------------------------------------------------- @@ -943,14 +1000,13 @@ begin reset_resync_ctr <= '0'; reset_parity_error_ctr <= '0'; fifo_reset_r <= '0'; - adc_reset_r <= '0'; debug_adc <= (others => '0'); adc_input_error_enable <= '0'; johnson_counter_sync <= "00"; pll_adc_sample_clk_dphase <= (others => '0'); pll_adc_sample_clk_finedelb <= (others => '0'); - pll_adc_sampling_clk_reset_r <= '0'; pll_adc_not_lock_ctr_clear <= '0'; + reset_adc_handler_r <= '0'; else slv_data_out_o <= (others => '0'); slv_ack_o <= '0'; @@ -959,9 +1015,8 @@ begin reset_resync_ctr <= '0'; reset_parity_error_ctr <= '0'; fifo_reset_r <= '0'; - adc_reset_r <= '0'; - pll_adc_sampling_clk_reset_r <= '0'; pll_adc_not_lock_ctr_clear <= '0'; + reset_adc_handler_r <= '0'; if (SLV_READ_IN = '1') then case SLV_ADDR_IN is @@ -1045,10 +1100,6 @@ begin elsif (SLV_WRITE_IN = '1') then case SLV_ADDR_IN is - when x"0001" => - adc_reset_r <= '1'; - slv_ack_o <= '1'; - when x"0002" => reset_resync_ctr <= '1'; slv_ack_o <= '1'; @@ -1063,18 +1114,21 @@ begin when x"0005" => johnson_counter_sync <= SLV_DATA_IN(1 downto 0); + reset_adc_handler_r <= '1'; slv_ack_o <= '1'; when x"0006" => pll_adc_sample_clk_dphase <= SLV_DATA_IN(3 downto 0); + reset_adc_handler_r <= '1'; slv_ack_o <= '1'; when x"0007" => pll_adc_sample_clk_finedelb <= SLV_DATA_IN(3 downto 0); + reset_adc_handler_r <= '1'; slv_ack_o <= '1'; when x"0009" => - pll_adc_sampling_clk_reset_r <= '1'; + reset_adc_handler_r <= '1'; slv_ack_o <= '1'; when x"000a" => diff --git a/nxyter/source/nx_fpga_timestamp.vhd b/nxyter/source/nx_fpga_timestamp.vhd index 6ce9327..91234aa 100644 --- a/nxyter/source/nx_fpga_timestamp.vhd +++ b/nxyter/source/nx_fpga_timestamp.vhd @@ -12,11 +12,11 @@ entity nx_fpga_timestamp is NX_MAIN_CLK_IN : in std_logic; TIMESTAMP_SYNC_IN : in std_logic; - TRIGGER_IN : in std_logic; + TRIGGER_IN : in std_logic; -- must be in NX_MAIN_CLK_DOMAIN TIMESTAMP_CURRENT_OUT : out unsigned(11 downto 0); TIMESTAMP_HOLD_OUT : out unsigned(11 downto 0); - NX_TIMESTAMP_SYNC_OUT : out std_logic; - NX_TIMESTAMP_TRIGGER_OUT : out std_logic; + TIMESTAMP_SYNCED_OUT : out std_logic; + TIMESTAMP_TRIGGER_OUT : out std_logic; -- Slave bus SLV_READ_IN : in std_logic; @@ -39,7 +39,8 @@ architecture Behavioral of nx_fpga_timestamp is signal trigger : std_logic; signal timestamp_sync : std_logic; - signal nx_timestamp_sync_o : std_logic; + signal timestamp_synced : std_logic; + signal timestamp_synced_o : std_logic; signal fifo_full : std_logic; signal fifo_write_enable : std_logic; @@ -48,7 +49,7 @@ begin DEBUG_OUT(0) <= CLK_IN; DEBUG_OUT(1) <= TIMESTAMP_SYNC_IN; - DEBUG_OUT(2) <= nx_timestamp_sync_o; + DEBUG_OUT(2) <= timestamp_synced_o; DEBUG_OUT(3) <= TRIGGER_IN; DEBUG_OUT(4) <= trigger; @@ -57,51 +58,40 @@ begin ----------------------------------------------------------------------------- -- NX Clock Domain ----------------------------------------------------------------------------- + -- signal_async_to_pulse_1: signal_async_to_pulse + -- port map ( + -- CLK_IN => NX_MAIN_CLK_IN, + -- RESET_IN => RESET_IN, + -- PULSE_A_IN => TRIGGER_IN, + -- PULSE_OUT => trigger + -- ); - -- Sync in TRIGGER and Timestamp Sync - pulse_dtrans_1: pulse_dtrans - generic map ( - CLK_RATIO => 2 - ) - port map ( - CLK_A_IN => CLK_IN, - RESET_A_IN => RESET_IN, - PULSE_A_IN => TRIGGER_IN, - CLK_B_IN => NX_MAIN_CLK_IN, - RESET_B_IN => RESET_IN, - PULSE_B_OUT => trigger - ); + trigger <= TRIGGER_IN; - pulse_dtrans_2: pulse_dtrans - generic map ( - CLK_RATIO => 2 - ) + signal_async_to_pulse_2: signal_async_to_pulse port map ( - CLK_A_IN => CLK_IN, - RESET_A_IN => RESET_IN, - PULSE_A_IN => TIMESTAMP_SYNC_IN, - CLK_B_IN => NX_MAIN_CLK_IN, - RESET_B_IN => RESET_IN, - PULSE_B_OUT => timestamp_sync + CLK_IN => NX_MAIN_CLK_IN, + RESET_IN => RESET_IN, + PULSE_A_IN => TIMESTAMP_SYNC_IN, + PULSE_OUT => timestamp_sync ); - - -- Timestamp Process + Trigger + -- Timestamp Process + Trigger PROC_TIMESTAMP_CTR: process (NX_MAIN_CLK_IN) begin if( rising_edge(NX_MAIN_CLK_IN) ) then if( RESET_IN = '1' ) then timestamp_ctr <= (others => '0'); timestamp_hold_o <= (others => '0'); - nx_timestamp_sync_o <= '0'; + timestamp_synced <= '0'; else - nx_timestamp_sync_o <= '0'; + timestamp_synced <= '0'; if (timestamp_sync = '1') then timestamp_ctr <= (others => '0'); - nx_timestamp_sync_o <= '1'; + timestamp_synced <= '1'; else if (trigger = '1') then - timestamp_hold_o <= std_logic_vector(timestamp_ctr - 3); + timestamp_hold_o <= std_logic_vector(timestamp_ctr); end if; timestamp_ctr <= timestamp_ctr + 1; end if; @@ -114,10 +104,23 @@ begin ----------------------------------------------------------------------------- -- Output Signals ----------------------------------------------------------------------------- + + pulse_dtrans_1: pulse_dtrans + generic map ( + CLK_RATIO => 4 + ) + port map ( + CLK_A_IN => NX_MAIN_CLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => timestamp_synced, + CLK_B_IN => CLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => timestamp_synced_o + ); TIMESTAMP_CURRENT_OUT <= timestamp_current_o; TIMESTAMP_HOLD_OUT <= timestamp_hold_o; - NX_TIMESTAMP_SYNC_OUT <= nx_timestamp_sync_o; - NX_TIMESTAMP_TRIGGER_OUT <= trigger; + TIMESTAMP_SYNCED_OUT <= timestamp_synced_o; + TIMESTAMP_TRIGGER_OUT <= trigger; end Behavioral; diff --git a/nxyter/source/nx_trigger_generator.vhd b/nxyter/source/nx_trigger_generator.vhd index 8d8de50..01864a2 100644 --- a/nxyter/source/nx_trigger_generator.vhd +++ b/nxyter/source/nx_trigger_generator.vhd @@ -9,8 +9,9 @@ entity nx_trigger_generator is port ( CLK_IN : in std_logic; RESET_IN : in std_logic; + NX_MAIN_CLK_IN : in std_logic; - TRIGGER_IN : in std_logic; + TRIGGER_IN : in std_logic; -- must be in NX_MAIN_CLK_DOMAIN TRIGGER_OUT : out std_logic; TS_RESET_OUT : out std_logic; TESTPULSE_OUT : out std_logic; @@ -33,6 +34,7 @@ end entity; architecture Behavioral of nx_trigger_generator is + signal trigger : std_logic; signal start_cycle : std_logic; signal trigger_cycle_ctr : unsigned(7 downto 0); signal wait_timer_init : unsigned(15 downto 0); @@ -43,9 +45,7 @@ architecture Behavioral of nx_trigger_generator is signal extern_trigger : std_logic; type STATES is (S_IDLE, - S_NEXT_CYCLE, - S_SET_TESTPULSE, - S_WAIT_TRIGGER_END + S_WAIT_TESTPULSE_END ); signal STATE : STATES; @@ -61,7 +61,7 @@ architecture Behavioral of nx_trigger_generator is signal slv_ack_o : std_logic; signal reg_trigger_period : unsigned(15 downto 0); - signal reg_testpulse_length : unsigned(15 downto 0); + signal reg_testpulse_length : unsigned(11 downto 0); signal reg_trigger_num_cycles : unsigned(7 downto 0); signal reg_ts_reset_on : std_logic; signal testpulse_rate : unsigned(27 downto 0); @@ -73,13 +73,14 @@ begin -- Debug Line DEBUG_OUT(0) <= CLK_IN; DEBUG_OUT(1) <= TRIGGER_IN; - DEBUG_OUT(2) <= start_cycle; - DEBUG_OUT(3) <= wait_timer_done; - DEBUG_OUT(4) <= ts_reset_o; - DEBUG_OUT(5) <= testpulse_o; - DEBUG_OUT(6) <= extern_trigger; - DEBUG_OUT(7) <= test_debug; - DEBUG_OUT(15 downto 8) <= (others => '0'); + DEBUG_OUT(2) <= trigger; + DEBUG_OUT(3) <= start_cycle; + DEBUG_OUT(4) <= wait_timer_done; + DEBUG_OUT(5) <= ts_reset_o; + DEBUG_OUT(6) <= testpulse_o; + DEBUG_OUT(7) <= testpulse_p; + DEBUG_OUT(8) <= test_debug; + DEBUG_OUT(15 downto 9) <= (others => '0'); PROC_TEST_DEBUG: process(CLK_IN) begin @@ -95,25 +96,42 @@ begin end if; end if; end process PROC_TEST_DEBUG; + -- Timer nx_timer_1: nx_timer generic map ( CTR_WIDTH => 16 ) port map ( - CLK_IN => CLK_IN, + CLK_IN => NX_MAIN_CLK_IN, RESET_IN => RESET_IN, TIMER_START_IN => wait_timer_init, TIMER_DONE_OUT => wait_timer_done ); ----------------------------------------------------------------------------- - -- Gernerate Trigger + -- Generate Trigger ----------------------------------------------------------------------------- - PROC_TRIGGER_OUT: process(CLK_IN) + -- signal_async_to_pulse_1: signal_async_to_pulse + -- port map ( + -- CLK_IN => NX_MAIN_CLK_IN, + -- RESET_IN => RESET_IN, + -- PULSE_A_IN => TRIGGER_IN, + -- PULSE_OUT => trigger + -- ); + + level_to_pulse_1: level_to_pulse + port map ( + CLK_IN => NX_MAIN_CLK_IN, + RESET_IN => RESET_IN, + LEVEL_IN => TRIGGER_IN, + PULSE_OUT => trigger + ); + + PROC_TESTPULSE_OUT: process(NX_MAIN_CLK_IN) begin - if( rising_edge(CLK_IN) ) then + if( rising_edge(NX_MAIN_CLK_IN) ) then if (RESET_IN = '1') then trigger_o <= '0'; testpulse_o <= '0'; @@ -130,37 +148,46 @@ begin case STATE is when S_IDLE => - if (TRIGGER_IN = '1') then - extern_trigger <= '1'; - wait_timer_init <= reg_testpulse_length; - STATE <= S_SET_TESTPULSE; + if (trigger = '1') then + extern_trigger <= '1'; + testpulse_o <= '1'; + if (reg_testpulse_length > 1) then + wait_timer_init(11 downto 0) <= reg_testpulse_length - 1; + wait_timer_init(15 downto 12) <= (others => '0'); + STATE <= S_WAIT_TESTPULSE_END; + else + STATE <= S_IDLE; + end if; else - extern_trigger <= '0'; - STATE <= S_IDLE; + extern_trigger <= '0'; + STATE <= S_IDLE; end if; - when S_SET_TESTPULSE => - testpulse_o <= '1'; + when S_WAIT_TESTPULSE_END => if (wait_timer_done = '0') then - STATE <= S_SET_TESTPULSE; + testpulse_o <= '1'; + STATE <= S_WAIT_TESTPULSE_END; else - STATE <= S_IDLE; + STATE <= S_IDLE; end if; - - when others => - STATE <= S_IDLE; + end case; end if; end if; - end process PROC_TRIGGER_OUT; + end process PROC_TESTPULSE_OUT; - -- Convert TRIGGER_IN to Pulse - level_to_pulse_1: level_to_pulse + -- Transfer testpulse_o to CLK_IN Domain + pulse_dtrans_1: pulse_dtrans + generic map ( + CLK_RATIO => 4 + ) port map ( - CLK_IN => CLK_IN, - RESET_IN => RESET_IN, - LEVEL_IN => testpulse_o, - PULSE_OUT => testpulse_p + CLK_A_IN => NX_MAIN_CLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => testpulse_o, + CLK_B_IN => CLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => testpulse_p ); PROC_CAL_RATES: process (CLK_IN) @@ -195,7 +222,7 @@ begin if( RESET_IN = '1' ) then reg_trigger_period <= x"00ff"; reg_trigger_num_cycles <= x"01"; - reg_testpulse_length <= x"0001"; + reg_testpulse_length <= x"001"; reg_ts_reset_on <= '0'; slv_data_out_o <= (others => '0'); slv_no_more_data_o <= '0'; @@ -212,13 +239,9 @@ begin if (SLV_WRITE_IN = '1') then case SLV_ADDR_IN is when x"0000" => - start_cycle <= '1'; - slv_ack_o <= '1'; - - when x"0001" => - if (reg_testpulse_length > 0) then + if (unsigned(SLV_DATA_IN(11 downto 0)) > 0) then reg_testpulse_length <= - unsigned(SLV_DATA_IN(15 downto 0)); + unsigned(SLV_DATA_IN(11 downto 0)); end if; slv_ack_o <= '1'; @@ -229,12 +252,13 @@ begin elsif (SLV_READ_IN = '1') then case SLV_ADDR_IN is - when x"0001" => - slv_data_out_o(15 downto 0) <= + when x"0000" => + slv_data_out_o(11 downto 0) <= std_logic_vector(reg_testpulse_length); + slv_data_out_o(31 downto 12) <= (others => '0'); slv_ack_o <= '1'; - when x"0005" => + when x"0001" => slv_data_out_o(27 downto 0) <= std_logic_vector(testpulse_rate); slv_data_out_o(31 downto 28) <= (others => '0'); slv_ack_o <= '1'; diff --git a/nxyter/source/nx_trigger_handler.vhd b/nxyter/source/nx_trigger_handler.vhd index f5d3e73..946794e 100644 --- a/nxyter/source/nx_trigger_handler.vhd +++ b/nxyter/source/nx_trigger_handler.vhd @@ -9,16 +9,17 @@ entity nx_trigger_handler is port ( CLK_IN : in std_logic; RESET_IN : in std_logic; + NX_MAIN_CLK_IN : in std_logic; NXYTER_OFFLINE_IN : in std_logic; - --LVL1 trigger - LVL1_TRG_DATA_VALID_IN : in std_logic; -- timing trigger valid, later - LVL1_VALID_TIMING_TRG_IN : in std_logic; -- normal read-out trigger with - -- reference time - LVL1_VALID_NOTIMING_TRG_IN : in std_logic; -- calibration trigger w/o - -- reference time - LVL1_INVALID_TRG_IN : in std_logic; -- + --Input Triggers + TIMING_TRIGGER_IN : in std_logic; -- The raw timing Trigger Signal + LVL1_TRG_DATA_VALID_IN : in std_logic; -- Data Trigger is valid + LVL1_VALID_TIMING_TRG_IN : in std_logic; -- Timin Trigger is valid + LVL1_VALID_NOTIMING_TRG_IN : in std_logic; -- calibration trigger w/o + -- reference time + LVL1_INVALID_TRG_IN : in std_logic; -- do fast clear LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0); LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); @@ -64,17 +65,46 @@ end entity; architecture Behavioral of nx_trigger_handler is - -- Trigger Handler - signal validate_trigger_o : std_logic; - signal lvl2_trigger_o : std_logic; - signal event_buffer_clear_o : std_logic; - signal fast_clear_o : std_logic; - signal trigger_busy_o : std_logic; - signal fee_trg_release_o : std_logic; - signal fee_trg_statusbits_o : std_logic_vector(31 downto 0); - signal timestamp_trigger_o : std_logic; - signal send_testpulse : std_logic; + -- Timing Trigger Handler + constant NUM_FF : integer := 10; + signal timing_trigger_ff_p : std_logic_vector(1 downto 0); + signal timing_trigger_ff : std_logic_vector(NUM_FF - 1 downto 0); + signal timing_trigger_l : std_logic; + signal timing_trigger : std_logic; + signal timing_trigger_set : std_logic; + signal timestamp_trigger : std_logic; + signal timestamp_trigger_o : std_logic; + + signal invalid_timing_trigger_n : std_logic; + signal invalid_timing_trigger : std_logic; + signal invalid_timing_trigger_ctr : unsigned(15 downto 0); + + signal trigger_busy : std_logic; + signal fast_clear : std_logic; + + type TS_STATES is (TS_IDLE, + TS_WAIT_VALID_TIMING_TRIGGER, + TS_INVALID_TRIGGER, + TS_WAIT_TRIGGER_END + ); + signal TS_STATE : TS_STATES; + + signal ts_wait_timer_reset : std_logic; + signal ts_wait_timer_init : unsigned(7 downto 0); + signal ts_wait_timer_done : std_logic; + + -- Trigger Handler + signal validate_trigger_o : std_logic; + signal lvl2_trigger_o : std_logic; + signal event_buffer_clear_o : std_logic; + signal fast_clear_o : std_logic; + signal trigger_busy_o : std_logic; + signal fee_trg_release_o : std_logic; + signal fee_trg_statusbits_o : std_logic_vector(31 downto 0); + signal send_testpulse_l : std_logic; + signal send_testpulse : std_logic; + type STATES is (S_IDLE, S_CTS_TRIGGER, S_WAIT_TRG_DATA_VALID, @@ -95,9 +125,9 @@ architecture Behavioral of nx_trigger_handler is signal T_STATE : T_STATES; - signal trigger_testpulse_o : std_logic; + signal trigger_testpulse_o : std_logic; signal wait_timer_reset : std_logic; - signal wait_timer_init : unsigned(7 downto 0); + signal wait_timer_init : unsigned(11 downto 0); signal wait_timer_done : std_logic; -- Rate Calculation @@ -110,49 +140,196 @@ architecture Behavioral of nx_trigger_handler is signal slv_unknown_addr_o : std_logic; signal slv_ack_o : std_logic; - signal reg_testpulse_delay : unsigned(7 downto 0); + signal reg_testpulse_delay : unsigned(11 downto 0); signal reg_testpulse_enable : std_logic; signal accepted_trigger_rate : unsigned(27 downto 0); + signal invalid_t_trigger_ctr_clear : std_logic; begin -- Debug Line DEBUG_OUT(0) <= CLK_IN; - DEBUG_OUT(1) <= LVL1_VALID_TIMING_TRG_IN; - DEBUG_OUT(2) <= LVL1_TRG_DATA_VALID_IN; - DEBUG_OUT(3) <= INTERNAL_TRIGGER_IN; - DEBUG_OUT(4) <= TRIGGER_VALIDATE_BUSY_IN; - DEBUG_OUT(5) <= LVL2_TRIGGER_BUSY_IN; - - DEBUG_OUT(6) <= validate_trigger_o; - DEBUG_OUT(7) <= timestamp_trigger_o; - DEBUG_OUT(8) <= lvl2_trigger_o; - DEBUG_OUT(9) <= event_buffer_clear_o; - DEBUG_OUT(10) <= fee_trg_release_o; - DEBUG_OUT(11) <= trigger_busy_o; - DEBUG_OUT(12) <= timestamp_trigger_o; - DEBUG_OUT(13) <= send_testpulse; - DEBUG_OUT(14) <= trigger_testpulse_o; - DEBUG_OUT(15) <= '0'; + DEBUG_OUT(1) <= TIMING_TRIGGER_IN; + DEBUG_OUT(2) <= invalid_timing_trigger; --timing_trigger_l; + DEBUG_OUT(3) <= LVL1_VALID_TIMING_TRG_IN; + DEBUG_OUT(4) <= LVL1_TRG_DATA_VALID_IN; + DEBUG_OUT(5) <= INTERNAL_TRIGGER_IN; + DEBUG_OUT(6) <= TRIGGER_VALIDATE_BUSY_IN; + DEBUG_OUT(7) <= LVL2_TRIGGER_BUSY_IN; + DEBUG_OUT(8) <= validate_trigger_o; + DEBUG_OUT(9) <= lvl2_trigger_o; + DEBUG_OUT(10) <= event_buffer_clear_o; + DEBUG_OUT(11) <= fee_trg_release_o; + DEBUG_OUT(12) <= trigger_busy_o; + DEBUG_OUT(13) <= timestamp_trigger; + DEBUG_OUT(14) <= send_testpulse; + DEBUG_OUT(15) <= trigger_testpulse_o; + + ----------------------------------------------------------------------------- + -- Trigger Handler + ----------------------------------------------------------------------------- + + PROC_TIMING_TRIGGER_HANDLER: process(NX_MAIN_CLK_IN) + constant pattern : std_logic_vector(NUM_FF - 1 downto 0) + := (others => '1'); + begin + if( rising_edge(NX_MAIN_CLK_IN) ) then + timing_trigger_ff_p(1) <= TIMING_TRIGGER_IN; + if (RESET_IN = '1') then + timing_trigger_ff_p(0) <= '0'; + timing_trigger_ff(NUM_FF - 1 downto 0) <= (others => '0'); + timing_trigger_l <= '0'; + else + timing_trigger_ff_p(0) <= timing_trigger_ff_p(1); + timing_trigger_ff(NUM_FF - 1) <= timing_trigger_ff_p(0); + + for I in NUM_FF - 2 downto 0 loop + timing_trigger_ff(I) <= timing_trigger_ff(I + 1); + end loop; + + if (timing_trigger_ff = pattern) then + timing_trigger_l <= '1'; + else + timing_trigger_l <= '0'; + end if; + end if; + end if; + end process PROC_TIMING_TRIGGER_HANDLER; + level_to_pulse_1: level_to_pulse + port map ( + CLK_IN => NX_MAIN_CLK_IN, + RESET_IN => RESET_IN, + LEVEL_IN => timing_trigger_l, + PULSE_OUT => timing_trigger + ); + -- Timer - nx_timer_1: nx_timer + nx_timer_2: nx_timer generic map ( CTR_WIDTH => 8 ) port map ( - CLK_IN => CLK_IN, - RESET_IN => wait_timer_reset, - TIMER_START_IN => wait_timer_init, - TIMER_DONE_OUT => wait_timer_done + CLK_IN => NX_MAIN_CLK_IN, + RESET_IN => ts_wait_timer_reset, + TIMER_START_IN => ts_wait_timer_init, + TIMER_DONE_OUT => ts_wait_timer_done ); - wait_timer_reset <= RESET_IN or fast_clear_o; + PROC_TIMING_TRIGGER_HANDLER: process(NX_MAIN_CLK_IN) + begin + if( rising_edge(NX_MAIN_CLK_IN) ) then + if (RESET_IN = '1' or fast_clear = '1') then + invalid_timing_trigger_n <= '1'; + ts_wait_timer_init <= (others => '0'); + ts_wait_timer_reset <= '1'; + send_testpulse <= '0'; + timestamp_trigger <= '0'; + TS_STATE <= TS_IDLE; + else + invalid_timing_trigger_n <= '0'; + ts_wait_timer_init <= (others => '0'); + ts_wait_timer_reset <= '0'; + send_testpulse <= '0'; + timestamp_trigger <= '0'; + + case TS_STATE is + when TS_IDLE => + if (timing_trigger = '1') then + if (trigger_busy = '0') then + if (reg_testpulse_enable = '1') then + send_testpulse <= '1'; + end if; + timestamp_trigger <= '1'; + ts_wait_timer_init <= x"20"; + TS_STATE <= TS_WAIT_VALID_TIMING_TRIGGER; + else + TS_STATE <= TS_INVALID_TRIGGER; + end if; + else + TS_STATE <= TS_IDLE; + end if; + + when TS_WAIT_VALID_TIMING_TRIGGER => + if (trigger_busy = '1') then + TS_STATE <= TS_WAIT_TRIGGER_END; + else + if (ts_wait_timer_done = '0') then + ts_wait_timer_reset <= '1'; + TS_STATE <= TS_WAIT_VALID_TIMING_TRIGGER; + else + ts_wait_timer_reset <= '1'; + TS_STATE <= TS_INVALID_TRIGGER; + end if; + end if; + + when TS_INVALID_TRIGGER => + invalid_timing_trigger_n <= '1'; + TS_STATE <= TS_IDLE; + + when TS_WAIT_TRIGGER_END => + if (trigger_busy = '0') then + TS_STATE <= TS_IDLE; + else + TS_STATE <= TS_WAIT_TRIGGER_END; + end if; + + end case; + end if; + end if; + end process PROC_TIMING_TRIGGER_HANDLER; - ----------------------------------------------------------------------------- - -- Trigger Handler - ----------------------------------------------------------------------------- + PROC_TIMING_TRIGGER_COUNTER: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if (RESET_IN = '1') then + invalid_timing_trigger_ctr <= (others => '0'); + else + if (invalid_t_trigger_ctr_clear = '1') then + invalid_timing_trigger_ctr <= (others => '0'); + elsif (invalid_timing_trigger = '1') then + invalid_timing_trigger_ctr <= invalid_timing_trigger_ctr + 1; + end if; + end if; + end if; + end process PROC_TIMING_TRIGGER_COUNTER; + + signal_async_trans_1: signal_async_trans + port map ( + CLK_IN => NX_MAIN_CLK_IN, + RESET_IN => RESET_IN, + SIGNAL_A_IN => trigger_busy_o, + SIGNAL_OUT => trigger_busy + ); + pulse_dtrans_3: pulse_dtrans + generic map ( + CLK_RATIO => 2 + ) + port map ( + CLK_A_IN => NX_MAIN_CLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => fast_clear_o, + CLK_B_IN => CLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => fast_clear + ); + + pulse_dtrans_2: pulse_dtrans + generic map ( + CLK_RATIO => 4 + ) + port map ( + CLK_A_IN => NX_MAIN_CLK_IN, + RESET_A_IN => RESET_IN, + PULSE_A_IN => invalid_timing_trigger_n, + CLK_B_IN => CLK_IN, + RESET_B_IN => RESET_IN, + PULSE_B_OUT => invalid_timing_trigger + ); + + ----------------------------------------------------------------------------- + PROC_TRIGGER_HANDLER: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then @@ -164,8 +341,7 @@ begin fast_clear_o <= '0'; event_buffer_clear_o <= '0'; trigger_busy_o <= '0'; - send_testpulse <= '0'; - timestamp_trigger_o <= '0'; + send_testpulse_l <= '0'; STATE <= S_IDLE; else validate_trigger_o <= '0'; @@ -175,13 +351,13 @@ begin fast_clear_o <= '0'; event_buffer_clear_o <= '0'; trigger_busy_o <= '1'; - send_testpulse <= '0'; - timestamp_trigger_o <= '0'; + send_testpulse_l <= '0'; if (LVL1_INVALID_TRG_IN = '1') then - fast_clear_o <= '1'; - fee_trg_release_o <= '1'; - STATE <= S_IDLE; + -- There was no valid Timing Trigger at CTS, do a fast clear + fast_clear_o <= '1'; + fee_trg_release_o <= '1'; + STATE <= S_IDLE; else case STATE is when S_IDLE => @@ -201,14 +377,14 @@ begin STATE <= S_IDLE; end if; - -- CTS Trigger Handler + when S_CTS_TRIGGER => + -- Do nothing, Just send Trigger ACK in reply event_buffer_clear_o <= '1'; validate_trigger_o <= '1'; - timestamp_trigger_o <= '1'; lvl2_trigger_o <= '1'; if (reg_testpulse_enable = '1') then - send_testpulse <= '1'; + send_testpulse_l <= '1'; end if; STATE <= S_WAIT_TRG_DATA_VALID; @@ -240,7 +416,6 @@ begin -- Internal Trigger Handler when S_INTERNAL_TRIGGER => validate_trigger_o <= '1'; - timestamp_trigger_o <= '1'; event_buffer_clear_o <= '1'; STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; @@ -264,17 +439,43 @@ begin end if; end process PROC_TRIGGER_HANDLER; - PROC_TESTPULSE_HANDLER: process (CLK_IN) +-- pulse_dtrans_4: pulse_dtrans +-- generic map ( +-- CLK_RATIO => 2 +-- ) +-- port map ( +-- CLK_A_IN => CLK_IN, +-- RESET_A_IN => RESET_IN, +-- PULSE_A_IN => send_testpulse_l, +-- CLK_B_IN => NX_MAIN_CLK_IN, +-- RESET_B_IN => RESET_IN, +-- PULSE_B_OUT => send_testpulse +-- ); + + nx_timer_1: nx_timer + generic map ( + CTR_WIDTH => 12 + ) + port map ( + CLK_IN => NX_MAIN_CLK_IN, + RESET_IN => wait_timer_reset, + TIMER_START_IN => wait_timer_init, + TIMER_DONE_OUT => wait_timer_done + ); + + PROC_TESTPULSE_HANDLER: process (NX_MAIN_CLK_IN) begin - if( rising_edge(CLK_IN) ) then - if (RESET_IN = '1' or fast_clear_o = '1') then + if( rising_edge(NX_MAIN_CLK_IN) ) then + if (RESET_IN = '1' or fast_clear = '1') then wait_timer_init <= (others => '0'); + wait_timer_reset <= '1'; trigger_testpulse_o <= '0'; T_STATE <= T_IDLE; else trigger_testpulse_o <= '0'; wait_timer_init <= (others => '0'); - + wait_timer_reset <= '0'; + case T_STATE is when T_IDLE => @@ -334,28 +535,34 @@ begin begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - slv_data_out_o <= (others => '0'); - slv_no_more_data_o <= '0'; - slv_unknown_addr_o <= '0'; - slv_ack_o <= '0'; - reg_testpulse_delay <= (others => '0'); - reg_testpulse_enable <= '0'; - else - slv_unknown_addr_o <= '0'; - slv_no_more_data_o <= '0'; - slv_data_out_o <= (others => '0'); - slv_ack_o <= '0'; - + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_ack_o <= '0'; + reg_testpulse_delay <= (others => '0'); + reg_testpulse_enable <= '0'; + invalid_t_trigger_ctr_clear <= '1'; + else + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; + slv_data_out_o <= (others => '0'); + slv_ack_o <= '0'; + invalid_t_trigger_ctr_clear <= '1'; + if (SLV_WRITE_IN = '1') then case SLV_ADDR_IN is when x"0000" => - reg_testpulse_delay <= unsigned(SLV_DATA_IN(7 downto 0)); + reg_testpulse_enable <= SLV_DATA_IN(0); slv_ack_o <= '1'; when x"0001" => - reg_testpulse_enable <= SLV_DATA_IN(0); - slv_ack_o <= '1'; + reg_testpulse_delay <= unsigned(SLV_DATA_IN(11 downto 0)); + slv_ack_o <= '1'; + when x"0003" => + invalid_t_trigger_ctr_clear <= '1'; + slv_ack_o <= '1'; + when others => slv_unknown_addr_o <= '1'; @@ -365,14 +572,14 @@ begin case SLV_ADDR_IN is when x"0000" => - slv_data_out_o(7 downto 0) <= - std_logic_vector(reg_testpulse_delay); - slv_data_out_o(31 downto 8) <= (others => '0'); + slv_data_out_o(0) <= reg_testpulse_enable; + slv_data_out_o(31 downto 1) <= (others => '0'); slv_ack_o <= '1'; when x"0001" => - slv_data_out_o(0) <= reg_testpulse_enable; - slv_data_out_o(31 downto 1) <= (others => '0'); + slv_data_out_o(11 downto 0) <= + std_logic_vector(reg_testpulse_delay); + slv_data_out_o(31 downto 12) <= (others => '0'); slv_ack_o <= '1'; when x"0002" => @@ -380,6 +587,12 @@ begin std_logic_vector(accepted_trigger_rate); slv_data_out_o(31 downto 28) <= (others => '0'); slv_ack_o <= '1'; + + when x"0003" => + slv_data_out_o(15 downto 0) <= + std_logic_vector(invalid_timing_trigger_ctr); + slv_data_out_o(31 downto 26) <= (others => '0'); + slv_ack_o <= '1'; when others => slv_unknown_addr_o <= '1'; @@ -395,6 +608,8 @@ begin -- Output Signals ----------------------------------------------------------------------------- + timestamp_trigger_o <= timestamp_trigger; + -- Trigger Output VALIDATE_TRIGGER_OUT <= validate_trigger_o; TIMESTAMP_TRIGGER_OUT <= timestamp_trigger_o; diff --git a/nxyter/source/nx_trigger_validate.vhd b/nxyter/source/nx_trigger_validate.vhd index de15756..b022103 100644 --- a/nxyter/source/nx_trigger_validate.vhd +++ b/nxyter/source/nx_trigger_validate.vhd @@ -17,9 +17,9 @@ entity nx_trigger_validate is DATA_CLK_IN : in std_logic; TIMESTAMP_IN : in std_logic_vector(13 downto 0); CHANNEL_IN : in std_logic_vector(6 downto 0); - TIMESTAMP_STATUS_IN : in std_logic_vector(2 downto 0); - ADC_DATA_IN : in std_logic_vector(11 downto 0); - NX_TOKEN_RETURN_IN : in std_logic; + TIMESTAMP_STATUS_IN : in std_logic_vector(2 downto 0); -- 2: parity + ADC_DATA_IN : in std_logic_vector(11 downto 0); -- 1: pileup + NX_TOKEN_RETURN_IN : in std_logic; -- 0: ovfl NX_NOMORE_DATA_IN : in std_logic; TRIGGER_IN : in std_logic; @@ -60,7 +60,7 @@ architecture Behavioral of nx_trigger_validate is signal channel_wait : std_logic_vector(127 downto 0); signal channel_done : std_logic_vector(127 downto 0); signal channel_all_done : std_logic; - + -- Channel Status Commands type CS_CMDS is (CS_RESET, CS_TOKEN_UPDATE, @@ -74,8 +74,8 @@ architecture Behavioral of nx_trigger_validate is signal ts_window_lower_thr : unsigned(11 downto 0); -- Process Timestamp - signal data_o : std_logic_vector(31 downto 0); - signal data_clk_o : std_logic; + signal d_data_o : std_logic_vector(31 downto 0); + signal d_data_clk_o : std_logic; signal out_of_window_l : std_logic; signal out_of_window_h : std_logic; signal out_of_window_error : std_logic; @@ -108,7 +108,7 @@ architecture Behavioral of nx_trigger_validate is signal wait_timer_reset : std_logic; signal min_val_time_expired : std_logic; signal event_counter : unsigned(9 downto 0); - + signal out_of_window_error_ctr : unsigned(15 downto 0); signal readout_mode : std_logic_vector(2 downto 0); signal timestamp_fpga : unsigned(11 downto 0); @@ -127,7 +127,11 @@ architecture Behavioral of nx_trigger_validate is -- Data FIFO Delay signal data_fifo_delay_o : unsigned(7 downto 0); - + + -- Output + signal data_clk_o : std_logic; + signal data_o : std_logic_vector(31 downto 0); + -- Slave Bus signal slv_data_out_o : std_logic_vector(31 downto 0); signal slv_no_more_data_o : std_logic; @@ -135,6 +139,7 @@ architecture Behavioral of nx_trigger_validate is signal slv_ack_o : std_logic; signal readout_mode_r : std_logic_vector(2 downto 0); + signal out_of_window_error_ctr_clear : std_logic; -- Timestamp Trigger Window Settings constant nxyter_cv_time : unsigned(11 downto 0) := x"190"; -- 400ns @@ -142,7 +147,8 @@ architecture Behavioral of nx_trigger_validate is signal ts_window_offset : signed(11 downto 0); signal ts_window_width : unsigned(9 downto 0); signal readout_time_max : unsigned(11 downto 0); - signal fpga_timestamp_offset : unsigned(11 downto 0); + signal fpga_timestamp_offset : unsigned(11 downto 0); + begin @@ -153,12 +159,12 @@ begin DEBUG_OUT(3) <= DATA_CLK_IN; DEBUG_OUT(4) <= out_of_window_l; DEBUG_OUT(5) <= out_of_window_h; - DEBUG_OUT(6) <= out_of_window_error; --NX_TOKEN_RETURN_IN; + DEBUG_OUT(6) <= NX_TOKEN_RETURN_IN; DEBUG_OUT(7) <= NX_NOMORE_DATA_IN; DEBUG_OUT(8) <= channel_all_done; DEBUG_OUT(9) <= store_to_fifo; DEBUG_OUT(10) <= data_clk_o; - DEBUG_OUT(11) <= t_data_clk_o; + DEBUG_OUT(11) <= out_of_window_error; DEBUG_OUT(12) <= wait_timer_done; DEBUG_OUT(13) <= wait_timer_done_ns; DEBUG_OUT(14) <= busy_time_min_done; @@ -204,28 +210,31 @@ begin begin if( rising_edge(CLK_IN) ) then if (RESET_IN = '1') then - data_o <= (others => '0'); - data_clk_o <= '0'; - out_of_window_l <= '0'; - out_of_window_h <= '0'; - out_of_window_error <= '0'; - ts_window_lower_thr <= (others => '0'); + d_data_o <= (others => '0'); + d_data_clk_o <= '0'; + out_of_window_l <= '0'; + out_of_window_h <= '0'; + out_of_window_error <= '0'; + ts_window_lower_thr <= (others => '0'); + out_of_window_error_ctr <= (others => '0'); else - data_o <= (others => '0'); - data_clk_o <= '0'; - out_of_window_l <= '0'; - out_of_window_h <= '0'; - out_of_window_error <= '0'; - ch_status_cmd_pr <= CS_NONE; - - histogram_fill_o <= '0'; - histogram_bin_o <= (others => '0'); - histogram_adc_o <= (others => '0'); - window_lower_thr := timestamp_fpga - cts_trigger_delay; + d_data_o <= (others => '0'); + d_data_clk_o <= '0'; + out_of_window_l <= '0'; + out_of_window_h <= '0'; + out_of_window_error <= '0'; + ch_status_cmd_pr <= CS_NONE; + + histogram_fill_o <= '0'; + histogram_bin_o <= (others => '0'); + histogram_adc_o <= (others => '0'); ----------------------------------------------------------------------- -- Calculate Thresholds and values for FIFO Delay ----------------------------------------------------------------------- + + window_lower_thr := timestamp_fpga - cts_trigger_delay; + if (ts_window_offset(11) = '1') then ts_window_offset_unsigned := (unsigned(ts_window_offset) xor x"fff") + 1; @@ -253,20 +262,18 @@ begin window_lower_thr + resize(ts_window_width, 12); ts_window_check_value := unsigned(TIMESTAMP_IN(13 downto 2)) - window_lower_thr; + + -- Timestamp to be stored + deltaTStore(13 downto 2) := ts_window_check_value; + deltaTStore( 1 downto 0) := unsigned(TIMESTAMP_IN(1 downto 0)); ----------------------------------------------------------------------- -- Validate incomming Data ----------------------------------------------------------------------- if (DATA_CLK_IN = '1') then if (store_to_fifo = '1') then - -- Timestamp to be stored - + if (readout_mode(2) = '0') then - -- Timestamp to be stored - deltaTStore(13 downto 2) := ts_window_check_value; - deltaTStore( 1 downto 0) := - "00" - unsigned(TIMESTAMP_IN(1 downto 0)); - -- TS Window Active --> do TS check if (ts_window_check_value(11) = '1') then @@ -284,89 +291,103 @@ begin -- TS in between Window: Set WAIT Bit in LUT and Take Data channel_index <= CHANNEL_IN; ch_status_cmd_pr <= CS_SET_WAIT; - data_clk_o <= '1'; case readout_mode(1 downto 0) is when "00" => -- RefValue + TS window filter + ovfl valid + parity valid if (TIMESTAMP_STATUS_IN(2) = '0' and TIMESTAMP_STATUS_IN(0) = '0') then - data_o(11 downto 0) <= deltaTStore(11 downto 0); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_o(11 downto 0) <= deltaTStore(11 downto 0); + d_data_o(23 downto 12) <= ADC_DATA_IN; + d_data_o(30 downto 24) <= CHANNEL_IN; + d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_clk_o <= '1'; end if; when "01" => -- RefValue + TS window filter + ovfl and pileup valid -- + parity valid - if (TIMESTAMP_STATUS_IN(2 downto 1) = "000") then - data_o(11 downto 0) <= deltaTStore(11 downto 0); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= TIMESTAMP_STATUS_IN(1); + if (TIMESTAMP_STATUS_IN = "000") then + d_data_o(11 downto 0) <= deltaTStore(11 downto 0); + d_data_o(23 downto 12) <= ADC_DATA_IN; + d_data_o(30 downto 24) <= CHANNEL_IN; + d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_clk_o <= '1'; end if; + -- when "11" => + -- -- RefValue + TS window filter + ovfl and pileup valid + -- -- + parity valid + -- if (TIMESTAMP_STATUS_IN = "000") then + -- d_data_o(11 downto 0) <= deltaTStore(11 downto 0); + -- d_data_o(23 downto 12) <= ADC_DATA_IN; + -- d_data_o(30 downto 24) <= CHANNEL_IN; + -- d_data_o(30) <= TIMESTAMP_STATUS_IN(0); + -- d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + -- d_data_clk_o <= '1'; + -- end if; + when others => -- RefValue + TS window filter + ignore status - data_o(11 downto 0) <= deltaTStore(11 downto 0); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= TIMESTAMP_STATUS_IN(1); - + d_data_o(11 downto 0) <= deltaTStore(11 downto 0); + d_data_o(23 downto 12) <= ADC_DATA_IN; + d_data_o(30 downto 24) <= CHANNEL_IN; + d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_clk_o <= '1'; end case; else -- TS Window Error condition, do nothing - out_of_window_error <= '0'; + out_of_window_error <= '0'; + if (out_of_window_error_ctr_clear = '0') then + out_of_window_error_ctr <= out_of_window_error_ctr + 1; + end if; end if; else - -- Timestamp to be stored - deltaTStore(13 downto 2) := - (timestamp_fpga - cts_trigger_delay) - - unsigned(TIMESTAMP_IN(13 downto 2)); - deltaTStore( 1 downto 0) := - "00" - unsigned(TIMESTAMP_IN(1 downto 0)); - - -- TS Window Inactive,take data anyhow - data_clk_o <= '1'; - + -- TS Window Inactive, take data anyhow case readout_mode(1 downto 0) is when "00" => -- RefValue + ovfl valid + parity valid if (TIMESTAMP_STATUS_IN(2) = '0' and TIMESTAMP_STATUS_IN(0) = '0') then - data_o(11 downto 0) <= deltaTStore(11 downto 0); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_o(11 downto 0) <= deltaTStore(11 downto 0); + d_data_o(23 downto 12) <= ADC_DATA_IN; + d_data_o(30 downto 24) <= CHANNEL_IN; + d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_clk_o <= '1'; end if; when "01" => -- RefValue + ovfl and pileup valid -- + parity valid - if (TIMESTAMP_STATUS_IN(2 downto 1) = "000") then - data_o(11 downto 0) <= deltaTStore(11 downto 0); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= TIMESTAMP_STATUS_IN(1); + if (TIMESTAMP_STATUS_IN = "000") then + d_data_o(11 downto 0) <= deltaTStore(11 downto 0); + d_data_o(23 downto 12) <= ADC_DATA_IN; + d_data_o(30 downto 24) <= CHANNEL_IN; + d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_clk_o <= '1'; end if; when others => -- RefValue + ignore status - data_o(11 downto 0) <= deltaTStore(11 downto 0); - data_o(23 downto 12) <= ADC_DATA_IN; - data_o(30 downto 24) <= CHANNEL_IN; - data_o(31) <= TIMESTAMP_STATUS_IN(1); - + d_data_o(11 downto 0) <= deltaTStore(11 downto 0); + d_data_o(23 downto 12) <= ADC_DATA_IN; + d_data_o(30 downto 24) <= CHANNEL_IN; + d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_clk_o <= '1'; + end case; end if; + + if (out_of_window_error_ctr_clear = '1') then + out_of_window_error_ctr <= (others => '0'); + end if; -- Fill Histogram - histogram_fill_o <= '1'; - histogram_bin_o <= CHANNEL_IN; - histogram_adc_o <= ADC_DATA_IN; + histogram_fill_o <= '1'; + histogram_bin_o <= CHANNEL_IN; + histogram_adc_o <= ADC_DATA_IN; end if; end if; @@ -461,7 +482,7 @@ begin when "001" => t_data_o(23 downto 22) <= "01"; when "100" => t_data_o(23 downto 22) <= "10"; when "101" => t_data_o(23 downto 22) <= "11"; - when others => t_data_o(23 downto 22) <= "11"; + when others => t_data_o(23 downto 22) <= "11"; end case; t_data_o(31 downto 24) <= BOARD_ID(7 downto 0); t_data_clk_o <= '1'; @@ -608,25 +629,27 @@ begin begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - slv_data_out_o <= (others => '0'); - slv_ack_o <= '0'; - slv_unknown_addr_o <= '0'; - slv_no_more_data_o <= '0'; - - ts_window_offset <= (others => '0'); - ts_window_width <= "0000110010"; -- 50 - cts_trigger_delay <= x"0c8"; - readout_mode_r <= "000"; - readout_time_max <= x"3e8"; - fpga_timestamp_offset <= (others => '0'); + slv_data_out_o <= (others => '0'); + slv_ack_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; + + ts_window_offset <= (others => '0'); + ts_window_width <= "0000110010"; -- 50 + cts_trigger_delay <= x"0c8"; + readout_mode_r <= "000"; + readout_time_max <= x"3e8"; + fpga_timestamp_offset <= (others => '0'); + out_of_window_error_ctr_clear <= '0'; else - slv_data_out_o <= (others => '0'); - slv_unknown_addr_o <= '0'; - slv_no_more_data_o <= '0'; + slv_data_out_o <= (others => '0'); + slv_unknown_addr_o <= '0'; + slv_no_more_data_o <= '0'; cts_trigger_delay(11 downto 10) <= (others => '0'); readout_time_max(11 downto 10) <= (others => '0'); - + out_of_window_error_ctr_clear <= '0'; + if (SLV_READ_IN = '1') then case SLV_ADDR_IN is when x"0000" => @@ -680,6 +703,11 @@ begin slv_data_out_o(31 downto 12) <= (others => '0'); slv_ack_o <= '1'; + when x"0009" => + slv_data_out_o(15 downto 0) <= out_of_window_error_ctr; + slv_data_out_o(31 downto 16) <= (others => '0'); + slv_ack_o <= '1'; + when x"000a" => slv_data_out_o(7 downto 0) <= std_logic_vector(data_fifo_delay_o); @@ -746,7 +774,11 @@ begin when x"0005" => fpga_timestamp_offset(11 downto 0) <= unsigned(SLV_DATA_IN(11 downto 0)); - slv_ack_o <= '1'; + slv_ack_o <= '1'; + + when x"0009" => + out_of_window_error_ctr_clear <= '1'; + slv_ack_o <= '1'; when others => slv_unknown_addr_o <= '1'; @@ -763,9 +795,12 @@ begin -- Output Signals ----------------------------------------------------------------------------- + data_clk_o <= d_data_clk_o or t_data_clk_o; + data_o <= d_data_o or t_data_o; + TRIGGER_BUSY_OUT <= trigger_busy_o; DATA_OUT <= data_o or t_data_o; - DATA_CLK_OUT <= data_clk_o or t_data_clk_o; + DATA_CLK_OUT <= data_clk_o; NOMORE_DATA_OUT <= nomore_data_o; DATA_FIFO_DELAY_OUT <= std_logic_vector(data_fifo_delay_o); diff --git a/nxyter/source/nxyter_components.vhd b/nxyter/source/nxyter_components.vhd index ed62f29..4587867 100644 --- a/nxyter/source/nxyter_components.vhd +++ b/nxyter/source/nxyter_components.vhd @@ -10,35 +10,28 @@ package nxyter_components is component nXyter_FEE_board generic ( - BOARD_ID : std_logic_vector(15 downto 0) - ); + BOARD_ID : std_logic_vector(15 downto 0)); port ( CLK_IN : in std_logic; RESET_IN : in std_logic; - CLK_NX_MAIN_IN : in std_logic; CLK_ADC_IN : in std_logic; PLL_NX_CLK_LOCK_IN : in std_logic; PLL_ADC_CLK_LOCK_IN : in std_logic; NX_DATA_CLK_TEST_IN : in std_logic; - TRIGGER_OUT : out std_logic; - I2C_SDA_INOUT : inout std_logic; I2C_SCL_INOUT : inout std_logic; I2C_SM_RESET_OUT : out std_logic; I2C_REG_RESET_OUT : out std_logic; - SPI_SCLK_OUT : out std_logic; SPI_SDIO_INOUT : inout std_logic; SPI_CSB_OUT : out std_logic; - NX_DATA_CLK_IN : in std_logic; NX_TIMESTAMP_IN : in std_logic_vector (7 downto 0); NX_RESET_OUT : out std_logic; NX_TESTPULSE_OUT : out std_logic; NX_TIMESTAMP_TRIGGER_OUT : out std_logic; - ADC_FCLK_IN : in std_logic_vector(1 downto 0); ADC_DCLK_IN : in std_logic_vector(1 downto 0); ADC_SAMPLE_CLK_OUT : out std_logic; @@ -46,7 +39,7 @@ package nxyter_components is ADC_B_IN : in std_logic_vector(1 downto 0); ADC_NX_IN : in std_logic_vector(1 downto 0); ADC_D_IN : in std_logic_vector(1 downto 0); - + TIMING_TRIGGER_IN : in std_logic; LVL1_TRG_DATA_VALID_IN : in std_logic; LVL1_VALID_TIMING_TRG_IN : in std_logic; LVL1_VALID_NOTIMING_TRG_IN : in std_logic; @@ -56,14 +49,12 @@ package nxyter_components is LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0); LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0); LVL1_INT_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); - FEE_TRG_RELEASE_OUT : out std_logic; FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0); FEE_DATA_OUT : out std_logic_vector(31 downto 0); FEE_DATA_WRITE_OUT : out std_logic; FEE_DATA_FINISHED_OUT : out std_logic; FEE_DATA_ALMOST_FULL_IN : in std_logic; - REGIO_ADDR_IN : in std_logic_vector(15 downto 0); REGIO_DATA_IN : in std_logic_vector(31 downto 0); REGIO_DATA_OUT : out std_logic_vector(31 downto 0); @@ -74,11 +65,10 @@ package nxyter_components is REGIO_WRITE_ACK_OUT : out std_logic; REGIO_NO_MORE_DATA_OUT : out std_logic; REGIO_UNKNOWN_ADDR_OUT : out std_logic; - DEBUG_LINE_OUT : out std_logic_vector(15 downto 0) ); end component; - + ------------------------------------------------------------------------------- -- nXyter I2C Interface ------------------------------------------------------------------------------- @@ -539,7 +529,7 @@ component pulse_to_level ); end component; -component pulse_async_trans +component signal_async_to_pulse generic ( NUM_FF : integer range 2 to 4 ); @@ -649,8 +639,8 @@ component nx_fpga_timestamp TRIGGER_IN : in std_logic; TIMESTAMP_CURRENT_OUT : out unsigned(11 downto 0); TIMESTAMP_HOLD_OUT : out unsigned(11 downto 0); - NX_TIMESTAMP_SYNC_OUT : out std_logic; - NX_TIMESTAMP_TRIGGER_OUT : out std_logic; + TIMESTAMP_SYNCED_OUT : out std_logic; + TIMESTAMP_TRIGGER_OUT : out std_logic; SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; SLV_DATA_OUT : out std_logic_vector(31 downto 0); @@ -666,7 +656,9 @@ component nx_trigger_handler port ( CLK_IN : in std_logic; RESET_IN : in std_logic; + NX_MAIN_CLK_IN : in std_logic; NXYTER_OFFLINE_IN : in std_logic; + TIMING_TRIGGER_IN : in std_logic; LVL1_TRG_DATA_VALID_IN : in std_logic; LVL1_VALID_TIMING_TRG_IN : in std_logic; LVL1_VALID_NOTIMING_TRG_IN : in std_logic; @@ -704,6 +696,7 @@ component nx_trigger_generator port ( CLK_IN : in std_logic; RESET_IN : in std_logic; + NX_MAIN_CLK_IN : in std_logic; TRIGGER_IN : in std_logic; TRIGGER_OUT : out std_logic; TS_RESET_OUT : out std_logic; diff --git a/nxyter/source/nxyter_fee_board.vhd b/nxyter/source/nxyter_fee_board.vhd index 969f3db..1316ea8 100644 --- a/nxyter/source/nxyter_fee_board.vhd +++ b/nxyter/source/nxyter_fee_board.vhd @@ -54,8 +54,8 @@ entity nXyter_FEE_board is ADC_NX_IN : in std_logic_vector(1 downto 0); ADC_D_IN : in std_logic_vector(1 downto 0); - -- Event Buffer - --LVL1 trigger to FEE + -- Input Triggers + TIMING_TRIGGER_IN : in std_logic; LVL1_TRG_DATA_VALID_IN : in std_logic; LVL1_VALID_TIMING_TRG_IN : in std_logic; LVL1_VALID_NOTIMING_TRG_IN : in std_logic; -- Status + Info TypE @@ -234,7 +234,7 @@ begin 6 => x"0120", -- Data Validate 7 => x"0160", -- Trigger Handler 8 => x"0180", -- Trigger Validate - 9 => x"0200", -- NX Register Setup + 9 => x"0200", -- NX Setup 10 => x"0800", -- NX Histograms 11 => x"0020", -- Debug Handler 12 => x"0130", -- Data Delay @@ -248,9 +248,9 @@ begin 4 => 0, -- SPI Master 5 => 3, -- Trigger Generator 6 => 4, -- Data Validate - 7 => 2, -- Trigger Handler + 7 => 4, -- Trigger Handler 8 => 4, -- Trigger Validate - 9 => 8, -- NX Register Setup + 9 => 8, -- NX Setup 10 => 9, -- NX Histograms 11 => 0, -- Debug Handler 12 => 1, -- Data Delay @@ -326,7 +326,7 @@ begin DEBUG_OUT => debug_line(0) ); - nx_register_setup_1: nx_setup + nx_setup_1: nx_setup port map ( CLK_IN => CLK_IN, RESET_IN => RESET_IN, @@ -420,8 +420,8 @@ begin TRIGGER_IN => timestamp_trigger, TIMESTAMP_CURRENT_OUT => timestamp_current, TIMESTAMP_HOLD_OUT => timestamp_hold, - NX_TIMESTAMP_SYNC_OUT => nx_timestamp_sync, - NX_TIMESTAMP_TRIGGER_OUT => nx_timestamp_trigger_o, + TIMESTAMP_SYNCED_OUT => nx_timestamp_sync, + TIMESTAMP_TRIGGER_OUT => nx_timestamp_trigger_o, SLV_READ_IN => open, SLV_WRITE_IN => open, SLV_DATA_OUT => open, @@ -441,8 +441,10 @@ begin port map ( CLK_IN => CLK_IN, RESET_IN => RESET_IN, + NX_MAIN_CLK_IN => CLK_NX_MAIN_IN, NXYTER_OFFLINE_IN => nxyter_offline, + TIMING_TRIGGER_IN => TIMING_TRIGGER_IN, LVL1_TRG_DATA_VALID_IN => LVL1_TRG_DATA_VALID_IN, LVL1_VALID_TIMING_TRG_IN => LVL1_VALID_TIMING_TRG_IN, LVL1_VALID_NOTIMING_TRG_IN => LVL1_VALID_NOTIMING_TRG_IN, @@ -491,6 +493,7 @@ begin port map ( CLK_IN => CLK_IN, RESET_IN => RESET_IN, + NX_MAIN_CLK_IN => CLK_NX_MAIN_IN, TRIGGER_IN => trigger_testpulse, TRIGGER_OUT => trigger_intern, TS_RESET_OUT => nx_ts_reset_2, diff --git a/nxyter/source/pulse_async_trans.vhd b/nxyter/source/pulse_async_trans.vhd deleted file mode 100644 index bfb9660..0000000 --- a/nxyter/source/pulse_async_trans.vhd +++ /dev/null @@ -1,57 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.nxyter_components.all; - -entity pulse_async_trans is - generic ( - NUM_FF : integer range 2 to 4 := 2 - ); - port ( - CLK_IN : in std_logic; - RESET_IN : in std_logic; - PULSE_A_IN : in std_logic; - PULSE_OUT : out std_logic - ); - -end entity; - -architecture Behavioral of pulse_async_trans is - signal pulse_ff : std_logic_vector(NUM_FF - 1 downto 0); - signal pulse_o : std_logic; - -begin - - ----------------------------------------------------------------------------- - -- Clock CLK_IN Domain - ----------------------------------------------------------------------------- - - PROC_SYNC_PULSE: process(CLK_IN) - begin - if( rising_edge(CLK_IN) ) then - pulse_ff(NUM_FF - 1) <= PULSE_A_IN; - if( RESET_IN = '1' ) then - for i in NUM_FF - 2 downto 0 loop - pulse_ff(i) <= '0'; - end loop; - else - for i in NUM_FF - 2 downto 0 loop - pulse_ff(i) <= pulse_ff(i + 1); - end loop; - end if; - end if; - end process PROC_SYNC_PULSE; - - level_to_pulse_1: level_to_pulse - port map ( - CLK_IN => CLK_IN, - RESET_IN => RESET_IN, - LEVEL_IN => pulse_ff(0), - PULSE_OUT => pulse_o - ); - - -- Outputs - PULSE_OUT <= pulse_o; - -end Behavioral; diff --git a/nxyter/source/pulse_dtrans.vhd b/nxyter/source/pulse_dtrans.vhd index c188f5f..68b05e3 100644 --- a/nxyter/source/pulse_dtrans.vhd +++ b/nxyter/source/pulse_dtrans.vhd @@ -44,7 +44,7 @@ begin -- Clock B Domain ----------------------------------------------------------------------------- - pulse_async_trans_1: pulse_async_trans + signal_async_to_pulse_1: signal_async_to_pulse generic map ( NUM_FF => 2 ) diff --git a/nxyter/source/registers.txt b/nxyter/source/registers.txt index 11c3c4e..87d8344 100644 --- a/nxyter/source/registers.txt +++ b/nxyter/source/registers.txt @@ -18,13 +18,15 @@ 0x8243 : w Write Memory to Trim DAC Register(129 deep FIFO) -- Trigger Generator -0x8141 : r/w Length of Trigger TestPulse (12 Bit, in 10ns) -0x8145 : r Testpulse Rate (in Hz) +0x8140 : r/w Length of Trigger TestPulse (12 Bit, in 4ns) +0x8141 : r Testpulse Rate (in Hz) -- Trigger Handler -0x8160 : r/w Bit 7-0 : Delay Testpulse Signal after Trigger (10ns) -0x8161 : r/w Bit 0 : Enable Testpulse Signal (default: off) -0x8162 : r : Accepted Trigger Rate (in Hz) +0x8160 : r/w Enable Testpulse Signal (default: off) +0x8161 : r/w Delay Testpulse Signal after Trigger (12 Bit, in 10ns) +0x8162 : r Accepted Trigger Rate (in Hz) +0x8163 : r/w r: Invalid Timing Trigger Counter + w: clear Counter -- NX Data Receiver 0x8500 : r current Timestamp FIFO value @@ -34,19 +36,18 @@ 2: fifo_almost_empty 3..29: ignore 31: nx_frame_synced - w: adc reset 0x8502 : r/w r: Resync Counter(12 Bit) w: clear Resync Counter 0x8503 : r/w r: Parity Error Counter (12 Bit) w: clear Parity Error Counter 0x8504 : r/w ADC Sampling PLL Clock Not Lock Counter w: clear counter -0x8505 : r/w johnson_counter_sync(2 Bit), do not touch, experts only register +0x8505 : r/w johnson_counter_sync (2 Bit), do not touch, experts only register 0x8506 : r/w PLL ADC Sampling Clock DPHASE (4 Bit) 0x8507 : r/w PLL ADC Sampling Clock FINEDELB (4 Bit) 0x8508 : r current ADC FIFO value -0x8509 : w PLL ADC Sampling CLK Reset +0x8509 : w Reset ADC Handler 0x850a : r/w Enable Test ADC Input Data Error Test 0x850b : r ADC Input Data Error Counter (16 Bit) (only valid in case of 0x8509 is 1, see line above) @@ -58,9 +59,17 @@ 2: ADC Value Testchannel 3: ADC Reset Handler +-- NX Data Validate +0x8120 : r/w Invalid Frame Counter (16 bit) / w: clear all counters +0x8121 : r Overflow Counter (16 bit) +0x8122 : r Pileup Counter (16 bit) +0x8123 : r Parity Error Counter (16 bit) +0x8124 : r Nxyter Hit Rate (in Hz) +0x8125 : r Frame Rate (in Hz) + -- NX Data Delay -0x8130 : r FIFO Delay, i.e. Trigger Delay (8 Bit, in 32ns). - Calculation is based on CTS Trigger Delay +0x8130 : r FIFO Delay, i.e. Trigger Delay (8 Bit, in 32ns). + Calculation is based on CTS Trigger Delay (see NX Trigger Validate) -- NX Trigger Validate @@ -87,6 +96,8 @@ 0x8186 : r Busy Time Counter (12 Bit, in 10ns) 0x8187 : r timestamp_ref 0x8188 : r window_lower_thr +0x8189 : r/w Out of Window Error Counter (16 Bit) + w: Clear Counter 0x818a : r data_fifo_delay (7 Bit, in 32ns) 0x818b : r done counter ch 0..31 0x818c : r done counter ch 32..63 @@ -144,9 +155,10 @@ CTS Trigger [CT] _____________________________________| |_____________ FPGA TS Trigger [FT] _________________________________________| |_________ | CTS+FPGA Trigger Delay |--------------------| - | | -FPGA TS-Ref stored in Event Header | | - | | + | +FPGA TS-Ref stored | +in Event Header -----------|--------------------| + | Trigger Window Offset(-) |----------| | Trigger Window Width(-) |----------------| | Timestamps stored in Event(-) |--|---|--|-||--|---------------| @@ -156,7 +168,5 @@ Trigger Window Offset(+) |-----| | Trigger Window Width(+) |---------| | Timestamps stored in Event(+) -----------------|--||--|-|-----| -TIME ----------------------------------------------------------------------> - - + ---------------------------------------------------------------> Time t diff --git a/nxyter/source/signal_async_trans.vhd b/nxyter/source/signal_async_trans.vhd index edfb6ec..546c6cd 100644 --- a/nxyter/source/signal_async_trans.vhd +++ b/nxyter/source/signal_async_trans.vhd @@ -28,21 +28,19 @@ begin PROC_SYNC_SIGNAL: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then - signal_ff(NUM_FF - 1) <= SIGNAL_A_IN; + signal_ff(NUM_FF - 1) <= SIGNAL_A_IN; if( RESET_IN = '1' ) then - for i in NUM_FF - 2 downto 0 loop - signal_ff(i) <= '0'; - end loop; + signal_ff(NUM_FF - 2 downto 0) <= (others => '0'); else for i in NUM_FF - 2 downto 0 loop - signal_ff(i) <= signal_ff(i + 1); + signal_ff(i) <= signal_ff(i + 1); end loop; end if; end if; end process PROC_SYNC_SIGNAL; - signal_o <= signal_ff(0); + signal_o <= signal_ff(0); -- Outpu Signals - SIGNAL_OUT <= signal_o; + SIGNAL_OUT <= signal_o; end Behavioral; diff --git a/nxyter/trb3_periph.prj b/nxyter/trb3_periph.prj index fb9c00b..a61915d 100644 --- a/nxyter/trb3_periph.prj +++ b/nxyter/trb3_periph.prj @@ -156,7 +156,7 @@ add_file -vhdl -lib "work" "source/nxyter_components.vhd" add_file -vhdl -lib "work" "source/level_to_pulse.vhd" add_file -vhdl -lib "work" "source/pulse_to_level.vhd" add_file -vhdl -lib "work" "source/pulse_dtrans.vhd" -add_file -vhdl -lib "work" "source/pulse_async_trans.vhd" +add_file -vhdl -lib "work" "source/signal_async_to_pulse.vhd" add_file -vhdl -lib "work" "source/signal_async_trans.vhd" add_file -vhdl -lib "work" "source/gray_decoder.vhd" add_file -vhdl -lib "work" "source/gray_encoder.vhd" diff --git a/nxyter/trb3_periph.vhd b/nxyter/trb3_periph.vhd index 4373737..bd60e0b 100644 --- a/nxyter/trb3_periph.vhd +++ b/nxyter/trb3_periph.vhd @@ -22,7 +22,8 @@ entity trb3_periph is CLK_PCLK_RIGHT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! --Trigger TRIGGER_LEFT : in std_logic; --left side trigger input from fan-out - TRIGGER_RIGHT : in std_logic; --right side trigger input from fan-out + TRIGGER_RIGHT : in std_logic; --Den Da nehmen sagt Jan midestend + -- , right side trigger input from fan-out --Serdes CLK_SERDES_INT_LEFT : in std_logic; --Clock Manager 1/(1357), off, 125 MHz possible CLK_SERDES_INT_RIGHT : in std_logic; --Clock Manager 2/(1357), 200 MHz, only in case of problems @@ -741,6 +742,7 @@ begin ADC_D_IN(0) => NX1_ADC_D_IN, ADC_D_IN(1) => NX1B_ADC_D_IN, + TIMING_TRIGGER_IN => TRIGGER_RIGHT, LVL1_TRG_DATA_VALID_IN => trg_data_valid_i, LVL1_VALID_TIMING_TRG_IN => trg_timing_valid_i, LVL1_VALID_NOTIMING_TRG_IN => trg_notiming_valid_i, @@ -820,7 +822,8 @@ begin ADC_NX_IN(1) => NX2B_ADC_NX_IN, ADC_D_IN(0) => NX2_ADC_D_IN, ADC_D_IN(1) => NX2B_ADC_D_IN, - + + TIMING_TRIGGER_IN => TRIGGER_RIGHT, LVL1_TRG_DATA_VALID_IN => trg_data_valid_i, LVL1_VALID_TIMING_TRG_IN => trg_timing_valid_i, LVL1_VALID_NOTIMING_TRG_IN => trg_notiming_valid_i, diff --git a/nxyter/trb3_periph_constraints.lpf b/nxyter/trb3_periph_constraints.lpf index 5468e66..6cbf6d3 100644 --- a/nxyter/trb3_periph_constraints.lpf +++ b/nxyter/trb3_periph_constraints.lpf @@ -68,9 +68,11 @@ MULTICYCLE FROM CELL "THE_RESET_HANDLER/final_reset*" 20 ns; MULTICYCLE FROM CLKNET "nXyter_FEE_board_1/nx_data_receiver_1/adc_ad9222_1/un1_adc_ad9222*" TO CLKNET "clk_100_i_c" 10 ns; MULTICYCLE FROM CLKNET "nXyter_FEE_board_0/nx_data_receiver_1/adc_ad9222_1/un1_adc_ad9222*" TO CLKNET "clk_100_i_c" 10 ns; +#MULTICYCLE TO CELL "nXyter_FEE_board_0/nx_fpga_timestamp_1/pulse_dtrans_2/pulse_async_trans_1/pulse_ff_1" 5 ns; MULTICYCLE TO CELL "nXyter_FEE_board_0/nx_fpga_timestamp_1/timestamp_sync_x" 5 ns; MULTICYCLE TO CELL "nXyter_FEE_board_0/nx_fpga_timestamp_1/trigger_x" 5 ns; +#MULTICYCLE TO CELL "nXyter_FEE_board_1/nx_fpga_timestamp_1/pulse_dtrans_2/pulse_async_trans_1/pulse_ff_1" 5 ns; MULTICYCLE TO CELL "nXyter_FEE_board_1/nx_fpga_timestamp_1/timestamp_sync_x" 5 ns; MULTICYCLE TO CELL "nXyter_FEE_board_1/nx_fpga_timestamp_1/trigger_x" 5 ns; @@ -80,11 +82,14 @@ MULTICYCLE TO CELL "nXyter_FEE_board_1/nx_fpga_timestamp_1/trigger_x" 5 ns; # look at .par and .twr.setup file for clocks # and .mrp or errors -PROHIBIT PRIMARY NET "NX1_DATA_CLK_IN_c"; -PROHIBIT SECONDARY NET "NX1_DATA_CLK_IN_c"; -PROHIBIT PRIMARY NET "NX2_DATA_CLK_IN_c"; -PROHIBIT SECONDARY NET "NX2_DATA_CLK_IN_c"; +#DEFINE PORT GROUP "NX1_CLK_IN" "NX1_DATA_CLK_*"; +PROHIBIT PRIMARY NET "NX1_DATA_CLK_*"; +PROHIBIT SECONDARY NET "NX1_DATA_CLK_*"; + +#DEFINE PORT GROUP "NX1_CLK_IN" "NX1_DATA_CLK_*"; +PROHIBIT PRIMARY NET "NX2_DATA_CLK_*"; +PROHIBIT SECONDARY NET "NX2_DATA_CLK_*"; DEFINE PORT GROUP "NX1_IN" "NX1_TIMESTAMP_*"; INPUT_SETUP GROUP "NX1_IN" 3.0 ns HOLD 3.0 ns CLKPORT="NX1_DATA_CLK_IN";