From: hadaq Date: Thu, 15 Jul 2010 15:29:38 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: oldGBE~219 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=dc7cdeff28be07867129dc001e3dcd334de4b177;p=trbnet.git *** empty log message *** --- diff --git a/special/handler_lvl1.vhd b/special/handler_lvl1.vhd index a8e1f40..6477d25 100644 --- a/special/handler_lvl1.vhd +++ b/special/handler_lvl1.vhd @@ -24,12 +24,12 @@ port( LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0); LVL1_ERROR_PATTERN_OUT : out std_logic_vector(31 downto 0); --errorbits to CTS LVL1_TRG_RELEASE_OUT : out std_logic := '0'; --release to CTS - + LVL1_INT_TRG_NUMBER_OUT : out std_logic_vector(15 downto 0); -- increased after trigger release - LVL1_INT_TRG_RESET_IN : in std_logic; -- reset internal trigger counter +-- LVL1_INT_TRG_RESET_IN : in std_logic; -- reset internal trigger counter LVL1_INT_TRG_LOAD_IN : in std_logic; -- load internal trigger counter - LVL1_INT_TRG_COUNTER_IN : in std_logic_vector(15 downto 0); -- load value for internal trigger counter - + LVL1_INT_TRG_COUNTER_IN : in std_logic_vector(15 downto 0); -- load value for internal trigger counter + --FEE logic / Data Handler LVL1_TRG_DATA_VALID_OUT : out std_logic; -- trigger type, number, code, information are valid LVL1_VALID_TIMING_TRG_OUT : out std_logic; -- valid timing trigger has been received @@ -37,12 +37,12 @@ port( LVL1_INVALID_TRG_OUT : out std_logic; -- the current trigger is invalid (e.g. no timing trigger, no LVL1...) LVL1_MULTIPLE_TRG_OUT : out std_logic; -- more than one timing trigger detected LVL1_DELAY_OUT : out std_logic_vector(15 downto 0); - + LVL1_ERROR_PATTERN_IN : in std_logic_vector(31 downto 0); -- error pattern from FEE LVL1_TRG_RELEASE_IN : in std_logic := '0'; -- trigger release from FEE - + --Stat/Control - STATUS_OUT : out std_logic_vector (31 downto 0); -- bits for status registers + STATUS_OUT : out std_logic_vector (63 downto 0); -- bits for status registers TRG_ENABLE_IN : in std_logic; -- trigger enable flag TRG_INVERT_IN : in std_logic; -- trigger invert flag --Debug @@ -65,11 +65,13 @@ port( end component pulse_stretch; -- state machine signals -type STATES is (IDLE, BADTRG, TRGFND, LVL1FND, WAITREL, TOCFND, RELEASE, DONE); +type STATES is (IDLE, BADTRG, TRGFND, LVL1FND, WAITREL, TOCFND, DONE); signal CURRENT_STATE, NEXT_STATE: STATES; signal toc_ce : std_logic; -- count enable for TRG/LVL1 timeout signal next_toc_ce : std_logic; +signal toc_save : std_logic; -- count enable for TRG/LVL1 timeout +signal next_toc_save : std_logic; signal toc_rst : std_logic; -- reset for timout signal next_toc_rst : std_logic; signal trg_rel : std_logic; -- release LVL1 channel @@ -79,7 +81,7 @@ signal next_trg_rst : std_logic; signal val_trg : std_logic; -- valid timing + LVL1 trigger signal next_val_trg : std_logic; signal val_ttl_trg : std_logic; -- valid timingtriggerless trigger (who invented that name?) -signal next_val_ttl_trg : std_logic; +signal next_val_ttl_trg : std_logic; signal invalid_trg : std_logic; -- invalid trigger: LVL1 missing, or wrong information signal next_invalid_trg : std_logic; @@ -99,7 +101,7 @@ signal timing_trg_reg : std_logic_vector(3 downto 0); signal timing_trg_comb : std_logic; signal timing_trg_rising : std_logic; signal timing_trg_found : std_logic; -signal timeout_ctr : unsigned(8 downto 0); +signal timeout_ctr : unsigned(10 downto 0); signal timeout_found : std_logic; signal next_timeout_found : std_logic; signal trg_num_match : std_logic; @@ -109,19 +111,13 @@ signal error_pattern : std_logic_vector(31 downto 0); signal next_error_pattern : std_logic_vector(31 downto 0); signal lvl1_delay : std_logic_vector(15 downto 0); +signal trigger_edge_count : unsigned(15 downto 0); +signal trigger_length : unsigned(15 downto 0); signal debug : std_logic_vector(15 downto 0); begin ---------------------------------------------------------------------------- --- Debug signals ---------------------------------------------------------------------------- -debug(15 downto 12) <= bsm_x; -debug(11 downto 9) <= (others => '0'); -debug(8 downto 0) <= std_logic_vector(timeout_ctr); - -DEBUG_OUT <= debug; --------------------------------------------------------------------------- -- One process for registering combinatorial signals @@ -131,7 +127,6 @@ begin if( rising_edge(CLOCK) ) then timeout_found <= next_timeout_found; trg_num_match <= next_trg_num_match; - data_valid <= next_data_valid; error_pattern <= next_error_pattern; end if; end process THE_SYNC_PROC; @@ -151,7 +146,7 @@ port map( --------------------------------------------------------------------------- -- Sync the external timing trigger, if necessary. --------------------------------------------------------------------------- -GEN_SYNC: if ( TIMING_TRIGGER_RAW = 1 ) generate +GEN_SYNC: if ( TIMING_TRIGGER_RAW = c_YES ) generate THE_TIMING_TRG_SYNC: signal_sync generic map( WIDTH => 1, DEPTH => 2 ) port map( @@ -161,10 +156,36 @@ GEN_SYNC: if ( TIMING_TRIGGER_RAW = 1 ) generate D_IN(0) => LVL1_TIMING_TRG_IN, D_OUT(0) => synced_timing_trg ); + + THE_TRIGGER_SHIFT_PROC: process( CLOCK ) + begin + if( rising_edge(CLOCK) ) then + if( RESET = '1' ) then + timing_trg_reg <= (others => '0'); + else + timing_trg_reg <= timing_trg_reg(2 downto 0) & timing_trg_comb; -- could be generalized here + end if; + end if; + end process THE_TRIGGER_SHIFT_PROC; + + -- detect rising edge and valid length + THE_RISING_EDGE_PROC: process( CLOCK ) + begin + if( rising_edge(CLOCK) ) then + if( RESET = '1' ) then + timing_trg_rising <= '0'; + else + -- 0111 sequence marks the rising edge + timing_trg_rising <= not timing_trg_reg(3) and timing_trg_reg(2) and timing_trg_reg(1) and timing_trg_reg(0); + end if; + end if; + end process THE_RISING_EDGE_PROC; + end generate GEN_SYNC; -GEN_NOSYNC: if ( TIMING_TRIGGER_RAW = 0 ) generate +GEN_NOSYNC: if ( TIMING_TRIGGER_RAW = c_NO ) generate synced_timing_trg <= LVL1_TIMING_TRG_IN; + timing_trg_rising <= synced_timing_trg; end generate GEN_NOSYNC; --------------------------------------------------------------------------- @@ -172,29 +193,6 @@ end generate GEN_NOSYNC; --------------------------------------------------------------------------- timing_trg_comb <= ((synced_timing_trg xor TRG_INVERT_IN) and TRG_ENABLE_IN) or stretched_fake_trg; -THE_TRIGGER_SHIFT_PROC: process( CLOCK ) -begin - if( rising_edge(CLOCK) ) then - if( RESET = '1' ) then - timing_trg_reg <= (others => '0'); - else - timing_trg_reg <= timing_trg_reg(2 downto 0) & timing_trg_comb; -- could be generalized here - end if; - end if; -end process THE_TRIGGER_SHIFT_PROC; - --- detect rising edge and valid length -THE_RISING_EDGE_PROC: process( CLOCK ) -begin - if( rising_edge(CLOCK) ) then - if( RESET = '1' ) then - timing_trg_rising <= '0'; - else - -- 0111 sequence marks the rising edge - timing_trg_rising <= not timing_trg_reg(3) and timing_trg_reg(2) and timing_trg_reg(1) and timing_trg_reg(0); - end if; - end if; -end process THE_RISING_EDGE_PROC; -- latch the result for state machine -- detect multiple timing triggers @@ -212,38 +210,22 @@ begin end process THE_LATCH_PROC; --------------------------------------------------------------------------- --- Timeout counter for LVL1 +-- Timeout counter for LVL1 --------------------------------------------------------------------------- THE_TIMEOUT_CTR_PROC: process( CLOCK ) begin if( rising_edge(CLOCK) ) then if ( (RESET = '1') or (toc_rst = '1') ) then timeout_ctr <= (others => '0'); - elsif( (toc_ce = '1') and (timeout_found = '0') ) then + elsif( (toc_ce = '1') and (and_all(std_logic_vector(timeout_ctr)) = '0') ) then timeout_ctr <= timeout_ctr + 1; - end if; + end if; end if; end process THE_TIMEOUT_CTR_PROC; --- 5.12us maximum --- Jan, be fast :-) -next_timeout_found <= '1' when ( timeout_ctr = b"1_1111_1111" ) else '0'; +-- 20.48us maximum +next_timeout_found <= and_all(std_logic_vector(timeout_ctr)); --- store measured delay --- BUG: register loading is not perfect! -THE_MEASURED_DELAY_PROC: process( CLOCK ) -begin - if( rising_edge(CLOCK) ) then - if ( RESET = '1' ) then - lvl1_delay <= (others => '0'); - elsif( toc_rst = '1' ) then - lvl1_delay(15 downto 9) <= (others => '0'); -- here we can store nice status bits - lvl1_delay(8 downto 0) <= std_logic_vector(timeout_ctr); - end if; - end if; -end process THE_MEASURED_DELAY_PROC; - -LVL1_DELAY_OUT <= lvl1_delay; --------------------------------------------------------------------------- -- State machine @@ -256,115 +238,115 @@ begin CURRENT_STATE <= IDLE; toc_ce <= '0'; toc_rst <= '1'; + toc_save <= '0'; trg_rel <= '0'; trg_rst <= '0'; val_trg <= '0'; val_ttl_trg <= '0'; invalid_trg <= '0'; + data_valid <= '0'; else CURRENT_STATE <= NEXT_STATE; toc_ce <= next_toc_ce; toc_rst <= next_toc_rst; + toc_save <= next_toc_save; trg_rel <= next_trg_rel; trg_rst <= next_trg_rst; val_trg <= next_val_trg; val_ttl_trg <= next_val_ttl_trg; invalid_trg <= next_invalid_trg; + data_valid <= next_data_valid; end if; end if; end process STATE_MEM; -- state transitions STATE_TRANSFORM: process( CURRENT_STATE, LVL1_TRG_RECEIVED_IN, LVL1_TRG_TYPE_IN(3), LVL1_TRG_INFORMATION_IN(7), - LVL1_TRG_RELEASE_IN, timing_trg_found, timing_trg_rising, timeout_found ) + LVL1_TRG_RELEASE_IN, timing_trg_found, timing_trg_rising, timeout_found, data_valid ) begin - NEXT_STATE <= IDLE; -- avoid latches - next_toc_ce <= '0'; - next_toc_rst <= '0'; - next_trg_rel <= '0'; - next_trg_rst <= '0'; - next_val_trg <= val_trg; - next_val_ttl_trg <= val_ttl_trg; - next_invalid_trg <= invalid_trg; + NEXT_STATE <= IDLE; -- avoid latches + next_toc_ce <= '0'; + next_toc_rst <= '0'; + next_toc_save <= toc_save; + next_trg_rel <= '0'; + next_trg_rst <= '0'; + next_val_trg <= '0'; + next_val_ttl_trg <= '0'; + next_invalid_trg <= '0'; + next_data_valid <= data_valid; case CURRENT_STATE is when IDLE => bsm_x <= x"0"; - if ( (timing_trg_found = '1') ) then - -- timing trigger has a rising edge and valid length - NEXT_STATE <= TRGFND; - next_toc_rst <= '1'; - elsif( (timing_trg_found = '0') and (LVL1_TRG_RECEIVED_IN = '1') and - (LVL1_TRG_TYPE_IN(3) = '1') and (LVL1_TRG_INFORMATION_IN(7) = '1')) then - -- timingtriggerless trigger found - NEXT_STATE <= LVL1FND; - next_toc_rst <= '1'; - next_val_ttl_trg <= '1'; - elsif( (timing_trg_found = '0') and (LVL1_TRG_RECEIVED_IN = '1') and - ((LVL1_TRG_TYPE_IN(3) = '0') or (LVL1_TRG_INFORMATION_IN(7) = '0')) ) then - -- missing timing trigger - NEXT_STATE <= BADTRG; - next_invalid_trg <= '1'; - else - NEXT_STATE <= IDLE; - end if; + if ( (timing_trg_found = '1') ) then + -- timing trigger has a rising edge and valid length + NEXT_STATE <= TRGFND; + next_toc_rst <= '1'; + next_val_trg <= '1'; + elsif( (timing_trg_found = '0') and (LVL1_TRG_RECEIVED_IN = '1') and + (LVL1_TRG_TYPE_IN(3) = '1') and (LVL1_TRG_INFORMATION_IN(7) = '1')) then + -- timingtriggerless trigger found + NEXT_STATE <= LVL1FND; + next_toc_rst <= '1'; + next_val_ttl_trg <= '1'; + next_data_valid <= '1'; + elsif( (timing_trg_found = '0') and (LVL1_TRG_RECEIVED_IN = '1') and + ((LVL1_TRG_TYPE_IN(3) = '0') or (LVL1_TRG_INFORMATION_IN(7) = '0')) ) then + -- missing timing trigger + NEXT_STATE <= BADTRG; + next_invalid_trg <= '1'; + else + NEXT_STATE <= IDLE; + end if; when TRGFND => bsm_x <= x"1"; - if ( LVL1_TRG_RECEIVED_IN = '1' ) then - -- suitable LVL1 information has arrived - NEXT_STATE <= LVL1FND; - next_toc_rst <= '1'; - next_val_trg <= '1'; - elsif( timeout_found = '1' ) then - -- LVL1 did not arrive in time - NEXT_STATE <= TOCFND; - next_toc_rst <= '1'; - next_trg_rst <= '1'; - next_invalid_trg <= '1'; - else - -- wait for either timeout or LVL1 - NEXT_STATE <= TRGFND; - next_toc_ce <= '1'; - end if; - when TOCFND => bsm_x <= x"2"; - NEXT_STATE <= IDLE; + if ( LVL1_TRG_RECEIVED_IN = '1' ) then + -- suitable LVL1 information has arrived + NEXT_STATE <= LVL1FND; + next_data_valid <= '1'; + next_toc_rst <= '1'; +-- was commented out + elsif( timeout_found = '1' ) then + -- LVL1 did not arrive in time + NEXT_STATE <= TOCFND; + next_toc_save <= '1'; + next_toc_rst <= '1'; + next_trg_rst <= '1'; + next_invalid_trg <= '1'; +---------------------------- + else + -- wait for either timeout or LVL1 + NEXT_STATE <= TRGFND; + next_toc_ce <= '1'; + end if; +-- was commented out + when TOCFND => bsm_x <= x"2"; + NEXT_STATE <= IDLE; +---------------------------- when LVL1FND => bsm_x <= x"3"; - NEXT_STATE <= WAITREL; - when WAITREL => bsm_x <= x"4"; - if( LVL1_TRG_RELEASE_IN = '1' ) then - -- FEE logic releases trigger - NEXT_STATE <= RELEASE; - next_trg_rel <= '1'; - next_trg_rst <= '1'; - else - -- FEE logic still busy - NEXT_STATE <= WAITREL; - end if; + if( LVL1_TRG_RELEASE_IN = '1' ) then + -- FEE logic releases trigger + NEXT_STATE <= DONE; + next_trg_rel <= '1'; + next_trg_rst <= '1'; + else + -- FEE logic still busy + NEXT_STATE <= LVL1FND; --WAITREL; + end if; when BADTRG => bsm_x <= x"5"; - NEXT_STATE <= RELEASE; - next_trg_rst <= '1'; - when RELEASE => bsm_x <= x"6"; - NEXT_STATE <= DONE; - next_val_trg <= '0'; - next_val_ttl_trg <= '0'; - next_invalid_trg <= '0'; + NEXT_STATE <= DONE; + next_trg_rel <= '1'; + next_trg_rst <= '1'; when DONE => bsm_x <= x"7"; - if( LVL1_TRG_RECEIVED_IN = '0' ) then - NEXT_STATE <= IDLE; - else - NEXT_STATE <= DONE; - end if; + if( LVL1_TRG_RECEIVED_IN = '0' ) then + NEXT_STATE <= IDLE; + next_data_valid <= '0'; + else + NEXT_STATE <= DONE; + next_trg_rst <= '1'; + end if; when others => bsm_x <= x"f"; - NEXT_STATE <= IDLE; + NEXT_STATE <= IDLE; end case; -end process STATE_TRANSFORM; +end process STATE_TRANSFORM; -next_data_valid <= '1' when ( CURRENT_STATE = WAITREL ) else '0'; - -LVL1_TRG_RELEASE_OUT <= trg_rel; - -LVL1_TRG_DATA_VALID_OUT <= data_valid; -LVL1_VALID_TIMING_TRG_OUT <= val_trg; -LVL1_VALID_NOTIMING_TRG_OUT <= val_ttl_trg; -LVL1_INVALID_TRG_OUT <= invalid_trg; -LVL1_MULTIPLE_TRG_OUT <= mult_trg_found; --------------------------------------------------------------------------- -- Internal trigger counter, compare internal and external counters @@ -372,12 +354,12 @@ LVL1_MULTIPLE_TRG_OUT <= mult_trg_found; THE_INTERNAL_TRG_CTR_PROC: process( CLOCK ) begin if( rising_edge(CLOCK) ) then - if ( (RESET = '1') or (LVL1_INT_TRG_RESET_IN = '1') ) then + if ( (RESET = '1') ) then lvl1_int_trg_number <= (others => '0'); elsif( LVL1_INT_TRG_LOAD_IN = '1' ) then lvl1_int_trg_number <= unsigned(LVL1_INT_TRG_COUNTER_IN); elsif( lvl1_int_trg_ce = '1' ) then - lvl1_int_trg_number <= lvl1_int_trg_number + 1; + lvl1_int_trg_number <= lvl1_int_trg_number + to_unsigned(1,1); end if; end if; end process THE_INTERNAL_TRG_CTR_PROC; @@ -389,10 +371,28 @@ begin end if; end process THE_INC_CTR_PROC; -next_trg_num_match <= '1' when ( lvl1_int_trg_number = unsigned(LVL1_TRG_NUMBER_IN) ) - else '0'; +next_trg_num_match <= '1' when ( lvl1_int_trg_number = unsigned(LVL1_TRG_NUMBER_IN) ) + else '0'; -LVL1_INT_TRG_NUMBER_OUT <= std_logic_vector(lvl1_int_trg_number); + +--------------------------------------------------------------------------- +-- Input Monitoring +--------------------------------------------------------------------------- +COUNT_EDGES_AND_LENGTH_PROC: process(CLOCK) +begin + if( rising_edge(CLOCK) ) then + if ( RESET = '1' ) then + trigger_edge_count <= (others => '0'); + trigger_length <= (others => '0'); + elsif( (timing_trg_reg(1) = '0') and (timing_trg_reg(0) = '1') and (TRG_ENABLE_IN = '1') ) then + trigger_edge_count <= trigger_edge_count + 1; + trigger_length <= x"0001"; + elsif( (synced_timing_trg = '1') and (trigger_length /= 0) and (TRG_ENABLE_IN = '1') ) then + trigger_length <= trigger_length + 1; + trigger_edge_count <= trigger_edge_count; + end if; + end if; +end process COUNT_EDGES_AND_LENGTH_PROC; --------------------------------------------------------------------------- -- Error bits @@ -403,12 +403,65 @@ next_error_pattern(17) <= LVL1_ERROR_PATTERN_IN(17) or invalid_trg; next_error_pattern(16) <= LVL1_ERROR_PATTERN_IN(16) or trg_num_match; -- trigger counter mismatch next_error_pattern(15 downto 0) <= LVL1_ERROR_PATTERN_IN(15 downto 0); -LVL1_ERROR_PATTERN_OUT <= error_pattern; +--------------------------------------------------------------------------- +-- Delay measurement +--------------------------------------------------------------------------- +-- store measured delay +-- BUG: register loading is not perfect! +THE_MEASURED_DELAY_PROC: process( CLOCK ) +begin + if( rising_edge(CLOCK) ) then + if ( RESET = '1' ) then + lvl1_delay <= (others => '0'); + elsif( toc_rst = '1' ) then + lvl1_delay(15 downto 11) <= (others => '0'); -- here we can store nice status bits + lvl1_delay(10 downto 0) <= std_logic_vector(timeout_ctr); + end if; + end if; +end process THE_MEASURED_DELAY_PROC; --------------------------------------------------------------------------- -- Status bits --------------------------------------------------------------------------- +STATUS_OUT(63 downto 48) <= std_logic_vector(trigger_length); +STATUS_OUT(47 downto 32) <= std_logic_vector(trigger_edge_count); +STATUS_OUT(31 downto 16) <= lvl1_delay; +STATUS_OUT(15) <= timing_trg_found; +STATUS_OUT(14) <= data_valid; +STATUS_OUT(13) <= mult_trg_found; +STATUS_OUT(12) <= trg_num_match; +STATUS_OUT(11) <= timeout_found; +STATUS_OUT(10 downto 4) <= (others => '0'); +STATUS_OUT(3 downto 0) <= bsm_x; + + +--------------------------------------------------------------------------- +-- Debug signals +--------------------------------------------------------------------------- +debug(15 downto 12) <= bsm_x; +debug(11) <= synced_timing_trg; +debug(10) <= timing_trg_rising; +debug(9) <= LVL1_TRG_RECEIVED_IN; +debug(8) <= val_trg; --LVL1_VALID_TIMING_TRG_OUT; +debug(7) <= invalid_trg; --LVL1_INVALID_TRG_OUT; +debug(6) <= val_ttl_trg; --LVL1_VALID_NOTIMING_TRG_OUT; +debug(5) <= LVL1_TRG_RELEASE_IN; +debug(4) <= data_valid; +debug(3 downto 0) <= std_logic_vector(timeout_ctr(8 downto 5)); + +--------------------------------------------------------------------------- +-- Outputs +--------------------------------------------------------------------------- +LVL1_TRG_RELEASE_OUT <= trg_rel; +LVL1_TRG_DATA_VALID_OUT <= data_valid; +LVL1_VALID_TIMING_TRG_OUT <= val_trg; +LVL1_VALID_NOTIMING_TRG_OUT <= val_ttl_trg; +LVL1_INVALID_TRG_OUT <= invalid_trg; +LVL1_MULTIPLE_TRG_OUT <= mult_trg_found; +LVL1_INT_TRG_NUMBER_OUT <= std_logic_vector(lvl1_int_trg_number); +LVL1_DELAY_OUT <= lvl1_delay; +LVL1_ERROR_PATTERN_OUT <= error_pattern; -STATUS_OUT(31 downto 0) <= (others => '0'); +DEBUG_OUT <= debug; end architecture; \ No newline at end of file