From: hadaq Date: Thu, 1 Jul 2010 12:50:22 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: oldGBE~239 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=764ff7b15d87569e53c9e775c08beb7ca2c05ad9;p=trbnet.git *** empty log message *** --- diff --git a/special/handler_lvl1.vhd b/special/handler_lvl1.vhd index bccdb72..5fe0c7e 100644 --- a/special/handler_lvl1.vhd +++ b/special/handler_lvl1.vhd @@ -6,50 +6,309 @@ library work; use work.trb_net_std.all; use work.trb_net_components.all; - entity handler_lvl1 is - generic( - TIMING_TRIGGER_RAW : integer range 0 to 1 := c_YES - ); - port ( - RESET : in std_logic; - CLOCK : in std_logic; - --Timing Trigger - LVL1_TIMING_TRG_IN : in std_logic; --raw trigger signal input, min. 80 ns or strobe, see generics - LVL1_PSEUDO_TMG_TRG_IN : in std_logic; --strobe for dummy timing trigger - --LVL1_handler connection - LVL1_TRG_RECEIVED_IN : in std_logic; - LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0); - LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); - LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0); - 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 - - --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 - LVL1_VALID_NOTIMING_TRG_OUT : out std_logic; --valid trigger without timing trigger has been received - LVL1_INVALID_TRG_OUT : out std_logic; --the current trigger is invalid (e.g. no timing trigger, no LVL1...) - - 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 - TRG_ENABLE_IN : in std_logic; --trigger enable flag - --Debug - DEBUG_OUT : out std_logic_vector (15 downto 0) - ); +generic( + TIMING_TRIGGER_RAW : integer range 0 to 1 := c_YES +); +port( + RESET : in std_logic; + CLOCK : in std_logic; + --Timing Trigger + LVL1_TIMING_TRG_IN : in std_logic; --raw trigger signal input, min. 80 ns or strobe, see generics + LVL1_PSEUDO_TMG_TRG_IN : in std_logic; --strobe for dummy timing trigger + --LVL1_handler connection + LVL1_TRG_RECEIVED_IN : in std_logic; + LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0); + LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0); + LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0); + 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_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 + + --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 + LVL1_VALID_NOTIMING_TRG_OUT : out std_logic; --valid trigger without timing trigger has been received + LVL1_INVALID_TRG_OUT : out std_logic; --the current trigger is invalid (e.g. no timing trigger, no LVL1...) + + 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 + TRG_ENABLE_IN : in std_logic; -- trigger enable flag + TRG_INVERT_IN : in std_logic; -- trigger invert flag + --Debug + DEBUG_OUT : out std_logic_vector (15 downto 0) +); end entity; architecture handler_lvl1_arch of handler_lvl1 is +-- Components +component pulse_stretch is +port( + CLK_IN : in std_logic; + RESET_IN : in std_logic; + START_IN : in std_logic; + PULSE_OUT : out std_logic; + DEBUG_OUT : out std_logic_vector(15 downto 0) +); +end component pulse_stretch; + +-- state machine signals +type STATES is (IDLE, BADTRG, TRGFND, LVL1FND, WAITREL, TOCFND, RELEASE, DONE); +signal CURRENT_STATE, NEXT_STATE: STATES; + +signal toc_ce : std_logic; +signal next_toc_ce : std_logic; +signal toc_rst : std_logic; +signal next_toc_rst : std_logic; +signal bsm_x : std_logic_vector(3 downto 0); + +-- Signals +signal lvl1_int_trg_number : unsigned(15 downto 0); +signal lvl1_int_trg_ce : std_logic; +signal stretched_fake_trg : std_logic; +signal synced_timing_trg : std_logic; +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_found : std_logic; +signal next_timeout_found : std_logic; + +signal debug : std_logic_vector(15 downto 0); + +begin + +--------------------------------------------------------------------------- +-- Debug signals +--------------------------------------------------------------------------- +debug(15 downto 4) <= (others => '0'); +debug(3 downto 0) <= bsm_x; -- state bits + +DEBUG_OUT <= debug; + +--------------------------------------------------------------------------- +-- fake timing trigger has only 10ns length! +--------------------------------------------------------------------------- +THE_PULSE_STRETCH: pulse_stretch +port map( + CLK_IN => CLOCK, + RESET_IN => RESET, + START_IN => LVL1_PSEUDO_TMG_TRG_IN, + PULSE_OUT => stretched_fake_trg, + DEBUG_OUT => open +); + +--------------------------------------------------------------------------- +-- Sync the external timing trigger, if necessary. +--------------------------------------------------------------------------- +GEN_SYNC: if ( TIMING_TRIGGER_RAW = 1 ) generate + THE_TIMING_TRG_SYNC: signal_sync + generic map( WIDTH => 1, DEPTH => 2 ) + port map( + RESET => RESET, + CLK0 => CLOCK, + CLK1 => CLOCK, + D_IN(0) => LVL1_TIMING_TRG_IN, + D_OUT(0) => synced_timing_trg + ); +end generate GEN_SYNC; + +GEN_NOSYNC: if ( TIMING_TRIGGER_RAW = 0 ) generate + synced_timing_trg <= LVL1_TIMING_TRG_IN; +end generate GEN_NOSYNC; + +--------------------------------------------------------------------------- +-- Combine both trigger sources, check length, find edges +--------------------------------------------------------------------------- +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 +-- BUG: reset missing! +THE_LATCH_PROC: process( CLOCK ) begin + if( rising_edge(CLOCK) ) then + if ( RESET = '1' ) then + timing_trg_found <= '0'; + elsif( timing_trg_rising = '1' ) then + timing_trg_found <= '1'; + end if; + end if; +end process THE_LATCH_PROC; + +LVL1_VALID_TIMING_TRG_OUT <= timing_trg_rising; -- BUG + +LVL1_VALID_NOTIMING_TRG_OUT <= timing_trg_comb; -- BUG + +--------------------------------------------------------------------------- +-- 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 + timeout_ctr <= timeout_ctr + 1; + end if; + end if; +end process THE_TIMEOUT_CTR_PROC; + +-- 5.12us maximum +next_timeout_found <= '1' when ( timeout_ctr = b"1_1111_1111" ) else '0'; + +THE_SYNC_PROC: process( CLOCK ) +begin + if( rising_edge(CLOCK) ) then + timeout_found <= next_timeout_found; + end if; +end process THE_SYNC_PROC; + +--------------------------------------------------------------------------- +-- State machine +--------------------------------------------------------------------------- +-- state registers +STATE_MEM: process( CLOCK ) +begin + if( rising_edge(CLOCK) ) then + if( RESET = '1' ) then + CURRENT_STATE <= IDLE; + toc_ce <= '0'; + toc_rst <= '1'; + else + CURRENT_STATE <= NEXT_STATE; + toc_ce <= next_toc_ce; + toc_rst <= next_toc_rst; + 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, timeout_found ) +begin + NEXT_STATE <= IDLE; -- avoid latches + next_toc_ce <= '0'; + next_toc_rst <= '0'; + 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; + 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; + 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 <= WAITREL; + next_toc_rst <= '1'; + elsif( timeout_found = '1' ) then + -- LVL1 did not arrive in time + NEXT_STATE <= TOCFND; + next_toc_rst <= '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; + when WAITREL => bsm_x <= x"3"; + if( LVL1_TRG_RELEASE_IN = '1' ) then + -- FEE logic releases trigger + NEXT_STATE <= DONE; + else + -- FEE logic still busy + NEXT_STATE <= WAITREL; + end if; + when BADTRG => bsm_x <= x"4"; + NEXT_STATE <= RELEASE; + when RELEASE => bsm_x <= x"5"; + NEXT_STATE <= DONE; + when DONE => bsm_x <= x"6"; + if( LVL1_TRG_RECEIVED_IN = '0' ) then + NEXT_STATE <= IDLE; + else + NEXT_STATE <= DONE; + end if; + when others => bsm_x <= x"f"; + NEXT_STATE <= IDLE; + end case; +end process STATE_TRANSFORM; + +--type STATES is (IDLE, BADTRG, TRGFND, LVL1FND, WAITREL, TOCFND, DONE); + + +--------------------------------------------------------------------------- +-- Internal trigger counter +--------------------------------------------------------------------------- +THE_INTERNAL_TRG_CTR_PROC: process( CLOCK ) +begin + if( rising_edge(CLOCK) ) then + if ( (RESET = '1') or (LVL1_INT_TRG_RESET_IN = '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; + end if; + end if; +end process THE_INTERNAL_TRG_CTR_PROC; + +lvl1_int_trg_ce <= '0'; + +LVL1_INT_TRG_NUMBER_OUT <= std_logic_vector(lvl1_int_trg_number); + + +--------------------------------------------------------------------------- +--------------------------------------------------------------------------- +--------------------------------------------------------------------------- +--------------------------------------------------------------------------- --This code is copied from endpoint_hades_full -- -------------------------------------------------