From 2683fc3c8a733ae364245a7ac8881c5ccaceaea4 Mon Sep 17 00:00:00 2001 From: Ludwig Maier Date: Thu, 17 Jul 2014 00:52:26 +0200 Subject: [PATCH] nxyter ts/adc timestamp delay auto adjust entity implemented --- nxyter/source/nx_data_receiver.vhd | 98 +++++--- nxyter/source/nx_data_validate.vhd | 211 +++++++++------- nxyter/source/nx_status_event.vhd | 24 +- nxyter/source/nx_trigger_handler.vhd | 347 ++++++++++++++++++-------- nxyter/source/nx_trigger_validate.vhd | 20 +- nxyter/source/nxyter_components.vhd | 53 ++-- nxyter/source/nxyter_fee_board.vhd | 64 ++--- nxyter/source/registers.txt | 8 +- nxyter/trb3_periph_constraints.lpf | 4 +- nxyter/trb3_periph_multi.p2t | 2 +- nxyter/trb3_periph_nxyter.lpf | 34 +-- 11 files changed, 561 insertions(+), 304 deletions(-) diff --git a/nxyter/source/nx_data_receiver.vhd b/nxyter/source/nx_data_receiver.vhd index b944e3c..c204049 100644 --- a/nxyter/source/nx_data_receiver.vhd +++ b/nxyter/source/nx_data_receiver.vhd @@ -37,7 +37,7 @@ entity nx_data_receiver is -- Outputs DATA_OUT : out std_logic_vector(43 downto 0); DATA_CLK_OUT : out std_logic; - + -- Slave bus SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; @@ -47,7 +47,8 @@ entity nx_data_receiver is SLV_ACK_OUT : out std_logic; SLV_NO_MORE_DATA_OUT : out std_logic; SLV_UNKNOWN_ADDR_OUT : out std_logic; - + + ADC_TR_ERROR_IN : in std_logic; DISABLE_ADC_OUT : out std_logic; ERROR_OUT : out std_logic; DEBUG_OUT : out std_logic_vector(15 downto 0) @@ -239,7 +240,11 @@ architecture Behavioral of nx_data_receiver is signal johnson_counter_sync_r : unsigned(1 downto 0); signal pll_adc_sample_clk_dphase_r : unsigned(3 downto 0); signal pll_adc_sample_clk_finedelb_r : unsigned(3 downto 0); + signal nx_timestamp_delay_adjust : std_logic; signal nx_timestamp_delay_r : unsigned(2 downto 0); + signal nx_timestamp_delay_a : unsigned(2 downto 0); + signal nx_timestamp_delay_s : unsigned(2 downto 0); + signal nx_timestamp_delay_actr : unsigned(15 downto 0); signal nx_frame_word_delay_rr : unsigned(1 downto 0); signal nx_frame_word_delay_r : unsigned(1 downto 0); signal fifo_full_rr : std_logic; @@ -562,7 +567,7 @@ begin PROC_PLL_LOCK_COUNTER: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then if( RESET_IN = '1' or pll_adc_not_lock_ctr_clear = '1') then pll_adc_not_lock_f <= (others => '0'); pll_adc_not_lock_ctr <= (others => '0'); @@ -744,7 +749,7 @@ begin PROC_NX_SHIFT_REGISTER_DELAY: process(NX_TIMESTAMP_CLK_IN) begin if (rising_edge(NX_TIMESTAMP_CLK_IN)) then - nx_timestamp_delay_f <= nx_timestamp_delay_r; + nx_timestamp_delay_f <= nx_timestamp_delay_s; if( RESET_NX_TIMESTAMP_CLK_IN = '1' ) then nx_timestamp_delay <= "010"; nx_shift_register_delay <= "011011"; -- 27 @@ -776,7 +781,7 @@ begin -- Merge TS Data 8bit to 32Bit Timestamp Frame PROC_8_TO_32_BIT: process(NX_TIMESTAMP_CLK_IN) begin - if (rising_edge(NX_TIMESTAMP_CLK_IN) ) then + if (rising_edge(NX_TIMESTAMP_CLK_IN)) then case frame_byte_pos is when "11" => nx_frame_word_t(31 downto 24) <= nx_frame_word_s; nx_frame_clk_t <= '0'; @@ -805,7 +810,7 @@ begin -- TS Frame Sync process PROC_SYNC_TO_NX_FRAME: process(NX_TIMESTAMP_CLK_IN) begin - if (rising_edge(NX_TIMESTAMP_CLK_IN) ) then + if (rising_edge(NX_TIMESTAMP_CLK_IN)) then if( RESET_NX_TIMESTAMP_CLK_IN = '1' ) then frame_byte_pos <= "11"; rs_sync_set <= '0'; @@ -844,7 +849,7 @@ begin -- RS FlipFlop to hold Sync Status PROC_RS_FRAME_SYNCED: process(NX_TIMESTAMP_CLK_IN) begin - if (rising_edge(NX_TIMESTAMP_CLK_IN) ) then + if (rising_edge(NX_TIMESTAMP_CLK_IN)) then if (RESET_NX_TIMESTAMP_CLK_IN = '1') then nx_frame_synced <= '0'; else @@ -892,7 +897,7 @@ begin ----------------------------------------------------------------------------- PROC_NX_TIMESTAMP_FRAME_DELAY: process(NX_TIMESTAMP_CLK_IN) begin - if (rising_edge(NX_TIMESTAMP_CLK_IN) ) then + if (rising_edge(NX_TIMESTAMP_CLK_IN)) then nx_frame_word_delayed_t(0) <= nx_frame_word; nx_frame_clk_delayed_t(0) <= nx_frame_clk; @@ -912,7 +917,7 @@ begin PROC_NX_FRAME_WORD_DELAY_AUTO_SETUP: process(NX_TIMESTAMP_CLK_IN) begin - if (rising_edge(NX_TIMESTAMP_CLK_IN) ) then + if (rising_edge(NX_TIMESTAMP_CLK_IN)) then nx_frame_word_delay <= nx_frame_word_delay_f; adc_data_clk_last(0) <= adc_data_s_clk; @@ -1031,7 +1036,7 @@ begin PROC_ADC_DATA_BIT_SHIFT: process(NX_TIMESTAMP_CLK_IN) variable adcval : unsigned(11 downto 0) := (others => '0'); begin - if (rising_edge(NX_TIMESTAMP_CLK_IN) ) then + if (rising_edge(NX_TIMESTAMP_CLK_IN)) then if (adc_bit_shift(3) = '1') then adcval := unsigned(adc_data) rol to_integer(adc_bit_shift(2 downto 0)); @@ -1062,7 +1067,7 @@ begin PROC_DATA_MERGE_HANDLER: process(NX_TIMESTAMP_CLK_IN) begin - if (rising_edge(NX_TIMESTAMP_CLK_IN) ) then + if (rising_edge(NX_TIMESTAMP_CLK_IN)) then if (RESET_NX_TIMESTAMP_CLK_IN = '1' or merge_handler_reset = '1') then merge_timeout_ctr <= (others => '0'); merge_timeout_error <= '0'; @@ -1119,7 +1124,7 @@ begin PROC_NX_FIFO_READ_ENABLE: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then fifo_data_clk_tt <= fifo_read_enable; if(RESET_IN = '1') then fifo_data_clk_t <= '0'; @@ -1134,7 +1139,7 @@ begin PROC_DATA_OUTPUT_HANDLER: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then if(RESET_IN = '1') then data_o <= (others => '0'); data_clk_o <= '0'; @@ -1171,7 +1176,7 @@ begin -- Counters PROC_RESYNC_COUNTER: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then if (RESET_IN = '1' or reset_resync_ctr = '1') then resync_counter <= (others => '0'); else @@ -1184,7 +1189,7 @@ begin PROC_PARITY_ERROR_COUNTER: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then if (RESET_IN = '1' or reset_parity_error_ctr = '1') then parity_error_counter <= (others => '0'); else @@ -1202,7 +1207,7 @@ begin PROC_RATE_COUNTER: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then if (RESET_IN = '1' or frame_rates_reset = '1') then nx_frame_rate_ctr <= (others => '0'); nx_frame_rate <= (others => '0'); @@ -1343,7 +1348,7 @@ begin PROC_EVENT_ERRORS_PER_SECOND: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then if (RESET_IN = '1' or frame_rates_reset = '1') then adc_dt_error_cur <= '0'; adc_dt_error <= '0'; @@ -1369,7 +1374,7 @@ begin PROC_DATA_STREAM_DELTA_T: process(NX_TIMESTAMP_CLK_IN) begin - if (rising_edge(NX_TIMESTAMP_CLK_IN) ) then + if (rising_edge(NX_TIMESTAMP_CLK_IN)) then if (RESET_NX_TIMESTAMP_CLK_IN = '1') then new_adc_dt_ctr <= (others => '0'); new_timestamp_dt_ctr <= (others => '0'); @@ -1414,7 +1419,7 @@ begin PROC_RESET_HANDLER: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then if( RESET_IN = '1' ) then frame_rates_reset <= '0'; fifo_reset_handler <= '0'; @@ -1716,13 +1721,40 @@ begin end if; end if; end process PROC_ERROR_STATUS; + + PROC_NX_TIMESTAMP_DELAY_ADJUST: process(CLK_IN) + begin + if (rising_edge(CLK_IN)) then + if (RESET_IN = '1') then + nx_timestamp_delay_a <= (others => '0'); + nx_timestamp_delay_actr <= (others => '0'); + else + -- Automatic nx_timestamp_delay adjust + if (nx_timestamp_delay_adjust = '1' and ADC_TR_ERROR_IN = '1') then + if (nx_timestamp_delay_a <= "100") then + nx_timestamp_delay_a <= nx_timestamp_delay_a + 1; + else + nx_timestamp_delay_a <= (others => '0'); + end if; + nx_timestamp_delay_actr <= nx_timestamp_delay_actr + 1; + end if; + + -- Multiplexer + if (nx_timestamp_delay_adjust = '1') then + nx_timestamp_delay_s <= nx_timestamp_delay_a; + else + nx_timestamp_delay_s <= nx_timestamp_delay_r; + end if; + end if; + end if; + end process PROC_NX_TIMESTAMP_DELAY_ADJUST; ----------------------------------------------------------------------------- -- TRBNet Slave Bus ----------------------------------------------------------------------------- PROC_SLAVE_BUS_BUFFER: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then fifo_full_rr <= fifo_full; fifo_empty_rr <= fifo_empty; nx_frame_synced_rr <= nx_frame_synced; @@ -1746,15 +1778,10 @@ begin end if; end process PROC_SLAVE_BUS_BUFFER; - -- Give status info to the TRB Slow Control Channel - - -- Register Info - nx_frame_word_delay_rr <= nx_frame_word_delay_f when rising_edge(CLK_IN); - nx_frame_word_delay_r <= nx_frame_word_delay_rr when rising_edge(CLK_IN); - + -- Slave Bus PROC_SLAVE_BUS: process(CLK_IN) begin - if (rising_edge(CLK_IN) ) then + if (rising_edge(CLK_IN)) then if( RESET_IN = '1' ) then slv_data_out_o <= (others => '0'); slv_ack_o <= '0'; @@ -1767,6 +1794,7 @@ begin pll_adc_sample_clk_dphase_r <= x"d"; pll_adc_sample_clk_finedelb_r <= (others => '0'); pll_adc_not_lock_ctr_clear <= '0'; + nx_timestamp_delay_adjust <= '1'; nx_timestamp_delay_r <= "010"; reset_handler_start_r <= '0'; adc_bit_shift <= x"0"; @@ -1782,7 +1810,7 @@ begin reset_parity_error_ctr <= '0'; pll_adc_not_lock_ctr_clear <= '0'; reset_handler_start_r <= '0'; - + if (SLV_READ_IN = '1') then case SLV_ADDR_IN is when x"0000" => @@ -1874,11 +1902,12 @@ begin when x"0010" => slv_data_out_o(2 downto 0) <= - std_logic_vector(nx_timestamp_delay_r); - slv_data_out_o(3) <= '0'; + std_logic_vector(nx_timestamp_delay_s); slv_data_out_o(5 downto 4) <= std_logic_vector(nx_frame_word_delay_r); - slv_data_out_o(31 downto 6) <= (others => '0'); + slv_data_out_o(14 downto 6) <= (others => '0'); + slv_data_out_o(15) <= nx_timestamp_delay_adjust; + slv_data_out_o(31 downto 16) <= nx_timestamp_delay_actr; slv_ack_o <= '1'; when x"0011" => @@ -1978,10 +2007,9 @@ begin slv_ack_o <= '1'; when x"0010" => - if (unsigned(SLV_DATA_IN(2 downto 0)) < 5) then - nx_timestamp_delay_r <= - unsigned(SLV_DATA_IN(2 downto 0)); - end if; + nx_timestamp_delay_r <= + unsigned(SLV_DATA_IN(2 downto 0)); + nx_timestamp_delay_adjust <= SLV_DATA_IN(15); slv_ack_o <= '1'; when x"0012" => diff --git a/nxyter/source/nx_data_validate.vhd b/nxyter/source/nx_data_validate.vhd index 787877c..bfcdcab 100644 --- a/nxyter/source/nx_data_validate.vhd +++ b/nxyter/source/nx_data_validate.vhd @@ -8,36 +8,37 @@ use work.nxyter_components.all; entity nx_data_validate is port ( - CLK_IN : in std_logic; - RESET_IN : in std_logic; - - -- Inputs - DATA_IN : in std_logic_vector(43 downto 0); - DATA_CLK_IN : in std_logic; - - -- Outputs - TIMESTAMP_OUT : out std_logic_vector(13 downto 0); - CHANNEL_OUT : out std_logic_vector(6 downto 0); - TIMESTAMP_STATUS_OUT : out std_logic_vector(2 downto 0); - ADC_DATA_OUT : out std_logic_vector(11 downto 0); - DATA_CLK_OUT : out std_logic; - - NX_TOKEN_RETURN_OUT : out std_logic; - NX_NOMORE_DATA_OUT : out std_logic; - - -- Slave bus - SLV_READ_IN : in std_logic; - SLV_WRITE_IN : in std_logic; - SLV_DATA_OUT : out std_logic_vector(31 downto 0); - SLV_DATA_IN : in std_logic_vector(31 downto 0); - SLV_ADDR_IN : in std_logic_vector(15 downto 0); - SLV_ACK_OUT : out std_logic; - SLV_NO_MORE_DATA_OUT : out std_logic; - SLV_UNKNOWN_ADDR_OUT : out std_logic; - - DISABLE_ADC_IN : in std_logic; - ERROR_OUT : out std_logic; - DEBUG_OUT : out std_logic_vector(15 downto 0) + CLK_IN : in std_logic; + RESET_IN : in std_logic; + + -- Inputs + DATA_IN : in std_logic_vector(43 downto 0); + DATA_CLK_IN : in std_logic; + + -- Outputs + TIMESTAMP_OUT : out std_logic_vector(13 downto 0); + CHANNEL_OUT : out std_logic_vector(6 downto 0); + TIMESTAMP_STATUS_OUT : out std_logic_vector(2 downto 0); + ADC_DATA_OUT : out std_logic_vector(11 downto 0); + DATA_CLK_OUT : out std_logic; + + NX_TOKEN_RETURN_OUT : out std_logic; + NX_NOMORE_DATA_OUT : out std_logic; + + -- Slave bus + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_ADDR_IN : in std_logic_vector(15 downto 0); + SLV_ACK_OUT : out std_logic; + SLV_NO_MORE_DATA_OUT : out std_logic; + SLV_UNKNOWN_ADDR_OUT : out std_logic; + + ADC_TR_ERROR_OUT : out std_logic; + DISABLE_ADC_IN : in std_logic; + ERROR_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(15 downto 0) ); end entity; @@ -93,10 +94,12 @@ architecture Behavioral of nx_data_validate is signal adc_average_ctr : unsigned(15 downto 0); signal adc_average_sum : unsigned(31 downto 0); signal adc_average : unsigned(11 downto 0); + signal adc_data_last : std_logic_vector(11 downto 0); -- Token Return Average - signal nx_token_return_pipe : std_logic_vector(4 downto 0); + signal nx_token_return_pipe : std_logic_vector(8 downto 0); + signal adc_tr_value_tmp : std_logic_vector(11 downto 0); signal adc_tr_value : std_logic_vector(11 downto 0); signal adc_tr_data_p : unsigned(11 downto 0); signal adc_tr_data_c : unsigned(11 downto 0); @@ -106,6 +109,13 @@ architecture Behavioral of nx_data_validate is signal adc_tr_error : std_logic; signal adc_tr_error_status : std_logic_vector(1 downto 0); signal adc_tr_debug_mode : std_logic; + signal adc_tr_error_o : std_logic; + + type TR_STATES is (S_IDLE, + S_START, + S_END + ); + signal TR_STATE : TR_STATES; -- Config signal readout_type : std_logic_vector(1 downto 0); @@ -129,9 +139,9 @@ architecture Behavioral of nx_data_validate is signal adc_tr_debug_p : std_logic; signal adc_tr_debug_c : std_logic; - - signal lower_limit_r : std_logic_vector(11 downto 0); - + signal adc_tr_value_update : std_logic; + signal state_debug : std_logic_vector(1 downto 0); + begin -- Debug Line @@ -142,14 +152,14 @@ begin DEBUG_OUT(4) <= data_clk_o; DEBUG_OUT(5) <= new_timestamp; DEBUG_OUT(6) <= self_trigger_o; - DEBUG_OUT(7) <= invalid_adc; - DEBUG_OUT(8) <= adc_tr_data_clk; - DEBUG_OUT(9) <= adc_tr_error; - DEBUG_OUT(11 downto 10) <= adc_tr_error_status; - DEBUG_OUT(12) <= adc_tr_debug_p; - DEBUG_OUT(13) <= adc_tr_debug_c; - DEBUG_OUT(14) <= '0'; - DEBUG_OUT(15) <= parity_error; +-- DEBUG_OUT(7) <= invalid_adc; + DEBUG_OUT(7) <= adc_tr_data_clk; + DEBUG_OUT(8) <= adc_tr_error; + DEBUG_OUT(10 downto 9) <= adc_tr_error_status; + DEBUG_OUT(11) <= adc_tr_debug_p; + DEBUG_OUT(12) <= adc_tr_debug_c; + DEBUG_OUT(13) <= adc_tr_value_update; + DEBUG_OUT(15 downto 14) <= state_debug; ----------------------------------------------------------------------------- @@ -264,7 +274,12 @@ begin adc_tr_data_p <= (others => '0'); adc_tr_data_c <= (others => '0'); adc_tr_data_clk <= '0'; + nx_token_return_pipe <= (others => '0'); adc_data_last <= (others => '0'); + adc_tr_value_tmp <= (others => '0'); + adc_tr_value_update <= '0'; + TR_STATE <= S_IDLE; + state_debug <= "00"; else timestamp_o <= (others => '0'); channel_o <= (others => '0'); @@ -277,10 +292,12 @@ begin overflow_rate_inc <= '0'; invalid_adc <= '0'; adc_tr_data_clk <= '0'; - + adc_tr_value_update <= '0'; + if (new_timestamp = '1') then adc_data_last <= adc_data; + if (parity_error = '1') then parity_error_ctr <= parity_error_ctr + 1; end if; @@ -321,8 +338,9 @@ begin nx_nomore_data_o <= '0'; trigger_rate_inc <= '1'; - if (nx_token_return_o = '1') then - -- First Data Word after empty Frame + if (nx_token_return_o = '1' and + nx_token_return_pipe(4 downto 0) = "11111") then + -- First Data Word after 5 empty Frames adc_tr_data_p <= unsigned(adc_data_last); adc_tr_data_c <= unsigned(adc_data); adc_tr_data_clk <= '1'; @@ -345,21 +363,48 @@ begin frame_rate_inc <= '1'; + -- Token Return Check Handler + case TR_STATE is + when S_IDLE => + if (nx_token_return_pipe(4 downto 0) = "11111") then + adc_tr_value_tmp <= adc_data_last; + TR_STATE <= S_START; + else + TR_STATE <= S_IDLE; + end if; + state_debug <= "01"; + + when S_START => + if (nx_token_return_pipe = "111111111") then + TR_STATE <= S_END; + elsif (nx_token_return_pipe(5 downto 0) = "111111" or + nx_token_return_pipe(6 downto 0) = "1111111" or + nx_token_return_pipe(7 downto 0) = "11111111") then + TR_STATE <= S_START; + else + TR_STATE <= S_IDLE; + end if; + state_debug <= "10"; + + when S_END => + adc_tr_value <= adc_tr_value_tmp; + adc_tr_value_update <= '1'; + TR_STATE <= S_IDLE; + state_debug <= "11"; + + end case; + -- Token Return Pipeline - nx_token_return_pipe(0) <= nx_token_return_o; - for I in 1 to 4 loop - nx_token_return_pipe(I) <= nx_token_return_pipe(I - 1); - end loop; - - -- Store ADC Value after 5 consecutive empty Frames - if (nx_token_return_pipe = "11111") then - adc_tr_value <= adc_data_last; + if (TR_STATE /= S_END) then + nx_token_return_pipe(0) <= nx_token_return_o; + for I in 1 to 8 loop + nx_token_return_pipe(I) <= nx_token_return_pipe(I - 1); + end loop; + else + nx_token_return_pipe <= (others => '0'); end if; - - else - nx_token_return_o <= nx_token_return_o; - nx_nomore_data_o <= nx_nomore_data_o; - end if; + + end if; -- Reset Counters if (clear_counters = '1') then @@ -381,6 +426,8 @@ begin nx_rate_timer <= (others => '0'); nx_hit_rate <= (others => '0'); nx_frame_rate <= (others => '0'); + adc_tr_error_ctr_t <= (others => '0'); + adc_tr_error_ctr <= (others => '0'); adc_tr_error_rate <= (others => '0'); else if (nx_rate_timer < x"5f5e100") then @@ -399,6 +446,7 @@ begin end if; if (adc_tr_error = '1') then adc_tr_error_ctr_t <= adc_tr_error_ctr_t + 1; + adc_tr_error_ctr <= adc_tr_error_ctr + 1; end if; nx_rate_timer <= nx_rate_timer + 1; else @@ -462,7 +510,6 @@ begin begin if (rising_edge(CLK_IN) ) then if (RESET_IN = '1') then - adc_tr_error_ctr <= (others => '0'); adc_tr_error <= '0'; adc_tr_debug_p <= '0'; adc_tr_debug_c <= '0'; @@ -471,17 +518,15 @@ begin lower_limit := unsigned(adc_tr_value) - adc_tr_limit; adc_tr_error <= '0'; - lower_limit_r <= lower_limit; - if (adc_tr_data_clk = '1') then - if (adc_tr_data_p < x"92e") then -- 2350 + if (adc_tr_data_p > lower_limit) then adc_tr_debug_p <= '1'; else adc_tr_debug_p <= '0'; end if; - if (adc_tr_data_c < x"92e") then + if (adc_tr_data_c > lower_limit) then adc_tr_debug_c <= '1'; else adc_tr_debug_c <= '0'; @@ -496,23 +541,16 @@ begin adc_tr_data_c > lower_limit) then adc_tr_error_status <= "01"; adc_tr_error <= '1'; - - elsif (adc_tr_data_p < lower_limit and - adc_tr_data_c < lower_limit) then + else adc_tr_error_status <= "10"; adc_tr_error <= '1'; - - elsif (adc_tr_data_p < lower_limit and - adc_tr_data_c > lower_limit) then - adc_tr_error_status <= "11"; - adc_tr_error <= '1'; end if; end if; end if; end if; end process PROC_ADC_TOKEN_RETURN; - + PROC_ADC_TOKEN_RETURN_ERROR: process(CLK_IN) begin if (rising_edge(CLK_IN) ) then @@ -545,7 +583,7 @@ begin clear_counters <= '0'; adc_average_divisor <= x"3"; - adc_tr_limit <= x"014"; -- 20 + adc_tr_limit <= x"064"; -- 100 adc_tr_debug_mode <= '0'; else slv_data_out_o <= (others => '0'); @@ -691,20 +729,23 @@ begin -- Output Signals ----------------------------------------------------------------------------- - TIMESTAMP_OUT <= timestamp_o; - CHANNEL_OUT <= channel_o; - TIMESTAMP_STATUS_OUT <= timestamp_status_o; - ADC_DATA_OUT <= adc_data_o; - DATA_CLK_OUT <= data_clk_o; - NX_TOKEN_RETURN_OUT <= nx_token_return_o; - NX_NOMORE_DATA_OUT <= nx_nomore_data_o; + adc_tr_error_o <= adc_tr_error; + + TIMESTAMP_OUT <= timestamp_o; + CHANNEL_OUT <= channel_o; + TIMESTAMP_STATUS_OUT <= timestamp_status_o; + ADC_DATA_OUT <= adc_data_o; + DATA_CLK_OUT <= data_clk_o; + NX_TOKEN_RETURN_OUT <= nx_token_return_o; + NX_NOMORE_DATA_OUT <= nx_nomore_data_o; - ERROR_OUT <= error_o; + ADC_TR_ERROR_OUT <= adc_tr_error_o; + ERROR_OUT <= error_o; -- Slave - SLV_DATA_OUT <= slv_data_out_o; - SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; - SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o; - SLV_ACK_OUT <= slv_ack_o; + SLV_DATA_OUT <= slv_data_out_o; + SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; + SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o; + SLV_ACK_OUT <= slv_ack_o; end Behavioral; diff --git a/nxyter/source/nx_status_event.vhd b/nxyter/source/nx_status_event.vhd index ba3d6ba..5eb13be 100644 --- a/nxyter/source/nx_status_event.vhd +++ b/nxyter/source/nx_status_event.vhd @@ -61,17 +61,27 @@ architecture Behavioral of nx_status_event is signal E_STATE : E_STATES; - constant NUM_REGS : integer := 3; + -- constant NUM_REGS : integer := 3; + -- type reg_addr_t is array(0 to NUM_REGS - 1) of std_logic_vector(15 downto 0); + -- constant reg_addr_start : reg_addr_t := + -- (x"0000", + -- x"0100", + -- x"0080" + -- ); + -- constant reg_addr_end : reg_addr_t := + -- (x"002d", + -- x"0180", + -- x"0083" + -- ); + + -- For the moment just the 4 I2C ADC Values, event must be small + constant NUM_REGS : integer := 1; type reg_addr_t is array(0 to NUM_REGS - 1) of std_logic_vector(15 downto 0); constant reg_addr_start : reg_addr_t := - (x"0000", - x"0100", - x"0080" + (x"0080" ); constant reg_addr_end : reg_addr_t := - (x"002d", - x"0180", - x"0083" + (x"0083" ); signal index_ctr : unsigned(3 downto 0); diff --git a/nxyter/source/nx_trigger_handler.vhd b/nxyter/source/nx_trigger_handler.vhd index 3985db8..aef7d0a 100644 --- a/nxyter/source/nx_trigger_handler.vhd +++ b/nxyter/source/nx_trigger_handler.vhd @@ -50,6 +50,7 @@ entity nx_trigger_handler is TIMESTAMP_TRIGGER_OUT : out std_logic; TRIGGER_TIMING_OUT : out std_logic; TRIGGER_STATUS_OUT : out std_logic; + TRIGGER_CALIBRATION_OUT : out std_logic; FAST_CLEAR_OUT : out std_logic; TRIGGER_BUSY_OUT : out std_logic; @@ -112,6 +113,8 @@ architecture Behavioral of nx_trigger_handler is signal valid_trigger_o : std_logic; signal timing_trigger_o : std_logic; signal status_trigger_o : std_logic; + signal calibration_trigger_o : std_logic; + signal calib_downscale_ctr : unsigned(15 downto 0); signal fast_clear_o : std_logic; signal trigger_busy_o : std_logic; signal fee_data_o : std_logic_vector(31 downto 0); @@ -122,9 +125,16 @@ architecture Behavioral of nx_trigger_handler is signal testpulse_trigger : std_logic; signal testpulse_enable : std_logic; + + signal timestamp_calib_trigger_c100 : std_logic; + signal timestamp_calib_trigger_f : std_logic; + signal timestamp_calib_trigger_o : std_logic; type STATES is (S_IDLE, - S_CTS_TRIGGER, + S_IGNORE_TRIGGER, + S_STATUS_TRIGGER, + S_TIMING_TRIGGER, + S_CALIBRATION_TRIGGER, S_WAIT_TRG_DATA_VALID, S_WAIT_TIMING_TRIGGER_DONE, S_FEE_TRIGGER_RELEASE, @@ -137,9 +147,9 @@ architecture Behavioral of nx_trigger_handler is type TRIGGER_TYPES is (T_UNDEF, T_IGNORE, - T_INTERNAL, T_TIMING, - T_SETUP + T_STATUS, + T_CALIBRATION ); signal TRIGGER_TYPE : TRIGGER_TYPES; @@ -163,7 +173,7 @@ architecture Behavioral of nx_trigger_handler is signal wait_timer_end : unsigned(11 downto 0); signal internal_trigger_f : std_logic; signal internal_trigger : std_logic; - + -- Rate Calculation signal start_testpulse_ff : std_logic; signal start_testpulse_f : std_logic; @@ -185,9 +195,15 @@ architecture Behavioral of nx_trigger_handler is signal accepted_trigger_rate : unsigned(27 downto 0); signal testpulse_rate : unsigned(27 downto 0); signal invalid_t_trigger_ctr_clear : std_logic; - signal bypass_ctr_trigger : std_logic; + signal bypass_all_trigger : std_logic; + signal bypass_physics_trigger : std_logic; signal bypass_status_trigger : std_logic; - + signal bypass_calibration_trigger : std_logic; + signal calibration_downscale : unsigned(15 downto 0); + signal physics_trigger_type : std_logic_vector(3 downto 0); + signal status_trigger_type : std_logic_vector(3 downto 0); + signal calibration_trigger_type : std_logic_vector(3 downto 0); + -- Reset signal reset_nx_main_clk_in_ff : std_logic; signal reset_nx_main_clk_in_f : std_logic; @@ -208,6 +224,9 @@ architecture Behavioral of nx_trigger_handler is attribute syn_keep of start_testpulse_ff : signal is true; attribute syn_keep of start_testpulse_f : signal is true; + + attribute syn_keep of timestamp_calib_trigger_f : signal is true; + attribute syn_keep of timestamp_calib_trigger_o : signal is true; attribute syn_preserve : boolean; attribute syn_preserve of reset_nx_main_clk_in_ff : signal is true; @@ -224,6 +243,9 @@ architecture Behavioral of nx_trigger_handler is attribute syn_preserve of start_testpulse_ff : signal is true; attribute syn_preserve of start_testpulse_f : signal is true; + + attribute syn_preserve of timestamp_calib_trigger_f : signal is true; + attribute syn_preserve of timestamp_calib_trigger_o : signal is true; begin @@ -293,7 +315,7 @@ begin LEVEL_IN => timing_trigger_l, PULSE_OUT => timing_trigger ); - + -- Timer timer_static_2: timer_static generic map ( @@ -437,25 +459,30 @@ begin begin if( rising_edge(CLK_IN) ) then if (RESET_IN = '1') then - valid_trigger_o <= '0'; - timing_trigger_o <= '0'; - status_trigger_o <= '0'; - fee_data_finished_o <= '0'; - fee_trg_release_o <= '0'; - fee_trg_statusbits_o <= (others => '0'); - fast_clear_o <= '0'; - trigger_busy_o <= '0'; - TRIGGER_TYPE <= T_UNDEF; - STATE <= S_IDLE; - else - valid_trigger_o <= '0'; - timing_trigger_o <= '0'; - status_trigger_o <= '0'; - fee_data_finished_o <= '0'; - fee_trg_release_o <= '0'; - fee_trg_statusbits_o <= (others => '0'); - fast_clear_o <= '0'; - trigger_busy_o <= '1'; + valid_trigger_o <= '0'; + timing_trigger_o <= '0'; + status_trigger_o <= '0'; + calibration_trigger_o <= '0'; + fee_data_finished_o <= '0'; + fee_trg_release_o <= '0'; + fee_trg_statusbits_o <= (others => '0'); + fast_clear_o <= '0'; + trigger_busy_o <= '0'; + timestamp_calib_trigger_c100 <= '0'; + calib_downscale_ctr <= (others => '0'); + TRIGGER_TYPE <= T_UNDEF; + STATE <= S_IDLE; + else + valid_trigger_o <= '0'; + timing_trigger_o <= '0'; + status_trigger_o <= '0'; + calibration_trigger_o <= '0'; + fee_data_finished_o <= '0'; + fee_trg_release_o <= '0'; + fee_trg_statusbits_o <= (others => '0'); + fast_clear_o <= '0'; + trigger_busy_o <= '1'; + timestamp_calib_trigger_c100 <= '0'; if (LVL1_INVALID_TRG_IN = '1') then -- There was no valid Timing Trigger at CTS, do a fast clear @@ -463,88 +490,152 @@ begin fee_trg_release_o <= '1'; STATE <= S_IDLE; else + case STATE is + when S_IDLE => - if (LVL1_VALID_NOTIMING_TRG_IN = '1') then - -- Calibration Trigger - if (LVL1_TRG_TYPE_IN = x"e" and - bypass_status_trigger = '0') then - -- Status Trigger - TRIGGER_TYPE <= T_SETUP; - status_trigger_o <= '1'; + + if (LVL1_VALID_TIMING_TRG_IN = '1') then + -- Timing Trigger IN + if (NXYTER_OFFLINE_IN = '1' or + bypass_all_trigger = '1') then + + -- Ignore Trigger for nxyter is or pretends to be offline + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; else - -- Something else, Ignore - TRIGGER_TYPE <= T_IGNORE; + -- Check Trigger Type + if (LVL1_TRG_TYPE_IN = physics_trigger_type) then + -- Physiks Trigger + if (bypass_physics_trigger = '1') then + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + TRIGGER_TYPE <= T_TIMING; + STATE <= S_TIMING_TRIGGER; + end if; + else + -- Unknown Timing Trigger, ignore + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + end if; end if; - STATE <= S_WAIT_TRG_DATA_VALID; - - elsif (LVL1_VALID_TIMING_TRG_IN = '1') then - if (NXYTER_OFFLINE_IN = '0' and - bypass_ctr_trigger = '0') then - -- Normal Trigger - TRIGGER_TYPE <= T_TIMING; - STATE <= S_CTS_TRIGGER; - else + + elsif (LVL1_VALID_NOTIMING_TRG_IN = '1') then + -- No Timing Trigger IN + if (NXYTER_OFFLINE_IN = '1' or + bypass_all_trigger = '1') then + -- Ignore Trigger for nxyter is or pretends to be offline - TRIGGER_TYPE <= T_IGNORE; - STATE <= S_WAIT_TRG_DATA_VALID; + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + -- Check Trigger Type + if (LVL1_TRG_TYPE_IN = calibration_trigger_type) then + -- Calibration Trigger + if (bypass_calibration_trigger = '1') then + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + if (calib_downscale_ctr >= calibration_downscale) then + timestamp_calib_trigger_c100 <= '1'; + calib_downscale_ctr <= x"0001"; + TRIGGER_TYPE <= T_CALIBRATION; + STATE <= S_CALIBRATION_TRIGGER; + else + calib_downscale_ctr <= calib_downscale_ctr + 1; + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + end if; + end if; + + elsif (LVL1_TRG_TYPE_IN = status_trigger_type) then + -- Status Trigger + if (bypass_status_trigger = '1') then + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + else + -- Status Trigger + status_trigger_o <= '1'; + TRIGGER_TYPE <= T_STATUS; + STATE <= S_STATUS_TRIGGER; + end if; + + else + -- Some other Trigger, ignore it + TRIGGER_TYPE <= T_IGNORE; + STATE <= S_IGNORE_TRIGGER; + end if; + end if; + else - trigger_busy_o <= '0'; - TRIGGER_TYPE <= T_UNDEF; - STATE <= S_IDLE; - end if; - - when S_CTS_TRIGGER => - valid_trigger_o <= '1'; - timing_trigger_o <= '1'; - STATE <= S_WAIT_TRG_DATA_VALID; + -- No Trigger IN, Nothing to do, Sleep Well + trigger_busy_o <= '0'; + TRIGGER_TYPE <= T_UNDEF; + STATE <= S_IDLE; + end if; + + when S_TIMING_TRIGGER => + valid_trigger_o <= '1'; + timing_trigger_o <= '1'; + STATE <= S_WAIT_TRG_DATA_VALID; + + when S_CALIBRATION_TRIGGER => + calibration_trigger_o <= '1'; + valid_trigger_o <= '1'; + timing_trigger_o <= '1'; + STATE <= S_WAIT_TRG_DATA_VALID; - when S_WAIT_TRG_DATA_VALID => + when S_WAIT_TRG_DATA_VALID | S_STATUS_TRIGGER | S_IGNORE_TRIGGER => if (LVL1_TRG_DATA_VALID_IN = '0') then - STATE <= S_WAIT_TRG_DATA_VALID; + STATE <= S_WAIT_TRG_DATA_VALID; else - STATE <= S_WAIT_TIMING_TRIGGER_DONE; + STATE <= S_WAIT_TIMING_TRIGGER_DONE; end if; when S_WAIT_TIMING_TRIGGER_DONE => - if ((TRIGGER_TYPE = T_TIMING and TRIGGER_BUSY_0_IN = '1') or - (TRIGGER_TYPE = T_SETUP and TRIGGER_BUSY_1_IN = '1') + if (((TRIGGER_TYPE = T_TIMING or + TRIGGER_TYPE = T_CALIBRATION) + and TRIGGER_BUSY_0_IN = '1') + or + (TRIGGER_TYPE = T_STATUS and + TRIGGER_BUSY_1_IN = '1') ) then - STATE <= S_WAIT_TIMING_TRIGGER_DONE; + STATE <= S_WAIT_TIMING_TRIGGER_DONE; else - fee_data_finished_o <= '1'; - STATE <= S_FEE_TRIGGER_RELEASE; + fee_data_finished_o <= '1'; + STATE <= S_FEE_TRIGGER_RELEASE; end if; when S_FEE_TRIGGER_RELEASE => - fee_trg_release_o <= '1'; - STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; + fee_trg_release_o <= '1'; + STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; when S_WAIT_FEE_TRIGGER_RELEASE_ACK => if (LVL1_TRG_DATA_VALID_IN = '1') then - STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; + STATE <= S_WAIT_FEE_TRIGGER_RELEASE_ACK; else - STATE <= S_IDLE; + STATE <= S_IDLE; end if; -- Internal Trigger Handler when S_INTERNAL_TRIGGER => - valid_trigger_o <= '1'; - STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; + valid_trigger_o <= '1'; + STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; when S_WAIT_TRIGGER_VALIDATE_ACK => if (TRIGGER_VALIDATE_BUSY_IN = '0') then - STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; + STATE <= S_WAIT_TRIGGER_VALIDATE_ACK; else - STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; + STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; end if; when S_WAIT_TRIGGER_VALIDATE_DONE => if (TRIGGER_VALIDATE_BUSY_IN = '1') then - STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; + STATE <= S_WAIT_TRIGGER_VALIDATE_DONE; else - STATE <= S_IDLE; + STATE <= S_IDLE; end if; end case; @@ -556,15 +647,15 @@ begin PROC_EVENT_DATA_MULTIPLEXER: process(TRIGGER_TYPE) begin case TRIGGER_TYPE is - when T_UNDEF | T_IGNORE | T_INTERNAL => + when T_UNDEF | T_IGNORE => fee_data_o <= (others => '0'); fee_data_write_o <= '0'; - when T_TIMING => + when T_TIMING | T_CALIBRATION => fee_data_o <= FEE_DATA_0_IN; fee_data_write_o <= FEE_DATA_WRITE_0_IN; - when T_SETUP => + when T_STATUS => fee_data_o <= FEE_DATA_1_IN; fee_data_write_o <= FEE_DATA_WRITE_1_IN; @@ -586,11 +677,13 @@ begin testpulse_delay <= reg_testpulse_delay when rising_edge(NX_MAIN_CLK_IN); testpulse_length <= reg_testpulse_length when rising_edge(NX_MAIN_CLK_IN); - internal_trigger_f <= INTERNAL_TRIGGER_IN when rising_edge(NX_MAIN_CLK_IN); + internal_trigger_f <= INTERNAL_TRIGGER_IN or + calibration_trigger_o when rising_edge(NX_MAIN_CLK_IN); internal_trigger <= internal_trigger_f when rising_edge(NX_MAIN_CLK_IN); - start_testpulse <= testpulse_trigger or internal_trigger; - + start_testpulse <= testpulse_trigger or + internal_trigger; + PROC_TESTPULSE_HANDLER: process (NX_MAIN_CLK_IN) begin if( rising_edge(NX_MAIN_CLK_IN) ) then @@ -650,7 +743,7 @@ begin end if; end process PROC_TESTPULSE_HANDLER; - -- Relax Timing +-- Relax Timing start_testpulse_ff <= start_testpulse when rising_edge(NX_MAIN_CLK_IN); start_testpulse_f <= start_testpulse_ff when rising_edge(NX_MAIN_CLK_IN); @@ -666,7 +759,7 @@ begin RESET_B_IN => RESET_IN, PULSE_B_OUT => start_testpulse_clk100 ); - + PROC_CAL_RATES: process (CLK_IN) begin if( rising_edge(CLK_IN) ) then @@ -697,11 +790,11 @@ begin end if; end if; end process PROC_CAL_RATES; - - ----------------------------------------------------------------------------- - -- TRBNet Slave Bus - ----------------------------------------------------------------------------- - + +----------------------------------------------------------------------------- +-- TRBNet Slave Bus +----------------------------------------------------------------------------- + PROC_SLAVE_BUS: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then @@ -714,8 +807,14 @@ begin reg_testpulse_length <= x"064"; reg_testpulse_enable <= '0'; invalid_t_trigger_ctr_clear <= '1'; - bypass_ctr_trigger <= '0'; - bypass_status_trigger <= '0'; + bypass_all_trigger <= '0'; + bypass_physics_trigger <= '0'; + bypass_status_trigger <= '1'; + bypass_calibration_trigger <= '1'; + calibration_downscale <= x"0001"; + physics_trigger_type <= x"1"; + calibration_trigger_type <= x"9"; + status_trigger_type <= x"e"; else slv_unknown_addr_o <= '0'; slv_no_more_data_o <= '0'; @@ -744,9 +843,30 @@ begin slv_ack_o <= '1'; when x"0006" => - bypass_ctr_trigger <= SLV_DATA_IN(0); + bypass_physics_trigger <= SLV_DATA_IN(0); bypass_status_trigger <= SLV_DATA_IN(1); + bypass_calibration_trigger <= SLV_DATA_IN(2); + bypass_all_trigger <= SLV_DATA_IN(3); slv_ack_o <= '1'; + + when x"0007" => + if (unsigned(SLV_DATA_IN(15 downto 0)) > x"0000") then + calibration_downscale <= + unsigned(SLV_DATA_IN(15 downto 0)); + end if; + slv_ack_o <= '1'; + + when x"0008" => + physics_trigger_type <= SLV_DATA_IN(3 downto 0); + slv_ack_o <= '1'; + + when x"0009" => + status_trigger_type <= SLV_DATA_IN(3 downto 0); + slv_ack_o <= '1'; + + when x"000a" => + status_trigger_type <= SLV_DATA_IN(3 downto 0); + slv_ack_o <= '1'; when others => slv_unknown_addr_o <= '1'; @@ -772,7 +892,7 @@ begin std_logic_vector(reg_testpulse_length); slv_data_out_o(31 downto 12) <= (others => '0'); slv_ack_o <= '1'; - + when x"0003" => slv_data_out_o(15 downto 0) <= std_logic_vector(invalid_timing_trigger_ctr); @@ -792,10 +912,32 @@ begin slv_ack_o <= '1'; when x"0006" => - slv_data_out_o(0) <= bypass_ctr_trigger; + slv_data_out_o(0) <= bypass_physics_trigger; slv_data_out_o(1) <= bypass_status_trigger; - slv_data_out_o(31 downto 2) <= (others => '0'); + slv_data_out_o(2) <= bypass_calibration_trigger; + slv_data_out_o(3) <= bypass_all_trigger; + slv_data_out_o(31 downto 4) <= (others => '0'); slv_ack_o <= '1'; + + when x"0007" => + slv_data_out_o(15 downto 0) <= calibration_downscale; + slv_data_out_o(31 downto 16) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0008" => + slv_data_out_o(3 downto 0) <= physics_trigger_type; + slv_data_out_o(31 downto 4) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0009" => + slv_data_out_o(3 downto 0) <= status_trigger_type; + slv_data_out_o(31 downto 4) <= (others => '0'); + slv_ack_o <= '1'; + + when x"000a" => + slv_data_out_o(3 downto 0) <= calibration_trigger_type; + slv_data_out_o(31 downto 4) <= (others => '0'); + slv_ack_o <= '1'; when others => slv_unknown_addr_o <= '1'; @@ -806,16 +948,23 @@ begin end if; end if; end process PROC_SLAVE_BUS; - - ----------------------------------------------------------------------------- - -- Output Signals - ----------------------------------------------------------------------------- - -- Trigger Output +----------------------------------------------------------------------------- +-- Output Signals +----------------------------------------------------------------------------- + + timestamp_calib_trigger_f <= timestamp_calib_trigger_c100 + when rising_edge(NX_MAIN_CLK_IN); + + timestamp_calib_trigger_o <= timestamp_calib_trigger_f + when rising_edge(NX_MAIN_CLK_IN); + +-- Trigger Output VALID_TRIGGER_OUT <= valid_trigger_o; - TIMESTAMP_TRIGGER_OUT <= timestamp_trigger_o; + TIMESTAMP_TRIGGER_OUT <= timestamp_trigger_o or timestamp_calib_trigger_o; TRIGGER_TIMING_OUT <= timing_trigger_o; TRIGGER_STATUS_OUT <= status_trigger_o; + TRIGGER_CALIBRATION_OUT <= calibration_trigger_o; FAST_CLEAR_OUT <= fast_clear_o; TRIGGER_BUSY_OUT <= trigger_busy_o; @@ -827,7 +976,7 @@ begin NX_TESTPULSE_OUT <= testpulse_o; - -- Slave Bus +-- Slave Bus SLV_DATA_OUT <= slv_data_out_o; SLV_NO_MORE_DATA_OUT <= slv_no_more_data_o; SLV_UNKNOWN_ADDR_OUT <= slv_unknown_addr_o; diff --git a/nxyter/source/nx_trigger_validate.vhd b/nxyter/source/nx_trigger_validate.vhd index fee9a75..b8d770c 100644 --- a/nxyter/source/nx_trigger_validate.vhd +++ b/nxyter/source/nx_trigger_validate.vhd @@ -24,6 +24,7 @@ entity nx_trigger_validate is NX_NOMORE_DATA_IN : in std_logic; TRIGGER_IN : in std_logic; + TRIGGER_CALIBRATION_IN : in std_logic; TRIGGER_BUSY_IN : in std_logic; FAST_CLEAR_IN : in std_logic; TRIGGER_BUSY_OUT : out std_logic; @@ -134,7 +135,8 @@ architecture Behavioral of nx_trigger_validate is signal wait_for_data_time_r : std_logic_vector(19 downto 0); signal min_validation_time_r : std_logic_vector(19 downto 0); signal skip_wait_for_data : std_logic; - + signal trigger_calibration : std_logic; + type STATES is (S_TEST_SELF_TRIGGER, S_IDLE, S_TRIGGER, @@ -210,7 +212,7 @@ architecture Behavioral of nx_trigger_validate is signal readout_time_max : unsigned(11 downto 0); signal fpga_timestamp_offset : unsigned(11 downto 0); - signal state_d : std_logic_vector(1 downto 0); + signal state_d : std_logic_vector(1 downto 0); attribute syn_keep : boolean; attribute syn_keep of timestamp_fpga_ff : signal is true; @@ -273,6 +275,7 @@ begin ----------------------------------------------------------------------------- PROC_FILTER_TIMESTAMPS: process (CLK_IN) + variable cts_trigger_delay_tmp : unsigned(11 downto 0); variable ts_window_offset_unsigned : unsigned(11 downto 0); variable window_lower_thr : unsigned(11 downto 0); variable window_upper_thr : unsigned(11 downto 0); @@ -318,17 +321,23 @@ begin ----------------------------------------------------------------------- -- Calculate Thresholds and values for FIFO Delay ----------------------------------------------------------------------- + + if (trigger_calibration = '0') then + cts_trigger_delay_tmp := cts_trigger_delay; + else + cts_trigger_delay_tmp := (others => '0'); + end if; if (ts_window_offset(11) = '1') then -- Offset is negative ts_window_offset_unsigned := (unsigned(ts_window_offset) xor x"fff") + 1; window_lower_thr := - cts_trigger_delay + ts_window_offset_unsigned; + cts_trigger_delay_tmp + ts_window_offset_unsigned; else -- Offset is positive window_lower_thr := - cts_trigger_delay - unsigned(ts_window_offset); + cts_trigger_delay_tmp - unsigned(ts_window_offset); end if; -- Calculate FIFO Delay @@ -628,6 +637,7 @@ begin evt_buffer_clear_o <= '0'; wait_for_data_time_r <= (others => '0'); min_validation_time_r <= (others => '0'); + trigger_calibration <= '0'; STATE <= S_TEST_SELF_TRIGGER; else store_to_fifo <= '0'; @@ -697,8 +707,10 @@ begin if (TRIGGER_IN = '1') then busy_time_ctr <= (others => '0'); + trigger_calibration <= TRIGGER_CALIBRATION_IN; STATE <= S_TRIGGER; else + trigger_calibration <= '0'; trigger_busy_o <= '0'; min_val_time_expired <= '0'; if (self_trigger_mode = '1') then diff --git a/nxyter/source/nxyter_components.vhd b/nxyter/source/nxyter_components.vhd index a16af71..8fc0ae8 100644 --- a/nxyter/source/nxyter_components.vhd +++ b/nxyter/source/nxyter_components.vhd @@ -476,6 +476,7 @@ component nx_data_receiver SLV_ACK_OUT : out std_logic; SLV_NO_MORE_DATA_OUT : out std_logic; SLV_UNKNOWN_ADDR_OUT : out std_logic; + ADC_TR_ERROR_IN : in std_logic; DISABLE_ADC_OUT : out std_logic; ERROR_OUT : out std_logic; DEBUG_OUT : out std_logic_vector(15 downto 0) @@ -505,36 +506,36 @@ end component; component nx_data_validate port ( - CLK_IN : in std_logic; - RESET_IN : in std_logic; - DATA_IN : in std_logic_vector(43 downto 0); - DATA_CLK_IN : in std_logic; - TIMESTAMP_OUT : out std_logic_vector(13 downto 0); - CHANNEL_OUT : out std_logic_vector(6 downto 0); - TIMESTAMP_STATUS_OUT : out std_logic_vector(2 downto 0); - ADC_DATA_OUT : out std_logic_vector(11 downto 0); - DATA_CLK_OUT : out std_logic; - NX_TOKEN_RETURN_OUT : out std_logic; - NX_NOMORE_DATA_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); - SLV_DATA_IN : in std_logic_vector(31 downto 0); - SLV_ADDR_IN : in std_logic_vector(15 downto 0); - SLV_ACK_OUT : out std_logic; - SLV_NO_MORE_DATA_OUT : out std_logic; - SLV_UNKNOWN_ADDR_OUT : out std_logic; - DISABLE_ADC_IN : in std_logic; - ERROR_OUT : out std_logic; - DEBUG_OUT : out std_logic_vector(15 downto 0) + CLK_IN : in std_logic; + RESET_IN : in std_logic; + DATA_IN : in std_logic_vector(43 downto 0); + DATA_CLK_IN : in std_logic; + TIMESTAMP_OUT : out std_logic_vector(13 downto 0); + CHANNEL_OUT : out std_logic_vector(6 downto 0); + TIMESTAMP_STATUS_OUT : out std_logic_vector(2 downto 0); + ADC_DATA_OUT : out std_logic_vector(11 downto 0); + DATA_CLK_OUT : out std_logic; + NX_TOKEN_RETURN_OUT : out std_logic; + NX_NOMORE_DATA_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); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_ADDR_IN : in std_logic_vector(15 downto 0); + SLV_ACK_OUT : out std_logic; + SLV_NO_MORE_DATA_OUT : out std_logic; + SLV_UNKNOWN_ADDR_OUT : out std_logic; + ADC_TR_ERROR_OUT : out std_logic; + DISABLE_ADC_IN : in std_logic; + ERROR_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(15 downto 0) ); end component; component nx_trigger_validate generic ( - BOARD_ID : std_logic_vector(1 downto 0); - VERSION_NUMBER : std_logic_vector(3 downto 0) := x"1" - ); + BOARD_ID : std_logic_vector(1 downto 0); + VERSION_NUMBER : std_logic_vector(3 downto 0)); port ( CLK_IN : in std_logic; RESET_IN : in std_logic; @@ -546,6 +547,7 @@ component nx_trigger_validate NX_TOKEN_RETURN_IN : in std_logic; NX_NOMORE_DATA_IN : in std_logic; TRIGGER_IN : in std_logic; + TRIGGER_CALIBRATION_IN : in std_logic; TRIGGER_BUSY_IN : in std_logic; FAST_CLEAR_IN : in std_logic; TRIGGER_BUSY_OUT : out std_logic; @@ -937,6 +939,7 @@ component nx_trigger_handler TIMESTAMP_TRIGGER_OUT : out std_logic; TRIGGER_TIMING_OUT : out std_logic; TRIGGER_STATUS_OUT : out std_logic; + TRIGGER_CALIBRATION_OUT : out std_logic; FAST_CLEAR_OUT : out std_logic; TRIGGER_BUSY_OUT : out std_logic; NX_TESTPULSE_OUT : out std_logic; diff --git a/nxyter/source/nxyter_fee_board.vhd b/nxyter/source/nxyter_fee_board.vhd index e71a09f..d34c90f 100644 --- a/nxyter/source/nxyter_fee_board.vhd +++ b/nxyter/source/nxyter_fee_board.vhd @@ -153,7 +153,7 @@ architecture Behavioral of nXyter_FEE_board is signal timestamp_status : std_logic_vector(2 downto 0); signal adc_data : std_logic_vector(11 downto 0); signal data_clk : std_logic; - + signal adc_tr_error : std_logic; signal nx_token_return : std_logic; signal nx_nomore_data : std_logic; @@ -199,6 +199,7 @@ architecture Behavioral of nXyter_FEE_board is signal timestamp_trigger : std_logic; signal trigger_timing : std_logic; signal trigger_status : std_logic; + signal trigger_calibration : std_logic; signal trigger_busy : std_logic; signal fast_clear : std_logic; signal fee_trg_release_o : std_logic; @@ -499,6 +500,7 @@ begin TIMESTAMP_TRIGGER_OUT => timestamp_trigger, TRIGGER_TIMING_OUT => trigger_timing, TRIGGER_STATUS_OUT => trigger_status, + TRIGGER_CALIBRATION_OUT => trigger_calibration, FAST_CLEAR_OUT => fast_clear, TRIGGER_BUSY_OUT => trigger_busy, @@ -555,7 +557,7 @@ begin port map ( CLK_IN => CLK_IN, RESET_IN => RESET_IN, - TRIGGER_IN => trigger_timing, + TRIGGER_IN => trigger_timing, -- for debugging only NX_ONLINE_IN => nxyter_online, NX_CLOCK_ON_IN => nxyter_clock_on, @@ -584,6 +586,8 @@ begin SLV_ACK_OUT => slv_ack(2), SLV_NO_MORE_DATA_OUT => slv_no_more_data(2), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(2), + + ADC_TR_ERROR_IN => adc_tr_error, DISABLE_ADC_OUT => disable_adc_receiver, ERROR_OUT => error_data_receiver, DEBUG_OUT => debug_line(7) @@ -623,33 +627,34 @@ begin nx_data_validate_1: nx_data_validate port map ( - CLK_IN => CLK_IN, - RESET_IN => RESET_IN, - - DATA_IN => data_delayed, - DATA_CLK_IN => data_clk_delayed, - - TIMESTAMP_OUT => timestamp, - CHANNEL_OUT => timestamp_channel_id, - TIMESTAMP_STATUS_OUT => timestamp_status, - ADC_DATA_OUT => adc_data, - DATA_CLK_OUT => data_clk, - - NX_TOKEN_RETURN_OUT => nx_token_return, - NX_NOMORE_DATA_OUT => nx_nomore_data, - - SLV_READ_IN => slv_read(6), - SLV_WRITE_IN => slv_write(6), - SLV_DATA_OUT => slv_data_rd(6*32+31 downto 6*32), - SLV_DATA_IN => slv_data_wr(6*32+31 downto 6*32), - SLV_ADDR_IN => slv_addr(6*16+15 downto 6*16), - SLV_ACK_OUT => slv_ack(6), - SLV_NO_MORE_DATA_OUT => slv_no_more_data(6), - SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(6), - - DISABLE_ADC_IN => disable_adc_receiver, - ERROR_OUT => error_data_validate, - DEBUG_OUT => debug_line(9) + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + + DATA_IN => data_delayed, + DATA_CLK_IN => data_clk_delayed, + + TIMESTAMP_OUT => timestamp, + CHANNEL_OUT => timestamp_channel_id, + TIMESTAMP_STATUS_OUT => timestamp_status, + ADC_DATA_OUT => adc_data, + DATA_CLK_OUT => data_clk, + + NX_TOKEN_RETURN_OUT => nx_token_return, + NX_NOMORE_DATA_OUT => nx_nomore_data, + + SLV_READ_IN => slv_read(6), + SLV_WRITE_IN => slv_write(6), + SLV_DATA_OUT => slv_data_rd(6*32+31 downto 6*32), + SLV_DATA_IN => slv_data_wr(6*32+31 downto 6*32), + SLV_ADDR_IN => slv_addr(6*16+15 downto 6*16), + SLV_ACK_OUT => slv_ack(6), + SLV_NO_MORE_DATA_OUT => slv_no_more_data(6), + SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(6), + + ADC_TR_ERROR_OUT => adc_tr_error, + DISABLE_ADC_IN => disable_adc_receiver, + ERROR_OUT => error_data_validate, + DEBUG_OUT => debug_line(9) ); ------------------------------------------------------------------------------- @@ -674,6 +679,7 @@ begin NX_NOMORE_DATA_IN => nx_nomore_data, TRIGGER_IN => trigger, + TRIGGER_CALIBRATION_IN => trigger_calibration, TRIGGER_BUSY_IN => trigger_busy, FAST_CLEAR_IN => fast_clear, TRIGGER_BUSY_OUT => trigger_validate_busy, diff --git a/nxyter/source/registers.txt b/nxyter/source/registers.txt index 2da5a0a..b9f8a81 100644 --- a/nxyter/source/registers.txt +++ b/nxyter/source/registers.txt @@ -52,8 +52,14 @@ w: Clear Counter 0x8164 : r/w Clear Countercceptred Trigger Rate (1/s) 0x8165 : r/w Testpulse Rate (1/s) -0x8166 : r/w Bit0: Bypass CTS Trigger +0x8166 : r/w Bit0: Bypass Timing Trigger Bit1: Bypass Status Trigger + Bit2: Bypass Calibration Trigger + Bit3: Bypass All Trigger +0x8167 : r/w Calibration Trigger Downscale (16 Bit) +0x8168 : r/w Timing Trigger Type (4 Bit) +0x8169 : r/w Status Trigger Type (4 Bit) +0x816a : r/w Calibration Trigger Type (4 Bit) -- NX Data Receiver 0x8500 : r current Timestamp FIFO value diff --git a/nxyter/trb3_periph_constraints.lpf b/nxyter/trb3_periph_constraints.lpf index ab89eb3..f01711f 100644 --- a/nxyter/trb3_periph_constraints.lpf +++ b/nxyter/trb3_periph_constraints.lpf @@ -74,6 +74,8 @@ MULTICYCLE to CELL "nXyter_FEE_board_*/nx_trigger_handler_*/fast_clear_ff*" MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_trigger_handler_*/reg_testpulse_delay*" 100 ns; MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_trigger_handler_*/reg_testpulse_length*" 100 ns; MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_trigger_handler_*/reg_testpulse_enable*" 100 ns; +MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_trigger_handler_*/calibration_trigger_o*" 50 ns; +MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_trigger_handler_*/timestamp_calib_trigger_c*" 20 ns; MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_trigger_generator_*/internal_trigger_o*" 100 ns; @@ -86,7 +88,7 @@ MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/merge_handler_reset_ MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_reset_handler_cnx_ff*" 30 ns; MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/reset_handler_start_r*" 100 ns; MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/johnson_counter_sync_r*" 100 ns; -MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/nx_timestamp_delay_r*" 100 ns; +MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/nx_timestamp_delay_s*" 100 ns; MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/nx_frame_word_delay_rr*" 100 ns; MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/fifo_full_r*" 100 ns; MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/fifo_empty_r*" 100 ns; diff --git a/nxyter/trb3_periph_multi.p2t b/nxyter/trb3_periph_multi.p2t index 6530322..b7195f8 100644 --- a/nxyter/trb3_periph_multi.p2t +++ b/nxyter/trb3_periph_multi.p2t @@ -1,7 +1,7 @@ -w -i 2 -l 5 --n 10 +-n 20 -t 30 -s 1 -c 1 diff --git a/nxyter/trb3_periph_nxyter.lpf b/nxyter/trb3_periph_nxyter.lpf index b3cf6d8..bab9324 100644 --- a/nxyter/trb3_periph_nxyter.lpf +++ b/nxyter/trb3_periph_nxyter.lpf @@ -125,27 +125,27 @@ LOCATE COMP "NX1_TIMESTAMP_IN_7" SITE "H1"; #DQUL3_4 #57 #DEFINE PORT GROUP "LVDS_group1" "NX1_TIMESTAMP*" ; -#IOBUF GROUP "LVDS_group1" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_TIMESTAMP_IN_0" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_TIMESTAMP_IN_1" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_TIMESTAMP_IN_2" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_TIMESTAMP_IN_3" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_TIMESTAMP_IN_4" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_TIMESTAMP_IN_5" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_TIMESTAMP_IN_6" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_TIMESTAMP_IN_7" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; +#IOBUF GROUP "LVDS_group1" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_TIMESTAMP_IN_0" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_TIMESTAMP_IN_1" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_TIMESTAMP_IN_2" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_TIMESTAMP_IN_3" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_TIMESTAMP_IN_4" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_TIMESTAMP_IN_5" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_TIMESTAMP_IN_6" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_TIMESTAMP_IN_7" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; #DEFINE PORT GROUP "LVDS_group2" "NX1_ADC*IN" ; -#IOBUF GROUP "LVDS_group2" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_ADC_D_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_ADC_A_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_ADC_DCLK_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_ADC_NX_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_ADC_B_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; -IOBUF PORT "NX1_ADC_FCLK_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; +#IOBUF GROUP "LVDS_group2" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_ADC_D_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_ADC_A_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_ADC_DCLK_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_ADC_NX_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_ADC_B_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; +IOBUF PORT "NX1_ADC_FCLK_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; IOBUF PORT "NX1_ADC_SAMPLE_CLK_OUT" IO_TYPE=LVDS25; -IOBUF PORT "NX1_DATA_CLK_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVT=off; +IOBUF PORT "NX1_DATA_CLK_IN" IO_TYPE=LVDS25 DIFFRESISTOR=100 TERMINATEVTT=off; IOBUF PORT "NX1_TESTPULSE_OUT" IO_TYPE=LVDS25; IOBUF PORT "NX1_MAIN_CLK_OUT" IO_TYPE=LVDS25; IOBUF PORT "NX1_RESET_OUT" IO_TYPE=LVDS25; -- 2.43.0