]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
*** empty log message ***
authorhadaq <hadaq>
Thu, 1 Jul 2010 12:50:22 +0000 (12:50 +0000)
committerhadaq <hadaq>
Thu, 1 Jul 2010 12:50:22 +0000 (12:50 +0000)
special/handler_lvl1.vhd

index bccdb7266e0d9370fc57d958a16ca35ae05fe252..5fe0c7e046980515507c35c2ddf5ab577dfdcd43 100644 (file)
@@ -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
 
 -- -------------------------------------------------