--- /dev/null
+-------------------------------------------------------------------------------
+-- Title : Detector Trigger Unit
+-- Project : HADES Second Level Trigger
+-------------------------------------------------------------------------------
+-- File : L12TrugBusInterface.vhd
+-- Author : Markus Petri, Daniel Schaefer
+-- Created : 2002/03/27
+-- Last modified : 2007/01/12 T. Perez
+-------------------------------------------------------------------------------
+-- Description : Generic Interace for the Trigger Bus
+--
+-------------------------------------------------------------------------------
+-- Modification history :
+-- 2002/03/27 : created
+-- 2002/05/31 : corrected TrigBus sequence, implemented BSY;
+-- 2007/01/12 : change in libraries to adapt to trbnet: numeric -> arith
+-- CLK_10 removed. Now DTU code is much faster than TRIGGERBUS.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+entity L12TrigBusInterface is
+ port (
+-- from Trigger bus
+ TSTR : in std_logic; -- trigger strobe
+ DSTR : in std_logic; -- data strobe
+ DIN : in std_logic_vector(3 downto 0);
+-- to Trigger bus
+ BSY : out std_logic;
+ ERR : out std_logic;
+-- general
+ RES : in std_logic;
+ CLK : in std_logic; -- should be 40 MHz!!
+-- CLK_10 : in std_logic; -- should be 10 MHz
+-- to state engine (and others)
+ DVAL : out std_logic; -- high for 2 clk cycles when TRIGTAG
+ -- and TRIGCODE have been received
+ TRIGTAG : out std_logic_vector(7 downto 0);
+ TRIGCODE : out std_logic_vector(3 downto 0);
+-- from state engine
+ TRIGTAG_MISMATCH : in std_logic; -- this is high whenever the received
+ -- TRIGTAG is not equal to the DTU's
+ -- internal counter and is not starting
+ -- with a 0 at begin
+ BUSY : in std_logic -- this should be controlled by the
+ -- state engine and is passed directly
+ -- to the trigger bus (where it is wired-
+ -- or with all the other busy's from
+ -- the DTU's, CTU)
+ );
+end L12TrigBusInterface;
+
+architecture ARCH_L12TrigInterface of L12TrigBusInterface is
+-------------------------------------------------------------------------------
+ type ShiftReg is array (0 to 2) of
+ std_logic_vector(3 downto 0);
+-------------------------------------------------------------------------------
+ signal NIBCNT : integer range 0 to 3; -- # of current nibble
+ signal TRIGBUFF : ShiftReg;
+ signal TSTR_REG, TSTR_REG_REG : std_logic;
+ signal DSTR_REG, DSTR_REG_REG : std_logic;
+-- signal DVAL_REG, DVAL_REG_LONG, DVAL_sync : std_logic;
+ signal DVAL_REG : std_logic;
+ signal DIN_REG : std_logic_vector(3 downto 0);
+-- signal counter_for_DVAL : integer range 0 to 3;
+
+ signal TRIGCODE_i : std_logic_vector(3 downto 0);
+ signal BUSY_FAST, BUSY_i : std_logic;
+-------------------------------------------------------------------------------
+
+begin
+
+ -- first we register all our inputs
+
+ reg_DIN : process (CLK, RES)
+ begin -- process reg_DIN
+ if RES = '1' then -- asynchronous reset (active high)
+ DIN_REG <= (others => '0');
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ DIN_REG <= (DIN);
+ end if;
+ end process reg_DIN;
+
+ reg_TSTR : process (CLK, RES)
+ begin -- process reg_NEW_TAG
+ if RES = '1' then -- asynchronous reset (active high)
+ TSTR_REG <= '0';
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ TSTR_REG <= TSTR;
+ end if;
+ end process reg_TSTR;
+
+ reg_reg_TSTR : process (CLK, RES)
+ begin -- process reg_NEW_TAG
+ if RES = '1' then -- asynchronous reset (active high)
+ TSTR_REG_REG <= '0';
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ TSTR_REG_REG <= TSTR_REG;
+ end if;
+ end process reg_reg_TSTR;
+
+ reg_DSTR : process (CLK, RES)
+ begin -- process reg_NEW_TAG
+ if RES = '1' then -- asynchronous reset (active high)
+ DSTR_REG <= '0';
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ DSTR_REG <= DSTR;
+ end if;
+ end process reg_DSTR;
+
+ reg_reg_DSTR : process (CLK, RES)
+ begin -- process reg_NEW_TAG
+ if RES = '1' then -- asynchronous reset (active high)
+ DSTR_REG_REG <= '0';
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ DSTR_REG_REG <= DSTR_REG;
+ end if;
+ end process reg_reg_DSTR;
+
+ CodeBuffering : process (CLK, RES)
+ begin -- process CodeBuffering
+ if RES = '1' then
+ TRIGCODE_i <= (others => '0');
+ elsif (CLK'event and CLK = '1') then
+ if (TSTR_REG = '0') and (TSTR_REG_REG = '1') then
+ -- falling edge of TSTR
+ TRIGCODE_i <= DIN_REG;
+ -- den registerten Wert
+ end if;
+ end if;
+ end process CodeBuffering;
+
+ TagBuffering : process (CLK, RES)
+ begin -- process TagBuffering
+ if RES = '1' then -- asynchronous reset (active high)
+ NIBCNT <= 0;
+ DVAL_REG <= '0';
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ DVAL_REG <= '0';
+ if NIBCNT >= 3 then
+ NIBCNT <= 0;
+ DVAL_REG <= '1';
+ elsif (DSTR_REG = '1') and (DSTR_REG_REG = '0') then
+ NIBCNT <= NIBCNT + 1;
+ end if;
+ end if;
+ end process TagBuffering;
+
+ Shift_Reg : process (CLK, RES)
+ begin -- process TagBuffering
+ if RES = '1' then -- asynchronous reset (active high)
+ TRIGBUFF(0) <= (others => '0');
+ TRIGBUFF(1) <= (others => '0');
+ TRIGBUFF(2) <= (others => '0');
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ if (DSTR_REG = '0') and (DSTR_REG_REG = '1') then
+ TRIGBUFF(2) <= TRIGBUFF(1);
+ TRIGBUFF(1) <= TRIGBUFF(0);
+ TRIGBUFF(0) <= DIN_REG; -- shift register
+ end if;
+ end if;
+ end process Shift_Reg;
+
+-- -- purpose: stretch DVAL_REG by four so it can be synchronised by CLK_10
+-- -- type : sequential
+-- -- inputs : CLK, RES, DVAL_REG
+-- -- outputs: DVAL_REG_LONG
+-- lenghten_DVAL_REG: process (CLK, RES)
+-- begin -- process lenghten_DVAL_REG
+-- if RES = '1' then -- asynchronous reset (active low)
+-- DVAL_REG_LONG <= '0';
+-- counter_for_DVAL <= 3;
+-- elsif CLK'event and CLK = '1' then -- rising clock edge
+-- DVAL_REG_LONG <= '0';
+-- if DVAL_REG='1' then
+-- counter_for_DVAL <= 0;
+-- DVAL_REG_LONG <= '1';
+-- end if;
+-- if counter_for_DVAL < 3 then
+-- counter_for_DVAL <= counter_for_DVAL + 1;
+-- DVAL_REG_LONG <= '1';
+-- end if;
+-- end if;
+-- end process lenghten_DVAL_REG;
+
+-- synchronise_DVAL_REG_LONG_to_CLK_10_1: process (CLK_10, RES)
+-- begin -- process synchronise_DVAL_REG_LONG to CLK_10
+-- if RES = '1' then -- asynchronous reset (active low)
+-- DVAL_sync <= '0';
+-- elsif CLK_10'event and CLK_10 = '1' then -- rising clock edge
+-- DVAL_sync <= DVAL_REG_LONG;
+-- end if;
+-- end process synchronise_DVAL_REG_LONG_to_CLK_10_1;
+
+-- synchronise_DVAL_REG_LONG_to_CLK_10_2: process (CLK_10, RES)
+-- begin -- process synchronise_DVAL_REG_LONG to CLK_10
+-- if RES = '1' then -- asynchronous reset (active low)
+-- DVAL <= '0';
+-- elsif CLK_10'event and CLK_10 = '1' then -- rising clock edge
+-- DVAL <= DVAL_sync;
+-- end if;
+-- end process synchronise_DVAL_REG_LONG_to_CLK_10_2;
+ -- purpose: register DVAL
+ -- type : sequential
+ -- inputs : CLK, RES, DVAL
+ -- outputs: DVAL_sync
+ DVAL_OUT : process (CLK, RES)
+ begin -- process DVAL_reg
+ if RES = '0' then -- asynchronous reset (active low)
+ DVAL <= '0';
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ DVAL <= DVAL_reg;
+ end if;
+ end process DVAL_OUT;
+
+ SynchBSY : process(RES, CLK)
+ begin
+ if (RES = '1') then
+ BSY <= '0';
+ elsif (CLK'event and CLK = '1') then
+ BSY <= BUSY_i;
+ end if;
+ end process SynchBSY;
+-------------------------------------------------------------------------------
+-- Combinatorial Signals
+-------------------------------------------------------------------------------
+ TRIGTAG <= TRIGBUFF(1) & TRIGBUFF(2);
+ TRIGCODE <= TRIGCODE_i;
+ ERR <= TRIGTAG_MISMATCH;
+-- DSTR_INV <= NOT(DSTR);
+ -- purpose: Set a fast busy on TSTR
+ -- type : sequential
+ -- inputs : CLK, RES, BUSY
+ -- outputs: BUSY_FASt
+ FastBusy : process (CLK, RES, BUSY)
+ begin -- process FastBusy
+ if RES = '1' or BUSY = '1'then -- asynchronous reset (active high)
+ BUSY_FAST <= '0';
+ elsif CLK'event and CLK = '1' then -- rising clock edge
+ if TSTR_REG = '1' then
+ BUSY_FAST <= '1';
+ end if;
+ end if;
+ end process FastBusy;
+ BUSY_i <= BUSY or BUSY_FAST;
+end ARCH_L12TrigInterface;
-- this is an apl, connecting the old trigger bus to the new system
+-------------------------------------------------------------------------------
+-- Title : trb_net_old_to_new
+-- Project : HADES trigger new net
+-------------------------------------------------------------------------------
+-- File : trb_net_old_to_new.vhd
+-- Author : Tiago Perez (tiago.perez@uni-giessen.de)
+-- Created : 2007/01/12
+-- Last modified : 2007/01/12 T. Perez
+-------------------------------------------------------------------------------
+-- Description : Interace between "old" and "new" trigger nets
+--
+-------------------------------------------------------------------------------
+-- Modification history :
+-- 2007/01/12 : created
+-- L12TrigBusInterface is driven only with the main clock. This
+-- used to be 40MHz in "OLD" DTU but now is around 10 times faster.
+-- I am not sure how "sharp" are the edges of T and TS in the
+-- trigger bus, but now, samplig at ca. 400MHz we may sample T and
+-- TS sereval times while falling and still not set. We should
+-- chek the quality and "sharpness" of the Triggerbus with a scope
+-- and eventually downscale the main clock to sample slower.
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use IEEE.STD_LOGIC_UNSIGNED.all;
+use ieee.numeric_std.all;
-LIBRARY IEEE;
-USE IEEE.STD_LOGIC_1164.ALL;
-USE IEEE.STD_LOGIC_ARITH.ALL;
-USE IEEE.STD_LOGIC_UNSIGNED.ALL;
-
-use work.trb_net_std.all;
+--use work.trb_net_std.all;
entity trb_net_old_to_new is
- generic (TRIGGER_LEVEL : integer := 1); -- either 1 or 2
-
- port(
+ generic (TRIGGER_LEVEL : integer := 1); -- either 1 or 2
+
+ port(
-- Misc
- CLK : in std_logic;
- RESET : in std_logic;
+ CLK : in std_logic;
+ RESET : in std_logic;
CLK_EN : in std_logic;
-- APL Transmitter port
- APL_DATA_OUT: out STD_LOGIC_VECTOR (47 downto 0); -- Data word "application to network"
- APL_WRITE_OUT: out STD_LOGIC; -- Data word is valid and should be transmitted
- APL_FIFO_FULL_IN: in STD_LOGIC; -- Stop transfer, the fifo is full
- APL_SHORT_TRANSFER_OUT: out STD_LOGIC; --
- APL_DTYPE_OUT: out STD_LOGIC_VECTOR (3 downto 0); -- see NewTriggerBusNetworkDescr
- APL_ERROR_PATTERN_OUT: out STD_LOGIC_VECTOR (31 downto 0); -- see NewTriggerBusNetworkDescr
- APL_SEND_OUT: out STD_LOGIC; -- Release sending of the data
- APL_TARGET_ADDRESS_OUT: out STD_LOGIC_VECTOR (15 downto 0); -- Address of
- -- the target (only for active APIs)
+ APL_DATA_OUT : out std_logic_vector (47 downto 0); -- Data word "application to network"
+ APL_WRITE_OUT : out std_logic; -- Data word is valid and should be transmitted
+ APL_FIFO_FULL_IN : in std_logic; -- Stop transfer, the fifo is full
+ APL_SHORT_TRANSFER_OUT : out std_logic; --
+ APL_DTYPE_OUT : out std_logic_vector (3 downto 0); -- see NewTriggerBusNetworkDescr
+ APL_ERROR_PATTERN_OUT : out std_logic_vector (31 downto 0); -- see NewTriggerBusNetworkDescr
+ APL_SEND_OUT : out std_logic; -- Release sending of the data
+ APL_TARGET_ADDRESS_OUT : out std_logic_vector (15 downto 0); -- Address of
+ -- the target (only for active APIs)
-- Receiver port
- APL_DATA_IN: in STD_LOGIC_VECTOR (47 downto 0); -- Data word "network to application"
- APL_TYP_IN: in STD_LOGIC_VECTOR (2 downto 0); -- Which kind of data word: DAT, HDR or TRM
- APL_DATAREADY_IN: in STD_LOGIC; -- Data word is valid and might be read out
- APL_READ_OUT: out STD_LOGIC; -- Read data word
-
+ APL_DATA_IN : in std_logic_vector (47 downto 0); -- Data word "network to application"
+ APL_TYP_IN : in std_logic_vector (2 downto 0); -- Which kind of data word: DAT, HDR or TRM
+ APL_DATAREADY_IN : in std_logic; -- Data word is valid and might be read out
+ APL_READ_OUT : out std_logic; -- Read data word
+
-- APL Control port
- APL_RUN_IN: in STD_LOGIC; -- Data transfer is running
- APL_SEQNR_IN: in STD_LOGIC_VECTOR (7 downto 0),
+ APL_RUN_IN : in std_logic; -- Data transfer is running
+ APL_SEQNR_IN : in std_logic_vector (7 downto 0);
-- the OLD trigger bus
- OLD_T: in STD_LOGIC; -- trigger signal
- -- used to strobe the trigger code
- OLD_TS: in STD_LOGIC; -- trigger strobe
+ OLD_T : in std_logic; -- trigger signal
+ -- used to strobe the trigger code
+ OLD_TS : in std_logic; -- trigger strobe
-- used to strobe the trigger tag and further
-- trigger data nibbles (e.g. trigger priority)
- OLD_TD: in STD_LOGIC_VECTOR (3 downto 0); -- trigger data lines
+ OLD_TD : in std_logic_vector (3 downto 0); -- trigger data lines
-- transmit the trigger data nibbles
- OLD_TB: out STD_LOGIC; -- trigger busy
+ OLD_TB : out std_logic; -- trigger busy
-- wired-or signal, that indicates busy state of one or more DTUs
- OLD_TE: out STD_LOGIC; -- trigger error
+ OLD_TE : out std_logic -- trigger error
-- wired-or signal, that indicates error state of one or more DTUs
---Ts0..1 trigger spare lines
+--Ts0..1 trigger spare lines
--free for future purposes
--not connected because useless
);
-END trb_net_old_to_new;
+end trb_net_old_to_new;
-architecture trb_net_old_to_new_arch of trb_net_old_to_new is
+--architecture trb_net_old_to_new_arch of trb_net_old_to_new is
+architecture behavioral of trb_net_old_to_new is
-- reconstruct the LVL1 or LVL2 trigger
-- for LVL1: Ignore the BEGRUN and ENDRUN triggers
-- if a tigger tag mismatch occures, raise the error line
-- feel free to add debug registers
-
-end trb_net_old_to_new_arch;
+
+ -- COMPONENTS
+ -- OLD TRIGGER INTERFACE
+ component L12TrigBusInterface
+ port (
+ TSTR : in std_logic;
+ DSTR : in std_logic;
+ DIN : in std_logic_vector(3 downto 0);
+ BSY : out std_logic;
+ ERR : out std_logic;
+ RES : in std_logic;
+ CLK : in std_logic;
+-- CLK_10 : in std_logic;
+ DVAL : out std_logic;
+ TRIGTAG : out std_logic_vector(7 downto 0);
+ TRIGCODE : out std_logic_vector(3 downto 0);
+ TRIGTAG_MISMATCH : in std_logic;
+ BUSY : in std_logic);
+ end component;
+
+ -- SIGNALS
+ signal TRIGTAG_i, TRIGTAG_ii : std_logic_vector(7 downto 0);
+-- signal TRIGCODE_i : std_logic_vector(3 downto 0);
+ signal DVAL_i, TRIGTAG_MISMATCH_i : std_logic;
+-- signal OLD_CLK, OLD_CLK_10 : std_logic;
+
+ type State_Type is (idle, compare, send, error_1);
+ signal present_state, next_state : State_Type;
+ signal do_send_cnt : unsigned(3 downto 0);
+ signal RESET_STATE : std_logic;
+
+begin
+ APL_DATA_OUT(7 downto 0) <= TRIGTAG_ii;
+ -----------------------------------------------------------------------------
+ -- FIX NON USED OUTPUTS
+ -----------------------------------------------------------------------------
+ APL_DATA_OUT(47 downto 8) <= (others => '0');
+ APL_WRITE_OUT <= '0';
+
+ APL_SHORT_TRANSFER_OUT <= '1'; -- short transfer TRUE
+ APL_ERROR_PATTERN_OUT <= (others => '0');
+ APL_TARGET_ADDRESS_OUT <= (others => '0');
+
+ -----------------------------------------------------------------------------
+ -- COMPONENTS
+ -----------------------------------------------------------------------------
+ BusInterfaceOld : L12TrigBusInterface
+ port map (
+ TSTR => OLD_T,
+ DSTR => OLD_TS,
+ DIN => OLD_TD,
+ BSY => OLD_TB,
+ ERR => OLD_TE,
+ RES => RESET,
+ CLK => CLK,
+ DVAL => DVAL_i,
+ TRIGTAG => TRIGTAG_i,
+ TRIGCODE => APL_DTYPE_OUT,
+ TRIGTAG_MISMATCH => TRIGTAG_MISMATCH_i,
+ BUSY => APL_RUN_IN);
+
+ -----------------------------------------------------------------------------
+ -- DIFF LVL1/LVL2
+ -----------------------------------------------------------------------------
+ -- filter BEGRUN out
+ -- CHANGE: TRIGTAG=TRIGTAG-1
+ GEN_L1 : if TRIGGER_LEVEL = 1 generate
+ process (CLK, RESET, CLK_EN, TRIGTAG_i)
+ begin -- process S
+ if RESET = '1' then
+ TRIGTAG_ii <= (others => '0');
+ elsif CLK'event and CLK = '1' and CLK_EN = '1' then
+ TRIGTAG_ii <= TRIGTAG_i - 1;
+ end if;
+ end process;
+ end generate GEN_L1;
+
+ -- Register TRIGTAG
+ GEN_L1 : if TRIGGER_LEVEL = 2 generate
+ process (CLK, RESET, CLK_EN, TRIGTAG_i)
+ begin -- process S
+ if RESET = '1' then
+ TRIGTAG_ii <= (others => '0');
+ elsif CLK'event and CLK = '1' and CLK_EN = '1' then
+ TRIGTAG_ii <= TRIGTAG_i;
+ end if;
+ end process;
+ end generate GEN_L1;
+
+ -----------------------------------------------------------------------------
+ -- FSM
+ -----------------------------------------------------------------------------
+ -- purpose: Register the STATE of the FSM
+ -- type : Sequential
+ -- inputs : CLK, RESET, next_state
+ -- output : next_state
+ state_clocked : process (CLK, RESET, CLK_EN)
+ begin -- process state_clocked
+ if RESET = '1' then -- asynchronous reset (active high)
+ present_state <= idle;
+ elsif CLK'event and CLK = '1' and CLK_EN = '1' then -- rising clock edge
+ present_state <= next_state;
+ end if;
+ end process state_clocked;
+
+ -- purpose: Finite State Machine
+ -- type : combinational
+ -- inputs : present_state
+ -- outputs:
+ FSM : process (present_state, DVAL_i, TRIGTAG_ii, APL_SEQNR_IN, APL_RUN_IN)
+ begin -- process FSM
+ next_state <= present_state;
+ case present_state is
+ when idle =>
+ if DVAL_i = '1' then
+ next_state <= compare;
+ end if;
+ when compare =>
+ if TRIGTAG_ii = APL_SEQNR_IN then
+ next_state <= send;
+ else
+ next_state <= error_1;
+ end if;
+ when send =>
+ if APL_RUN_IN = '1' then
+ next_state <= idle;
+ end if;
+ when others => null;
+ end case;
+ end process FSM;
+
+ -- purpose: decode the output signals of FSM
+ -- type : combinational
+ -- inputs : present_state
+ -- outputs:
+ decode_output : process (present_state, CLK, RESET_STATE)
+ begin -- process decode_output
+ TRIGTAG_MISMATCH_i <= '0';
+ APL_SEND_OUT <= '0';
+ APL_READ_OUT <= '0';
+ RESET_STATE <= '0';
+ case present_state is
+ when idle =>
+ TRIGTAG_MISMATCH_i <= '1';
+ RESET_STATE <= '1';
+ when compare =>
+ APL_READ_OUT <= '1';
+ when send =>
+ if RESET_STATE='1' then
+ do_send_cnt <= "0000";
+ elsif CLK'event and CLK='1' then
+ do_send_cnt <= do_send_cnt+1;
+ end if;
+
+ if do_send_cnt = X"01" then
+ APL_SEND_OUT <= '1';
+ elsif do_send_cnt="0011" or do_send_cnt="0100" then
+ APL_READ_OUT <= '1';
+ end if;
+
+ when error_1 =>
+ TRIGTAG_MISMATCH_i <= '1';
+ when others => null;
+ end case;
+ end process decode_output;
+
+end behavioral;
+