--******************************************************************************
--* @short Cancel-Out Unit in Logic FPGA
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv3.cern.ch>
--* @date $Date: 2005/01/31 15:17:29 $
--* @version $Revision: 1.8 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use WORK.GMTTypes.all;
use WORK.LFTypes.all;
use work.LFVMEAddrMap.all;
use work.LFVMERegDefaults.all;
use work.LFTiming.all;
use work.VMEMux.all;
--use STD.TEXTIO.all;
use IEEE.NUMERIC_STD.all;
-- TBD: use disable bits??
--
-- There are four cancel-out units, two in the barrel chip and two in the fwd chip.
--
-- the table below lists their indices and what muons they receive
-- idx unit where mu1 mu2 1st is mtch 2nd is mtch
----------------------------------------------------------------------------
-- 0 DT/CSC brl DT CSC DT CSC
-- 1 CSC/DT fwd CSC DT CSC DT
-- 2 bRPC/CSC brl bRPC CSC bRPC CSC
-- 3 fRPC/DT fwd fRPC DT fRPC DT
-- (mine) (other chip) (my matcher) (other chip matcher)
-- The first muons (mine) contain 6-bit eta and the eta has to be converted to
-- 4 bits in the ovletaconv (Overlap Eta Conversion) LUT. Empty muons are marked by empty bits (which
-- are generated from pt==0)
--
-- The second muons (other) contain only 4-bits as only 4-bits are sent from
-- the Input FPGAs. Empty muons are marked by an out-of-range eta value.
--
--
-- The cancel-decsison-logic in each case computes a cancel-out bit for each of
-- the first (my chip) and second (other chip) input muons.
--
--
-- idx unit Cancel_Mine CancelOther(DT/CSC)
-------------------------------------------------------------------------------
-- 0 DT/CSC DT would be CSC, not used
-- 1 CSC/DT CSC would be DT, not used
-- 2 bRPC/CSC bRPC(n/used) CSC (used often?)
-- 3 fRPC/DT FRPC DT(n/used)
--
-- The cancel-out units are configured via the cdl_control register
--
-- The lowest four bits control under which conditions the first (my chip) muon
-- will be cancelled. Bits 4 to 7 control under which conditions the second (other chip)
-- muons are cancelled.
--
-- A muon candidate can be cancelled if there is a match in the cancel-out unit
-- between the two types of candidates that are compared in this unit. The
-- decision on whether to cancel one of the candidates depends on wheter the
-- candidate and/or the candidate that it is matched to in the cancel-out unit
-- are matched with a complementary candidate in their own main matching unit.
--
-- e.g. in the first example below, a DT muon which is matched to a CSC muon in
-- the DT/CSC cancel-out unit will be cancelled only if the DT muon is not
-- matched to an RPC muon in then main matching unit and it the CSC muon is
-- matched to an RPC muon in its main matching unit.
--
-- Cancel Decision Logic Control Register for DT/CSC unit (brl chip)
-- =================================================================
--
-- possible matching results 1 1 0 0 DT is matched w bRPC
-- of main matching units (00..11) 1 0 1 0 CSC is matched w FRPC
--
-- DT/CSC brl | | | 0 0 1 0 | default programming
-- bit nr. | 7 6 5 4 | 3 2 1 0 |
-- cancel DT
--
--
-- Cancel Decision Logic Control Register for CSC/DT unit (fwd chip)
-- =================================================================
--
-- condition: 1 1 0 0 CSC is matched w fRPC
-- 1 0 1 0 DT is matched w bRPC
--
-- CSC/DT fwd | | | 0 0 1 1 | default programming
-- bit nr. | 7 6 5 4 | 3 2 1 0 |
-- cancel CSC
--
--
-- Cancel Decision Logic Control Register for bRPC/CSC unit (brl chip)
-- =================================================================
--
-- condition: 1 1 0 0 bRPC is matched w DT
-- 1 0 1 0 CSC is matched w fRPC
--
-- condition: 1 1 0 0 CSC is matched w fRPC
-- 1 0 1 0 bRPC is matched w DT
--
-- bRPC/CSC brl | | 0 0 0 1 | 0 0 0 0 | default programming
-- bit nr. | 7 6 5 4 | 3 2 1 0 |
-- cancel CSC cancel bRPC
-- in other chip
--
-- Cancel Decision Logic Control Register for fRPC/DT unit (fwd chip)
-- =================================================================
--
-- condition: 1 1 0 0 fRPC is matched w CSC
-- 1 0 1 0 DT is matched w bRPC
--
-- condition: 1 1 0 0 DT is matched w bRPC
-- 1 0 1 0 fRPC is matched w CSC
--
-- fRPC/DT fwd | | 0 0 0 0 | 0 0 0 1 | default programming
-- bit nr. | 7 6 5 4 | 3 2 1 0 |
-- cancel DT cancel fRPC
-- in other chip
--
--
entity LFCancelOutUnit is
generic (
cou_idx : integer := 0; -- 0: DT/CSC, 1: CSC/DT, 2: bRPC/CSC, 3: fRPC/DT
cou_lat_start : integer := 0); -- LATENCY at start
port (
phi_mine : in TPhi_vec (0 to 3);
eta_mine : in TEta_vec (0 to 3);
phi_other : in TPhi_vec (0 to 3);
eta_other : in TEta4_vec (0 to 3);
empty_mine : in std_logic_vector (0 to 3);
-- empty-other is coded in eta
disable_mine : in std_logic_vector (0 to 3); -- arrive 1/2 clock later
disable_other : in std_logic_vector (0 to 3); -- arrive 1/2 clock later
-- disable signal arrive 1/2 bx later and will be registered 1.5 bx after
-- the first input in the matcher (works ok)
mine_is_matched : in std_logic_vector (0 to 3);
other_is_matched : in std_logic_vector (0 to 3);
-- outputs
oPairMatrix : out TPairMatrix;
-- oMQMatrix : out TMQMatrix;
oCancelMine : out std_logic_vector(0 to 3);
oCancelOther_nr: out std_logic_vector(0 to 3);
-- VME port
vme_addr : in std_logic_vector;
vme_data : in std_logic_vector;
vme_en : in std_logic;
vme_wr : in std_logic;
vme_data_out : out std_logic_vector(15 downto 0);
vme_en_out : out std_logic;
-- Clock and control
clk : in std_logic;
sinit : in std_logic
);
end entity LFCancelOutUnit;
architecture behavioral of LFCancelOutUnit is
procedure calc_cancel_decision (
constant PairMatrix : in TPairMatrix;
constant FirstIsMatched : in std_logic_vector(0 to 3);
constant SecondIsMatched : in std_logic_vector(0 to 3);
constant mine_is_matched : in std_logic_vector(0 to 3);
constant other_is_matched: in std_logic_vector(0 to 3);
constant cdl_config : in std_logic_vector(15 downto 0);
signal cancel_mine : out std_logic_vector(0 to 3);
signal cancel_other : out std_logic_vector(0 to 3)) is
variable COU_match : std_logic;
variable match_is_matched : std_logic;
variable addr : std_logic_vector(1 downto 0);
-- variable lo : line;
begin -- process calc_cancel_decision
-- first check if "my muon" has to be cancelled
for i in 0 to 3 loop
-- is there a COU match for my muon number i?
COU_match := FirstIsMatched(i);
-- is the match matched in its own main matching unit?
match_is_matched := ( PairMatrix(i,0) and other_is_matched(0) ) or
( PairMatrix(i,1) and other_is_matched(1) ) or
( PairMatrix(i,2) and other_is_matched(2) ) or
( PairMatrix(i,3) and other_is_matched(3) );
addr := mine_is_matched(i) & match_is_matched;
cancel_mine(i) <= COU_match and cdl_config( TO_INTEGER(UNSIGNED(addr)) );
-- write (lo,string'("mine: idx_cou=")) ;
-- write (lo,cou_idx);
-- write (lo,string'(" i=")) ;
-- write (lo,i);
-- write (lo,string'(" cou_match = ")) ;
-- write (lo,TO_BIT(COU_match));
-- write (lo,string'(" mine_is_matched = ")) ;
-- write (lo,TO_BIT(mine_is_matched(i)));
-- write (lo,string'(" match_is_matched = ")) ;
-- write (lo,TO_BIT(match_is_matched));
-- write (lo,string'("cdl_config ")) ;
-- write (lo,TO_BITVECTOR(cdl_config));
-- write (lo,string'(" at addr ")) ;
-- write (lo,TO_INTEGER(UNSIGNED(addr))) ;
-- write (lo,string'(" is ")) ;
-- write (lo, TO_BIT( cdl_config( TO_INTEGER(UNSIGNED(addr) ))));
-- writeline(output, lo);
end loop; -- i
--
-- then check if "other muon" has to be cancelled
for i in 0 to 3 loop
-- is there a COU match for other muon nr i?
COU_match := SecondIsMatched(i);
-- is the match matched in its own main matching unit?
match_is_matched := ( PairMatrix(0,i) and mine_is_matched(0) ) or
( PairMatrix(1,i) and mine_is_matched(1) ) or
( PairMatrix(2,i) and mine_is_matched(2) ) or
( PairMatrix(3,i) and mine_is_matched(3) );
addr := other_is_matched(i) & match_is_matched;
cancel_other(i) <= COU_match and cdl_config( TO_INTEGER(UNSIGNED(addr)) + 4 );
-- write (lo,string'("other: idx_cou=")) ;
-- write (lo,cou_idx);
-- write (lo,string'(" i=")) ;
-- write (lo,i);
-- write (lo,string'(" cou_match = ")) ;
-- write (lo,TO_BIT(COU_match));
-- write (lo,string'(" other_is_matched = ")) ;
-- write (lo,TO_BIT(other_is_matched(i)));
-- write (lo,string'(" match_is_matched = ")) ;
-- write (lo,TO_BIT(match_is_matched));
-- write (lo,string'("cdl_config ")) ;
-- write (lo,TO_BITVECTOR(cdl_config));
-- write (lo,string'(" at addr ")) ;
-- write (lo,TO_INTEGER(UNSIGNED(addr))+4) ;
-- write (lo,string'(" is ")) ;
-- write (lo, TO_BIT( cdl_config( TO_INTEGER(UNSIGNED(addr) )+4)));
-- writeline(output, lo);
end loop; -- i
end; -- procedure calc_cancel_decision
-- signal MQMatrix : TMQMatrix;
signal vme_data_out_i : TVMEData_vec (0 to 6);
signal vme_en_out_i : TVMEEnable_vec (0 to 6);
signal nclk : std_logic;
signal PairMatrix_i : TPairMatrix;
signal FirstIsMatched_i : std_logic_vector (0 to 3);
signal SecondIsMatched_i : std_logic_vector (0 to 3);
signal eta4_mine : TEta4_vec (0 to 3);
signal eta4in6_mine : TEta_vec (0 to 3);
signal eta4in6_other : TEta_vec (0 to 3);
signal eta4in6_mine_d : TEta_vec (0 to 3);
signal eta4in6_other_d : TEta_vec (0 to 3);
signal low : std_logic_vector(0 to 3);
signal cdl_config : std_logic_vector(15 downto 0);
-- delayed inputs
signal phi_mine_d : TPhi_vec (0 to 3);
signal eta_mine_d : TEta_vec (0 to 3);
signal phi_other_d : TPhi_vec (0 to 3);
signal eta_other_d : TEtaCOU_vec (0 to 3);
signal mine_is_matched_d : std_logic_vector (0 to 3);
signal sCancelMine : std_logic_vector(0 to 3);
signal sCancelOther : std_logic_vector(0 to 3);
begin -- architecture behavioral
-----------------------------------------------------------------------------
-- convert my eta and store in vec of 6-bit eta
-----------------------------------------------------------------------------
n: for i in 0 to 3 generate
begin -- generate n
eta_conv: entity work.lfovletaconvlut
generic map (
instance_idx => cou_idx,
my_vme_base_address => LF_OvlEtaConvLUT_base(cou_idx / 2) + i * LF_OvlEtaConvLUT_size)
port map (
eta6 => eta_mine(i),
eta_ovl => eta4_mine(i),
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out_i(i),
vme_en_out => vme_en_out_i(i),
vme_clk => clk);
-- set to "out of range" if muon is empty
eta4in6_mine(i) <= ( "00" & eta4_mine(i) ) when empty_mine(i) = '0' else "000111";
eta4in6_other(i) <= ( "00" & eta_other(i) ) when phi_other(i) /= "11111111" else "000111";
end generate n;
-----------------------------------------------------------------------------
-- delay inputs
-----------------------------------------------------------------------------
delay_inputs: process (clk) is
begin -- process delay_inputs
if clk'event and clk = calc_lf_edge(cou_lat_start+LF_RLAT_COU_DELAY) then
phi_mine_d <= phi_mine;
eta4in6_mine_d <= eta4in6_mine;
phi_other_d <= phi_other;
eta4in6_other_d <= eta4in6_other;
end if;
end process delay_inputs;
-----------------------------------------------------------------------------
-- delay mine is matched
-----------------------------------------------------------------------------
delay_mineismatched: process (clk) is
begin
if clk'event and clk = calc_lf_edge(cou_lat_start+LF_RLAT_COU_MU) then
mine_is_matched_d <= mine_is_matched;
end if;
end process delay_mineismatched;
-----------------------------------------------------------------------------
-- Matching unit
-----------------------------------------------------------------------------
low <= "0000";
Matcher: entity work.LFMatchingUnit
generic map (
match_unit_idx => cou_idx+2,
match_unit_lat_start => cou_lat_start + LF_RLAT_COU_DELAY)
port map (
-- inputs
phi1 => phi_mine_d,
phi2 => phi_other_d,
eta1 => eta4in6_mine_d,
eta2 => eta4in6_other_d,
empty1 => low,
empty2 => low,
disable1 => disable_mine,
disable2 => disable_other,
-- outputs
oFirstIsMatched => FirstIsMatched_i,
oFirstIsMatched_nr => open,
oSecondIsMatched => SecondIsMatched_i,
oPairMatrix => PairMatrix_i,
-- oMQMatrix => MQMatrix,
-- VME
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out_i(4),
vme_en_out => vme_en_out_i(4),
clk => clk,
sinit => sinit);
-----------------------------------------------------------------------------
-- Cancel decision Logic
-----------------------------------------------------------------------------
cdl_control: entity work.VMEReg
generic map (
init_val => std_logic_vector(to_unsigned(LF_CDLConfig_defaults(cou_idx),16)),
my_vme_base_address => LF_CDLConfig_addr(cou_idx/2))
port map (
data => cdl_config,
reset => sinit,
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out_i(5),
vme_en_out => vme_en_out_i(5),
vme_clk => clk);
calc_cancel_decision (
PairMatrix => PairMatrix_i,
FirstIsMatched => FirstIsMatched_i,
SecondIsMatched => SecondIsMatched_i,
mine_is_matched => mine_is_matched_d,
other_is_matched=> other_is_matched,
cdl_config => cdl_config,
cancel_mine => sCancelMine,
cancel_other => sCancelOther);
cancel_decision: process (clk) is
begin
if (clk'event and clk = calc_lf_edge(cou_lat_start + LF_RLAT_COU_CDL )) then
oCancelMine <= sCancelMine;
oPairMatrix <= PairMatrix_i; -- for debug only
end if;
end process cancel_decision;
oCancelOther_nr <= sCancelOther; -- not registered
-- multiplex vme_data_output
mux_vme(vme_data_out_i, vme_en_out_i, vme_data_out, vme_en_out);
end architecture behavioral;