From f7a2e6d7ce0ae124650ede60926dfa32729c9d1a Mon Sep 17 00:00:00 2001 From: Ludwig Maier Date: Mon, 28 Apr 2014 09:22:41 +0200 Subject: [PATCH] nxyter update, timing corrections etc. --- nxyter/source/adc_ad9228.vhd | 15 +- nxyter/source/nx_data_receiver.vhd | 121 ++++---- nxyter/source/nx_trigger_generator.vhd | 384 ++++++++++++++++++------- nxyter/source/nx_trigger_handler.vhd | 21 +- nxyter/source/nx_trigger_validate.vhd | 39 ++- nxyter/source/nxyter_components.vhd | 4 +- nxyter/source/nxyter_fee_board.vhd | 16 +- nxyter/trb3_periph_constraints.lpf | 6 +- 8 files changed, 429 insertions(+), 177 deletions(-) diff --git a/nxyter/source/adc_ad9228.vhd b/nxyter/source/adc_ad9228.vhd index 2ca5424..4e9789d 100644 --- a/nxyter/source/adc_ad9228.vhd +++ b/nxyter/source/adc_ad9228.vhd @@ -55,7 +55,11 @@ architecture Behavioral of adc_ad9228 is -- DDR Generic Handler signal DDR_DATA_CLK : std_logic; + signal q_0_ff : std_logic_vector(19 downto 0); + signal q_0_f : std_logic_vector(19 downto 0); signal q_0 : std_logic_vector(19 downto 0); + signal q_1_ff : std_logic_vector(19 downto 0); + signal q_1_f : std_logic_vector(19 downto 0); signal q_1 : std_logic_vector(19 downto 0); -- NotLock Counters @@ -219,10 +223,17 @@ begin datain_1(3) => ADC1_DATA_D_IN, datain_1(4) => ADC1_FCLK_IN, - q_0 => q_0, - q_1 => q_1 + q_0 => q_0_ff, + q_1 => q_1_ff ); + -- Two Input FIFOs to relaxe timing + q_0_f <= q_0_ff when rising_edge(DDR_DATA_CLK); + q_0 <= q_0_f when rising_edge(DDR_DATA_CLK); + + q_1_f <= q_1_ff when rising_edge(DDR_DATA_CLK); + q_1 <= q_1_f when rising_edge(DDR_DATA_CLK); + ----------------------------------------------------------------------------- PROC_MERGE_DATA0: process(DDR_DATA_CLK) diff --git a/nxyter/source/nx_data_receiver.vhd b/nxyter/source/nx_data_receiver.vhd index 34d1c81..7561a81 100644 --- a/nxyter/source/nx_data_receiver.vhd +++ b/nxyter/source/nx_data_receiver.vhd @@ -236,6 +236,8 @@ architecture Behavioral of nx_data_receiver is signal new_adc_dt_error_ctr_r : unsigned(11 downto 0); signal new_timestamp_dt_error_ctr_r : unsigned(11 downto 0); signal adc_notlock_ctr_r : unsigned(7 downto 0); + signal merge_error_ctr_r : unsigned(11 downto 0); + signal nx_frame_synced_r : std_logic; ----------------------------------------------------------------------------- -- Reset Handler @@ -251,6 +253,8 @@ architecture Behavioral of nx_data_receiver is signal fifo_reset_handler : std_logic; type R_STATES is (R_IDLE, + R_RESET_TIMESTAMP, + R_WAIT_0, R_SET_ALL_RESETS, R_WAIT_1, R_WAIT_NX_FRAME_RATE_OK, @@ -280,7 +284,7 @@ architecture Behavioral of nx_data_receiver is signal parity_error_c100 : std_logic; signal parity_error_counter : unsigned(11 downto 0); - signal reg_nx_frame_synced : std_logic; + -- Reset Domain Transfers signal RESET_NX_TIMESTAMP_CLK_IN : std_logic; @@ -321,7 +325,7 @@ begin -- Reset Handler DEBUG_OUT(0) <= CLK_IN; DEBUG_OUT(1) <= nx_frame_clk; - DEBUG_OUT(2) <= adc_clk_skip; + DEBUG_OUT(2) <= adc_data_clk_c100; --clk_skip; DEBUG_OUT(3) <= adc_clk_ok; DEBUG_OUT(4) <= adc_reset_sync; DEBUG_OUT(5) <= adc_reset_handler; @@ -1074,14 +1078,6 @@ begin PULSE_B_OUT => resync_ctr_inc ); - -- nx_frame_synced --> CLK_IN Domain - signal_async_trans_1: signal_async_trans - port map ( - CLK_IN => CLK_IN, - SIGNAL_A_IN => nx_frame_synced, - SIGNAL_OUT => reg_nx_frame_synced - ); - -- Counters PROC_RESYNC_COUNTER: process(CLK_IN) begin @@ -1362,12 +1358,12 @@ begin if (reset_handler_start_r = '1') then -- Reset by register always wins, start it rs_timeout_timer_reset <= '1'; - R_STATE <= R_SET_ALL_RESETS; + R_STATE <= R_RESET_TIMESTAMP; elsif (rs_timeout_timer_done = '1') then -- Reset Timeout, retry RESET rs_timeout_timer_reset <= '1'; reset_timeout_flag <= '1'; - R_STATE <= R_SET_ALL_RESETS; + R_STATE <= R_RESET_TIMESTAMP; else case R_STATE is @@ -1377,93 +1373,115 @@ begin adc_reset_sync = '1' or startup_reset = '1' ) then - R_STATE <= R_SET_ALL_RESETS; + R_STATE <= R_RESET_TIMESTAMP; else reset_timeout_flag <= '0'; rs_timeout_timer_reset <= '1'; reset_handler_busy <= '0'; R_STATE <= R_IDLE; end if; - + + when R_RESET_TIMESTAMP => + -- must reset/resync Timestamp clock and data trnasmission clock + -- of nxyter first, afterwards wait a bit to let settle down + reset_handler_counter <= reset_handler_counter + 1; + nx_timestamp_reset_o <= '1'; + rs_wait_timer_start <= '1'; -- wait 1mue to settle + R_STATE <= R_WAIT_0; + debug_state <= x"1"; + + when R_WAIT_0 => + if (rs_wait_timer_done = '0') then + R_STATE <= R_WAIT_0; + else + R_STATE <= R_SET_ALL_RESETS; + end if; + debug_state <= x"2"; + when R_SET_ALL_RESETS => + -- timer reset should be finished, can we check status,To be done? + -- now set reset of all handlers frame_rates_reset <= '1'; - fifo_reset_handler <= '1'; sampling_clk_reset <= '1'; adc_reset_p <= '1'; adc_reset_handler <= '1'; output_handler_reset <= '1'; - - rs_wait_timer_start <= '1'; -- wait 1mue to settle + fifo_reset_handler <= '1'; + + -- give resets 1mue to take effect + rs_wait_timer_start <= '1'; R_STATE <= R_WAIT_1; - debug_state <= x"1"; - reset_handler_counter <= reset_handler_counter + 1; - + debug_state <= x"3"; + when R_WAIT_1 => + sampling_clk_reset <= '1'; + adc_reset_handler <= '1'; + output_handler_reset <= '1'; + fifo_reset_handler <= '1'; if (rs_wait_timer_done = '0') then - fifo_reset_handler <= '1'; - sampling_clk_reset <= '1'; - adc_reset_handler <= '1'; - output_handler_reset <= '1'; R_STATE <= R_WAIT_1; else - -- Release NX Fifo Reset + Start Timeout Handler - sampling_clk_reset <= '1'; - adc_reset_handler <= '1'; - output_handler_reset <= '1'; + -- now start timeout timer and begin to release resets + -- step by step rs_timeout_timer_start <= '1'; R_STATE <= R_WAIT_NX_FRAME_RATE_OK; end if; - debug_state <= x"2"; + debug_state <= x"4"; when R_WAIT_NX_FRAME_RATE_OK => if (nx_frame_rate_offline = '0' and nx_frame_rate_error = '0') then - -- Release PLL Reset + -- Next: Release PLL Reset, i.e. sampling_clk_reset adc_reset_handler <= '1'; output_handler_reset <= '1'; + fifo_reset_handler <= '1'; R_STATE <= R_PLL_WAIT_LOCK; else sampling_clk_reset <= '1'; adc_reset_handler <= '1'; output_handler_reset <= '1'; + fifo_reset_handler <= '1'; R_STATE <= R_WAIT_NX_FRAME_RATE_OK; end if; - debug_state <= x"3"; + debug_state <= x"5"; when R_PLL_WAIT_LOCK => - if (pll_adc_not_lock = '1') then - adc_reset_handler <= '1'; + if (pll_adc_not_lock = '0') then + -- Next: Release ADC Reset output_handler_reset <= '1'; - R_STATE <= R_PLL_WAIT_LOCK; + fifo_reset_handler <= '1'; + R_STATE <= R_WAIT_ADC_OK; else - -- Release ADC Reset + adc_reset_handler <= '1'; output_handler_reset <= '1'; - R_STATE <= R_WAIT_ADC_OK; + fifo_reset_handler <= '1'; + R_STATE <= R_PLL_WAIT_LOCK; end if; - debug_state <= x"4"; + debug_state <= x"6"; when R_WAIT_ADC_OK => if (error_adc0 = '0' and adc_frame_rate_error = '0') then - -- Release Output Handler Reset + -- Next: Release Output Handler and Clock Domain transfer Fifo + -- Resets R_STATE <= R_WAIT_DATA_HANDLER_OK; else output_handler_reset <= '1'; + fifo_reset_handler <= '1'; R_STATE <= R_WAIT_ADC_OK; end if; - debug_state <= x"5"; + debug_state <= x"7"; when R_WAIT_DATA_HANDLER_OK => if (frame_rate_error = '0') then startup_reset <= '0'; reset_timeout_flag <= '0'; rs_timeout_timer_reset <= '1'; - nx_timestamp_reset_o <= '1'; R_STATE <= R_IDLE; else R_STATE <= R_WAIT_DATA_HANDLER_OK; end if; - debug_state <= x"6"; + debug_state <= x"8"; end case; end if; end if; @@ -1485,7 +1503,7 @@ begin error_status_bits(2) <= nx_frame_rate_error; error_status_bits(3) <= adc_frame_rate_error; error_status_bits(4) <= parity_rate_error; - error_status_bits(5) <= not reg_nx_frame_synced; + error_status_bits(5) <= not nx_frame_synced_r; error_status_bits(6) <= error_adc0; error_status_bits(7) <= pll_adc_not_lock; error_status_bits(8) <= not adc_clk_ok_c100; @@ -1510,6 +1528,14 @@ begin PROC_SLAVE_BUS: process(CLK_IN) begin if (rising_edge(CLK_IN) ) then + fifo_full_r <= fifo_full; + fifo_empty_r <= fifo_empty; + new_adc_dt_error_ctr_r <= new_adc_dt_error_ctr; + new_timestamp_dt_error_ctr_r <= new_timestamp_dt_error_ctr; + adc_notlock_ctr_r <= adc_notlock_ctr; + merge_error_ctr_r <= merge_error_ctr; + nx_frame_synced_r <= nx_frame_synced; + if( RESET_IN = '1' ) then slv_data_out_o <= (others => '0'); slv_ack_o <= '0'; @@ -1528,8 +1554,6 @@ begin adc_debug_type <= (others => '0'); fifo_full_r <= '0'; fifo_empty_r <= '0'; - new_adc_dt_error_ctr_r <= (others => '0'); - new_timestamp_dt_error_ctr_r <= (others => '0'); else slv_data_out_o <= (others => '0'); slv_ack_o <= '0'; @@ -1539,11 +1563,6 @@ begin reset_parity_error_ctr <= '0'; pll_adc_not_lock_ctr_clear <= '0'; reset_handler_start_r <= '0'; - fifo_full_r <= fifo_full; - fifo_empty_r <= fifo_empty; - new_adc_dt_error_ctr_r <= new_adc_dt_error_ctr; - new_timestamp_dt_error_ctr_r <= new_timestamp_dt_error_ctr; - adc_notlock_ctr_r <= adc_notlock_ctr; if (SLV_READ_IN = '1') then case SLV_ADDR_IN is @@ -1595,7 +1614,7 @@ begin slv_ack_o <= '1'; when x"0009" => - slv_data_out_o(11 downto 0) <= merge_error_ctr; + slv_data_out_o(11 downto 0) <= merge_error_ctr_r; slv_data_out_o(31 downto 12) <= (others => '0'); slv_ack_o <= '1'; @@ -1651,7 +1670,7 @@ begin slv_data_out_o(5) <= '0'; slv_data_out_o(29 downto 6) <= (others => '0'); slv_data_out_o(30) <= '0'; - slv_data_out_o(31) <= reg_nx_frame_synced; + slv_data_out_o(31) <= nx_frame_synced_r; slv_ack_o <= '1'; when x"0012" => diff --git a/nxyter/source/nx_trigger_generator.vhd b/nxyter/source/nx_trigger_generator.vhd index a2547ea..2461a6e 100644 --- a/nxyter/source/nx_trigger_generator.vhd +++ b/nxyter/source/nx_trigger_generator.vhd @@ -7,70 +7,106 @@ use work.nxyter_components.all; entity nx_trigger_generator is port ( - CLK_IN : in std_logic; - RESET_IN : in std_logic; - NX_MAIN_CLK_IN : in std_logic; - - TRIGGER_BUSY_IN : in std_logic; - - TRIGGER_OUT : out std_logic; - - DATA_IN : in std_logic_vector(43 downto 0); - DATA_CLK_IN : in std_logic; - SELF_TRIGGER_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; + CLK_IN : in std_logic; + RESET_IN : in std_logic; + NX_MAIN_CLK_IN : in std_logic; + + TRIGGER_BUSY_IN : in std_logic; + EXTERNAL_TRIGGER_OUT : out std_logic; + INTERNAL_TRIGGER_OUT : out std_logic; + + DATA_IN : in std_logic_vector(43 downto 0); + DATA_CLK_IN : in 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; -- Debug Line - DEBUG_OUT : out std_logic_vector(15 downto 0) + DEBUG_OUT : out std_logic_vector(15 downto 0) ); end entity; architecture Behavioral of nx_trigger_generator is - -- Self Trigger + -- Internal Trigger Generator + signal pulser_trigger_on : std_logic; + signal pulser_trigger_period : unsigned(27 downto 0); + signal pulser_trigger : std_logic; + + -- Self Trigger Generator + signal data_i_f : std_logic_vector(43 downto 0); + signal data_i : std_logic_vector(43 downto 0); + signal data_clk_i_f : std_logic; + signal data_clk_i : std_logic; - type ST_STATES is (ST_IDLE, - ST_BUSY + signal self_trigger_on : std_logic; + signal self_trigger : std_logic; + + -- Trigger Outputs + signal trigger_output_select : std_logic; -- 0: Ext 1: Intern + signal external_trigger_i : std_logic; + signal external_trigger_o : std_logic; + signal internal_trigger_o : std_logic; + signal trigger : std_logic; + + type S_STATES is (S_IDLE, + S_BUSY ); - signal ST_STATE : ST_STATES; + signal S_STATE : S_STATES; - signal self_trigger_ctr : unsigned(4 downto 0); - signal self_trigger_busy : std_logic; - signal self_trigger : std_logic; - signal self_trigger_o : std_logic; - - -- TRBNet Slave Bus - signal slv_data_out_o : std_logic_vector(31 downto 0); - signal slv_no_more_data_o : std_logic; - signal slv_unknown_addr_o : std_logic; - signal slv_ack_o : std_logic; + signal external_trigger_on : std_logic; + signal external_trigger_ctr : unsigned(4 downto 0); + signal external_trigger_busy : std_logic; + signal external_trigger : std_logic; + + -- Rate Calculation + signal self_trigger_rate_t : unsigned(27 downto 0); + signal self_trigger_rate : unsigned(27 downto 0); + signal pulser_trigger_rate_t : unsigned(27 downto 0); + signal pulser_trigger_rate : unsigned(27 downto 0); + signal trigger_rate : unsigned(27 downto 0); + signal trigger_rate_t : unsigned(27 downto 0); + signal rate_timer : unsigned(27 downto 0); + + -- TRBNet Slave Bus + signal slv_data_out_o : std_logic_vector(31 downto 0); + signal slv_no_more_data_o : std_logic; + signal slv_unknown_addr_o : std_logic; + signal slv_ack_o : std_logic; + signal pulser_trigger_period_r : unsigned(27 downto 0); -- Reset - signal RESET_NX_MAIN_CLK_IN : std_logic; + signal RESET_NX_MAIN_CLK_IN : std_logic; - signal new_data_frame_debug : std_logic; - begin -- Debug Line - DEBUG_OUT(0) <= CLK_IN; - DEBUG_OUT(1) <= NX_MAIN_CLK_IN; - DEBUG_OUT(2) <= self_trigger; - DEBUG_OUT(3) <= self_trigger_o; - DEBUG_OUT(4) <= self_trigger_busy; - DEBUG_OUT(5) <= TRIGGER_BUSY_IN; - DEBUG_OUT(6) <= DATA_CLK_IN; - DEBUG_OUT(7) <= new_data_frame_debug; - DEBUG_OUT(15 downto 8 ) <= (others => '0'); + DEBUG_OUT(0) <= CLK_IN; + DEBUG_OUT(1) <= NX_MAIN_CLK_IN; + DEBUG_OUT(2) <= DATA_CLK_IN; + DEBUG_OUT(3) <= TRIGGER_BUSY_IN; + + DEBUG_OUT(4) <= self_trigger_on; + DEBUG_OUT(5) <= self_trigger; + + DEBUG_OUT(6) <= pulser_trigger_on; + DEBUG_OUT(7) <= pulser_trigger; + DEBUG_OUT(8) <= external_trigger_busy; + DEBUG_OUT(9) <= external_trigger; + + DEBUG_OUT(10) <= internal_trigger_o; + DEBUG_OUT(11) <= external_trigger_o; + DEBUG_OUT(12) <= trigger_output_select; + DEBUG_OUT(13) <= trigger; + DEBUG_OUT(15 downto 14) <= (others => '0'); + ----------------------------------------------------------------------------- -- Reset Domain Transfer ----------------------------------------------------------------------------- @@ -82,74 +118,183 @@ begin ); ----------------------------------------------------------------------------- - -- Generate Trigger + -- Generate Pulser Trigger ----------------------------------------------------------------------------- + timer_PULSER_TRIGGER: timer + generic map ( + CTR_WIDTH => 28 + ) + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + TIMER_START_IN => pulser_trigger_on, + TIMER_END_IN => pulser_trigger_period, + + TIMER_DONE_OUT => pulser_trigger + ); + + pulser_trigger_period <= (pulser_trigger_period_r - 1) + when pulser_trigger_period_r > 10 + else x"0000009"; + ----------------------------------------------------------------------------- -- Self Trigger ----------------------------------------------------------------------------- - + PROC_SELF_TRIGGER: process(CLK_IN) variable frame_bits : std_logic_vector(3 downto 0); begin if( rising_edge(CLK_IN) ) then + data_i_f <= DATA_IN; + data_i <= data_i_f; + data_clk_i_f <= DATA_CLK_IN; + data_clk_i <= data_clk_i_f; + if( RESET_IN = '1' ) then - self_trigger_ctr <= (others => '0'); - self_trigger_busy <= '0'; self_trigger <= '0'; else - frame_bits := DATA_IN(31) & - DATA_IN(23) & - DATA_IN(15) & - DATA_IN(7); - self_trigger <= '0'; - self_trigger_busy <= '0'; - - if (DATA_CLK_IN = '1' and + frame_bits := data_i(31) & + data_i(23) & + data_i(15) & + data_i(7); + self_trigger <= '0'; + + if (self_trigger_on = '1' and + data_clk_i = '1' and frame_bits = "1000") then - new_data_frame_debug <= '1'; + self_trigger <= '1'; else - new_data_frame_debug <= '0'; + self_trigger <= '0'; end if; - - case ST_STATE is - when ST_IDLE => + end if; + end if; + end process PROC_SELF_TRIGGER; + + ----------------------------------------------------------------------------- + -- Trigger Output Handler + ----------------------------------------------------------------------------- + + PROC_TRIGGER_OUTPUTS: process (CLK_IN) + variable trigger_signals : std_logic; + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + external_trigger_i <= '0'; + internal_trigger_o <= '0'; + else + trigger_signals := self_trigger or pulser_trigger; + + if (trigger_output_select = '0') then + external_trigger_i <= trigger_signals; + else + internal_trigger_o <= trigger_signals; + end if; + + -- For Rate Counter + trigger <= external_trigger or internal_trigger_o; + end if; + end if; + end process PROC_TRIGGER_OUTPUTS; + + PROC_EXTERN_TRIGGER_OUT: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + external_trigger_ctr <= (others => '0'); + external_trigger_busy <= '0'; + external_trigger <= '0'; + else + external_trigger <= '0'; + external_trigger_busy <= '0'; + + case S_STATE is + when S_IDLE => if (TRIGGER_BUSY_IN = '0' and - DATA_CLK_IN = '1' and - frame_bits = "1000") then - self_trigger_ctr <= "10100"; -- 20 - self_trigger <= '1'; - ST_STATE <= ST_BUSY; + external_trigger_i = '1') then + external_trigger_ctr <= "10100"; -- 20 + external_trigger <= '1'; + S_STATE <= S_BUSY; else - self_trigger_ctr <= (others => '0'); - ST_STATE <= ST_IDLE; + external_trigger_ctr <= (others => '0'); + S_STATE <= S_IDLE; end if; - when ST_BUSY => - if (self_trigger_ctr > 0) then - self_trigger_ctr <= self_trigger_ctr - 1; - self_trigger_busy <= '1'; - ST_STATE <= ST_BUSY; + when S_BUSY => + if (external_trigger_ctr > 0) then + external_trigger_ctr <= external_trigger_ctr - 1; + external_trigger_busy <= '1'; + S_STATE <= S_BUSY; else - ST_STATE <= ST_IDLE; + S_STATE <= S_IDLE; end if; end case; end if; end if; - end process PROC_SELF_TRIGGER; - - pulse_to_level_SELF_TRIGGER: pulse_to_level + end process PROC_EXTERN_TRIGGER_OUT; + + -- Goes to CTS + pulse_to_level_EXTERNAL_TRIGGER: pulse_to_level generic map ( NUM_CYCLES => 8 ) port map ( CLK_IN => CLK_IN, RESET_IN => RESET_IN, - PULSE_IN => self_trigger, - LEVEL_OUT => self_trigger_o + PULSE_IN => external_trigger, + LEVEL_OUT => external_trigger_o ); - + + ----------------------------------------------------------------------------- + -- Rate Counter + ----------------------------------------------------------------------------- + PROC_CAL_RATES: process (CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if (RESET_IN = '1') then + self_trigger_rate_t <= (others => '0'); + self_trigger_rate <= (others => '0'); + pulser_trigger_rate_t <= (others => '0'); + pulser_trigger_rate <= (others => '0'); + trigger_rate_t <= (others => '0'); + trigger_rate <= (others => '0'); + rate_timer <= (others => '0'); + else + if (rate_timer < x"5f5e100") then + if (self_trigger = '1') then + self_trigger_rate_t <= self_trigger_rate_t + 1; + end if; + + if (pulser_trigger = '1') then + pulser_trigger_rate_t <= pulser_trigger_rate_t + 1; + end if; + + if (trigger = '1') then + trigger_rate_t <= trigger_rate_t + 1; + end if; + + rate_timer <= rate_timer + 1; + else + self_trigger_rate_t(27 downto 1) <= (others => '0'); + self_trigger_rate_t(0) <= '0'; + + pulser_trigger_rate_t(27 downto 1) <= (others => '0'); + pulser_trigger_rate_t(0) <= pulser_trigger; + + trigger_rate_t(27 downto 1) <= (others => '0'); + trigger_rate_t(0) <= trigger; + + self_trigger_rate <= self_trigger_rate_t; + pulser_trigger_rate <= pulser_trigger_rate_t; + trigger_rate <= trigger_rate_t; + + rate_timer <= (others => '0'); + end if; + end if; + end if; + end process PROC_CAL_RATES; + ----------------------------------------------------------------------------- -- TRBNet Slave Bus ----------------------------------------------------------------------------- @@ -158,33 +303,80 @@ 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'; + slv_data_out_o <= (others => '0'); + slv_no_more_data_o <= '0'; + slv_unknown_addr_o <= '0'; + slv_ack_o <= '0'; + trigger_output_select <= '0'; + self_trigger_on <= '1'; + pulser_trigger_on <= '0'; + pulser_trigger_period_r <= x"00186a0"; else slv_unknown_addr_o <= '0'; slv_no_more_data_o <= '0'; slv_data_out_o <= (others => '0'); - + if (SLV_WRITE_IN = '1') then case SLV_ADDR_IN is + + when x"0000" => + self_trigger_on <= SLV_DATA_IN(0); + pulser_trigger_on <= SLV_DATA_IN(1); + trigger_output_select <= SLV_DATA_IN(2); + slv_ack_o <= '1'; + when x"0001" => + pulser_trigger_period_r <= + unsigned(SLV_DATA_IN(27 downto 0)); + slv_ack_o <= '1'; + when others => - slv_unknown_addr_o <= '1'; - slv_ack_o <= '0'; + slv_unknown_addr_o <= '1'; + slv_ack_o <= '0'; end case; elsif (SLV_READ_IN = '1') then + case SLV_ADDR_IN is + when x"0000" => + slv_data_out_o(0) <= self_trigger_on; + slv_data_out_o(1) <= pulser_trigger_on; + slv_data_out_o(2) <= trigger_output_select; + slv_data_out_o(31 downto 3) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0001" => + slv_data_out_o(27 downto 0) <= + std_logic_vector(pulser_trigger_period_r); + slv_data_out_o(31 downto 28) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0002" => + slv_data_out_o(27 downto 0) <= + std_logic_vector(self_trigger_rate); + slv_data_out_o(31 downto 28) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0003" => + slv_data_out_o(27 downto 0) <= + std_logic_vector(pulser_trigger_rate); + slv_data_out_o(31 downto 28) <= (others => '0'); + slv_ack_o <= '1'; + + when x"0004" => + slv_data_out_o(27 downto 0) <= + std_logic_vector(trigger_rate); + slv_data_out_o(31 downto 28) <= (others => '0'); + slv_ack_o <= '1'; + when others => - slv_unknown_addr_o <= '1'; - slv_ack_o <= '0'; + slv_unknown_addr_o <= '1'; + slv_ack_o <= '0'; end case; else - slv_ack_o <= '0'; + slv_ack_o <= '0'; end if; end if; end if; @@ -195,8 +387,8 @@ begin ----------------------------------------------------------------------------- -- Trigger Output - TRIGGER_OUT <= '0'; - SELF_TRIGGER_OUT <= self_trigger_o; + EXTERNAL_TRIGGER_OUT <= external_trigger_o; + INTERNAL_TRIGGER_OUT <= internal_trigger_o; -- Slave Bus SLV_DATA_OUT <= slv_data_out_o; diff --git a/nxyter/source/nx_trigger_handler.vhd b/nxyter/source/nx_trigger_handler.vhd index e99744b..9d6ed5c 100644 --- a/nxyter/source/nx_trigger_handler.vhd +++ b/nxyter/source/nx_trigger_handler.vhd @@ -85,6 +85,9 @@ architecture Behavioral of nx_trigger_handler is signal timestamp_trigger_o : std_logic; signal invalid_timing_trigger_n : std_logic; + + signal invalid_timing_trigger_ff : std_logic; + signal invalid_timing_trigger_f : std_logic; signal invalid_timing_trigger : std_logic; signal invalid_timing_trigger_ctr : unsigned(15 downto 0); @@ -114,6 +117,7 @@ architecture Behavioral of nx_trigger_handler is signal fee_trg_release_o : std_logic; signal fee_trg_statusbits_o : std_logic_vector(31 downto 0); signal send_testpulse : std_logic; + signal testpulse_enable : std_logic; type STATES is (S_IDLE, @@ -155,6 +159,9 @@ architecture Behavioral of nx_trigger_handler is signal wait_timer_end : unsigned(11 downto 0); -- Rate Calculation + signal send_testpulse_ff : std_logic; + signal send_testpulse_f : std_logic; + signal accepted_trigger_rate_t : unsigned(27 downto 0); signal testpulse_o_clk100 : std_logic; signal testpulse_rate_t : unsigned(27 downto 0); @@ -364,7 +371,12 @@ begin PULSE_A_IN => fast_clear_o, PULSE_OUT => fast_clear ); - + + -- Relax Timing + invalid_timing_trigger_ff <= + invalid_timing_trigger_n when rising_edge(NX_MAIN_CLK_IN); + invalid_timing_trigger_f <= + invalid_timing_trigger_ff when rising_edge(NX_MAIN_CLK_IN); pulse_dtrans_INVALID_TIMING_TRIGGER: pulse_dtrans generic map ( CLK_RATIO => 4 @@ -372,7 +384,7 @@ begin port map ( CLK_A_IN => NX_MAIN_CLK_IN, RESET_A_IN => RESET_NX_MAIN_CLK_IN, - PULSE_A_IN => invalid_timing_trigger_n, + PULSE_A_IN => invalid_timing_trigger_f, CLK_B_IN => CLK_IN, RESET_B_IN => RESET_IN, PULSE_B_OUT => invalid_timing_trigger @@ -594,6 +606,9 @@ begin end if; end process PROC_TESTPULSE_HANDLER; + -- Relax Timing + send_testpulse_ff <= send_testpulse when rising_edge(NX_MAIN_CLK_IN); + send_testpulse_f <= send_testpulse_ff when rising_edge(NX_MAIN_CLK_IN); pulse_dtrans_TESTPULSE_RATE: pulse_dtrans generic map ( CLK_RATIO => 2 @@ -601,7 +616,7 @@ begin port map ( CLK_A_IN => NX_MAIN_CLK_IN, RESET_A_IN => RESET_NX_MAIN_CLK_IN, - PULSE_A_IN => testpulse_o, + PULSE_A_IN => send_testpulse_f, CLK_B_IN => CLK_IN, RESET_B_IN => RESET_IN, PULSE_B_OUT => testpulse_o_clk100 diff --git a/nxyter/source/nx_trigger_validate.vhd b/nxyter/source/nx_trigger_validate.vhd index b18778e..7f6a5e0 100644 --- a/nxyter/source/nx_trigger_validate.vhd +++ b/nxyter/source/nx_trigger_validate.vhd @@ -165,7 +165,8 @@ architecture Behavioral of nx_trigger_validate is signal wait_timer_done : std_logic; signal wait_timer_done_ns : std_logic; - -- Histogram + -- Histogram + signal histogram_trigger_all : std_logic; signal histogram_fill_o : std_logic; signal histogram_bin_o : std_logic_vector(6 downto 0); signal histogram_adc_o : std_logic_vector(11 downto 0); @@ -185,7 +186,8 @@ architecture Behavioral of nx_trigger_validate is signal slv_unknown_addr_o : std_logic; signal slv_ack_o : std_logic; - signal readout_mode_r : std_logic_vector(3 downto 0); + signal readout_mode_r : std_logic_vector(3 downto 0); + signal histogram_trigger_all_r : std_logic; signal out_of_window_error_ctr_clear : std_logic; -- Timestamp Trigger Window Settings @@ -277,12 +279,13 @@ begin out_of_window_error <= '0'; fifo_delay_time <= (others => '0'); ch_status_cmd_pr <= CS_NONE; - + histogram_fill_o <= '0'; histogram_bin_o <= (others => '0'); histogram_adc_o <= (others => '0'); histogram_pileup_o <= '0'; histogram_ovfl_o <= '0'; + histogram_trigger_all <= histogram_trigger_all_r; ----------------------------------------------------------------------- -- Calculate Thresholds and values for FIFO Delay @@ -408,6 +411,16 @@ begin end if; end case; + + -- Fill Histogram + if (histogram_trigger_all = '0') then + histogram_fill_o <= '1'; + histogram_bin_o <= CHANNEL_IN; + histogram_adc_o <= ADC_DATA_IN; + histogram_pileup_o <= TIMESTAMP_STATUS_IN(S_PILEUP); + histogram_ovfl_o <= TIMESTAMP_STATUS_IN(S_OVFL); + end if; + end if; if (out_of_window_error_ctr_clear = '1') then @@ -416,12 +429,14 @@ begin end if; -- Fill Histogram - histogram_fill_o <= '1'; - histogram_bin_o <= CHANNEL_IN; - histogram_adc_o <= ADC_DATA_IN; - histogram_pileup_o <= TIMESTAMP_STATUS_IN(S_PILEUP); - histogram_ovfl_o <= TIMESTAMP_STATUS_IN(S_OVFL); - + if (histogram_trigger_all = '1') then + histogram_fill_o <= '1'; + histogram_bin_o <= CHANNEL_IN; + histogram_adc_o <= ADC_DATA_IN; + histogram_pileup_o <= TIMESTAMP_STATUS_IN(S_PILEUP); + histogram_ovfl_o <= TIMESTAMP_STATUS_IN(S_OVFL); + end if; + end if; end if; end if; @@ -844,7 +859,6 @@ begin -- Give status info to the TRB Slow Control Channel PROC_SLAVE_BUS: process(CLK_IN) - begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then @@ -858,6 +872,7 @@ begin cts_trigger_delay <= x"0c8"; readout_mode_r <= "0000"; readout_time_max <= x"3e8"; + histogram_trigger_all_r <= '1'; fpga_timestamp_offset <= (others => '0'); out_of_window_error_ctr_clear <= '0'; skip_wait_for_data <= '0'; @@ -875,7 +890,8 @@ begin case SLV_ADDR_IN is when x"0000" => slv_data_out_o( 3 downto 0) <= readout_mode_r; - slv_data_out_o(31 downto 5) <= (others => '0'); + slv_data_out_o(30 downto 5) <= (others => '0'); + slv_data_out_o(31) <= histogram_trigger_all_r; slv_ack_o <= '1'; when x"0001" => @@ -1066,6 +1082,7 @@ begin case SLV_ADDR_IN is when x"0000" => readout_mode_r <= SLV_DATA_IN(3 downto 0); + histogram_trigger_all_r <= SLV_DATA_IN(31); slv_ack_o <= '1'; when x"0001" => diff --git a/nxyter/source/nxyter_components.vhd b/nxyter/source/nxyter_components.vhd index 93be57d..5b02221 100644 --- a/nxyter/source/nxyter_components.vhd +++ b/nxyter/source/nxyter_components.vhd @@ -920,10 +920,10 @@ component nx_trigger_generator RESET_IN : in std_logic; NX_MAIN_CLK_IN : in std_logic; TRIGGER_BUSY_IN : in std_logic; - TRIGGER_OUT : out std_logic; + EXTERNAL_TRIGGER_OUT : out std_logic; + INTERNAL_TRIGGER_OUT : out std_logic; DATA_IN : in std_logic_vector(43 downto 0); DATA_CLK_IN : in std_logic; - SELF_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); diff --git a/nxyter/source/nxyter_fee_board.vhd b/nxyter/source/nxyter_fee_board.vhd index 6500021..2234176 100644 --- a/nxyter/source/nxyter_fee_board.vhd +++ b/nxyter/source/nxyter_fee_board.vhd @@ -139,7 +139,6 @@ architecture Behavioral of nXyter_FEE_board is -- Data Receiver signal data_recv : std_logic_vector(43 downto 0); signal data_clk_recv : std_logic; - signal self_trigger : std_logic; signal pll_sadc_clk_lock : std_logic; -- Data Delay @@ -205,8 +204,8 @@ architecture Behavioral of nXyter_FEE_board is signal timestamp_hold : unsigned(11 downto 0); -- Trigger Generator - signal trigger_intern : std_logic; - + signal internal_trigger : std_logic; + -- Error signal error_all : std_logic_vector(7 downto 0); signal error_data_receiver : std_logic; @@ -438,7 +437,7 @@ begin CLK_IN => CLK_IN, RESET_IN => RESET_IN, NX_MAIN_CLK_IN => CLK_NX_MAIN_IN, - TIMESTAMP_RESET_1_IN => nx_timestamp_reset_status, + TIMESTAMP_RESET_1_IN => '0', --nx_timestamp_reset_status, TIMESTAMP_RESET_2_IN => nx_timestamp_reset_receiver, TIMESTAMP_RESET_OUT => nx_timestamp_reset_o, TRIGGER_IN => timestamp_trigger, @@ -488,7 +487,7 @@ begin FEE_DATA_WRITE_0_IN => fee_data_write_o_0, FEE_DATA_1_IN => fee_data_o_1, FEE_DATA_WRITE_1_IN => fee_data_write_o_1, - INTERNAL_TRIGGER_IN => trigger_intern, + INTERNAL_TRIGGER_IN => '0', --internal_trigger, TRIGGER_VALIDATE_BUSY_IN => trigger_validate_busy, TRIGGER_BUSY_0_IN => trigger_evt_busy_0, @@ -526,11 +525,11 @@ begin NX_MAIN_CLK_IN => CLK_NX_MAIN_IN, TRIGGER_BUSY_IN => trigger_busy, - TRIGGER_OUT => trigger_intern, - + EXTERNAL_TRIGGER_OUT => TRIGGER_OUT, + INTERNAL_TRIGGER_OUT => internal_trigger, + DATA_IN => data_recv, DATA_CLK_IN => data_clk_recv, - SELF_TRIGGER_OUT => self_trigger, SLV_READ_IN => slv_read(5), SLV_WRITE_IN => slv_write(5), @@ -800,7 +799,6 @@ begin ------------------------------------------------------------------------------- -- Others ------------------------------------------------------------------------------- - TRIGGER_OUT <= self_trigger; ------------------------------------------------------------------------------- -- DEBUG Line Select diff --git a/nxyter/trb3_periph_constraints.lpf b/nxyter/trb3_periph_constraints.lpf index 0ceebf7..76de648 100644 --- a/nxyter/trb3_periph_constraints.lpf +++ b/nxyter/trb3_periph_constraints.lpf @@ -100,9 +100,9 @@ MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/new_timestamp_dt_err MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_clk_ok" 100 ns; MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_debug_type*" 100 ns; MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/nx_timestamp_reset_o*" 100 ns; -MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_notlock_ctr_r* 100 ns; -MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/merge_error_ctr_*" 100 ns; -MULTICYCLE FROM CELL "nXyter_FEE_board_*/nx_data_receiver_*/reg_nx_frame_synced*" 100 ns; +MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/adc_notlock_ctr_r*" 100 ns; +MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/merge_error_ctr_r*" 100 ns; +MULTICYCLE TO CELL "nXyter_FEE_board_*/nx_data_receiver_*/nx_frame_synced_r*" 100 ns; MULTICYCLE FROM CELL "nXyter_FEE_board_*/debug_multiplexer_*/port_select_*" 100 ns; #SPI Interface -- 2.43.0