From bcf5154c1632182b264b059b31d4178dea440bbe Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Fri, 9 Feb 2007 17:12:41 +0000 Subject: [PATCH] first draft of trb_net_old_to_new. Added L12TrigBussInterface: Trigger Buss decoder. --- L12TrigBusInterface.vhd | 248 +++++++++++++++++++++++++++++++++++++ trb_net_old_to_new.vhd | 265 ++++++++++++++++++++++++++++++++++------ 2 files changed, 475 insertions(+), 38 deletions(-) create mode 100644 L12TrigBusInterface.vhd diff --git a/L12TrigBusInterface.vhd b/L12TrigBusInterface.vhd new file mode 100644 index 0000000..c127e11 --- /dev/null +++ b/L12TrigBusInterface.vhd @@ -0,0 +1,248 @@ +------------------------------------------------------------------------------- +-- 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; diff --git a/trb_net_old_to_new.vhd b/trb_net_old_to_new.vhd index 48930be..1cd80da 100644 --- a/trb_net_old_to_new.vhd +++ b/trb_net_old_to_new.vhd @@ -1,66 +1,89 @@ -- 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 @@ -70,5 +93,171 @@ architecture trb_net_old_to_new_arch of trb_net_old_to_new is -- 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; + -- 2.43.0