--******************************************************************************
--* @short Matching Unit in Logic FPGA
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv3.cern.ch>
--* @date $Date: 2005/01/31 15:17:29 $
--* @version $Revision: 1.7 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use WORK.GMTTypes.all;
use WORK.LFTypes.all;
use work.LFVMEAddrMap.all;
use work.LFTiming.all;
use work.VMEMux.all;
--use STD.TEXTIO.all;
use IEEE.NUMERIC_STD.all;
-- the two main matching units receive:
-- 6-bit eta, empty bits (which are generated from pt==0), disable bits (for
-- hot regions)
-- the four cancel-out matching units receive:
-- 4-bit eta including empty code (which are generated from pt==0), disable bits (for
-- hot regions)
--
-- could just use only the lower bits of eta1, eta2
-- => attach '0' to the empty bits
entity LFMatchingUnit is
generic (
match_unit_idx : integer := 0; -- 0: DT/RPC, 1: CSC/RPC, 2: DT/CSC, 3: CSC/DT, 4: bRPC/CSC, 5: fRPC/DT
match_unit_lat_start : integer := 0); -- LATENCY at start
port (
phi1, phi2 : in TPhi_vec (0 to 3);
eta1, eta2 : in TEta_vec (0 to 3);
empty1 : in std_logic_vector (0 to 3);
empty2 : in std_logic_vector (0 to 3);
disable1 : in std_logic_vector (0 to 3); -- arrive 1/2 clock later (main
-- matching) or on time (COU)
disable2 : in std_logic_vector (0 to 3); -- arrive 1/2 clock later (main
-- matching) or on time (COU)
-- outputs
oFirstIsMatched : out std_logic_vector (0 to 3);
oFirstIsMatched_nr : out std_logic_vector (0 to 3); -- not registered
oSecondIsMatched : out std_logic_vector (0 to 3);
oPairMatrix : out TPairMatrix;
-- oMQMatrix : out TMQMatrix;
-- 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 LFMatchingUnit;
architecture behavioral of LFMatchingUnit is
type TDeltaEtaMatrix is array (integer range 0 to 3, integer range 0 to 3) of std_logic_vector(3 downto 0);
type TDeltaPhiMatrix is array (integer range 0 to 3, integer range 0 to 3) of std_logic_vector(2 downto 0);
signal MQMatrix : TMQMatrix;
signal MQMatrix_reg : TMQMatrix;
signal MQMatrix_notempty : TMQMatrix;
signal DeltaEtaMatrix : TDeltaEtaMatrix;
signal DeltaEtaMatrix_temp : TDeltaEtaMatrix;
signal DeltaPhiMatrix : TDeltaPhiMatrix;
signal vme_data_out_i : TVMEData_vec (0 to 31);
signal vme_en_out_i : TVMEEnable_vec (0 to 31);
signal PairMatrix_i : TPairMatrix;
signal empty1_d : std_logic_vector (0 to 3);
signal empty2_d : std_logic_vector (0 to 3);
signal disable1_d : std_logic_vector (0 to 3);
signal disable2_d : std_logic_vector (0 to 3);
begin -- architecture behavioral
-- register empty & disable
register_empty: process (clk) is
begin -- process register_empty
if clk'event and clk = calc_lf_edge(match_unit_lat_start + LF_RLAT_MU_DELTAETA) then
empty1_d <= empty1;
empty2_d <= empty2;
disable1_d <= disable1;
disable2_d <= disable2;
end if;
end process register_empty;
mq_i: for i in 0 to 3 generate
begin -- generate mq_i
mq_j: for j in 0 to 3 generate
begin -- generate mq_j
-------------------------------------------------------------------------
-- in main matching units calculate delta eta from 6-bit eta values
-------------------------------------------------------------------------
main: if (match_unit_idx<2) generate
begin -- generate main_or_cou
-- delta-eta LUT
delta_eta_lut: entity work.lfdeltaetalut
generic map (
instance_idx => match_unit_idx ,
my_vme_base_address => LF_DeltaEtaLUT_base(0) + LF_DeltaEtaLUT_size * (i*4+j),
edge => calc_lf_edge(match_unit_lat_start + LF_RLAT_MU_DELTAETA - 1))
port map (
eta_dtcsc => eta1(i),
eta_rpc => eta2(j),
delta_eta => DeltaEtaMatrix(i,j),
clk => clk,
sinit => sinit,
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out_i(i*4+j),
vme_en_out => vme_en_out_i(i*4+j),
vme_clk => clk);
end generate main;
-------------------------------------------------------------------------
-- in cancel-out matching units calculate delta_eta from 4-bit eta values
-- (use lower 4 bits)
-------------------------------------------------------------------------
cou: if (match_unit_idx>=2) generate
begin -- generate main_or_cou
-- delta-eta LUT (distr ram)
delta_eta_lut: entity work.lfcoudeltaetalut
generic map (
instance_idx => match_unit_idx - 2,
my_vme_base_address => LF_COUDeltaEtaLUT_base( (match_unit_idx-2) / 2) + LF_COUDeltaEtaLUT_size * (i*4+j) )
port map (
eta1 => eta1(i)(3 downto 0),
eta2 => eta2(j)(3 downto 0),
delta_eta => DeltaEtaMatrix_temp(i,j),
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out_i(i*4+j),
vme_en_out => vme_en_out_i(i*4+j),
vme_clk => clk);
DeltaEtaMatrix(i,j) <= DeltaEtaMatrix_temp(i,j);
end generate cou;
-- delta-phi subtracter
delta_phi_sub: entity work.LFDeltaPhiSub
port map (
phi1 => phi1(i),
phi2 => phi2(j),
dphi => DeltaPhiMatrix(i,j)
);
-- Match-Quality LUTs
mq_lut: entity work.lfmatchquallut
generic map (
instance_idx => match_unit_idx,
my_vme_base_address => LF_MatchQualLUT_base(match_unit_idx / 2) + LF_MatchQualLUT_size * (i*4+j) )
port map (
delta_eta => DeltaEtaMatrix(i,j),
delta_phi => DeltaPhiMatrix(i,j),
mq => MQMatrix(i,j),
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out_i(16+i*4+j),
vme_en_out => vme_en_out_i(16+i*4+j),
vme_clk => clk);
register_mq: process (clk) is
begin
if clk'event and clk = calc_lf_edge(match_unit_lat_start + LF_RLAT_MU_DELTAETA) then
MQMatrix_reg(i,j) <= MQMatrix(i,j);
end if;
end process register_mq;
MQMatrix_notempty(i,j) <= MQMatrix_reg(i,j) when ((empty1_d(i) = '0')
and (empty2_d(j)='0')
and (disable1_d(i)='0')
and (disable2_d(j)='0')) else "000000";
end generate mq_j;
end generate mq_i;
-- forward match quality to output
-- xx : process (clk) is
-- variable LO: line;
-- begin -- process xx
-- if clk'event and clk = calc_lf_edge(match_unit_lat_start + LF_DELAY_MU) then
-- oMQMatrix <= MQMatrix_notempty;
-- write(lo, string'("[[[[phi1, phi2, eta1, eta2]]]]"));
-- writeline(output, lo);
-- for r in 0 to 3 loop
-- write (LO,string'(" "));
-- write (LO, TO_INTEGER(UNSIGNED(phi1(r))));
-- write (LO,string'(" "));
-- write (LO, TO_INTEGER(UNSIGNED(phi2(r))));
-- write (LO,string'(" "));
-- write (LO, TO_INTEGER(UNSIGNED(eta1(r))));
-- write (LO,string'(" "));
-- write (LO, TO_INTEGER(UNSIGNED(eta2(r))));
-- writeline (OUTPUT, LO);
-- end loop; -- r
-- write(lo, string'("matchunit idx = "));
-- write(lo, match_unit_idx);
-- writeline(output, lo);
-- write(lo, string'("[[[[delta eta Matrix]]]]"));
-- writeline(output, lo);
-- for r in 0 to 3 loop
-- for c in 0 to 3 loop
-- -- write (LO,string'(" "));
-- -- write (LO,r);
-- -- write (LO,string'(" "));
-- -- write (LO,c);
-- write (LO,string'(" "));
-- write (LO, TO_INTEGER(SIGNED(DeltaEtaMatrix(r,c))));
-- end loop; -- c
-- writeline (OUTPUT, LO);
-- end loop; -- r
-- writeline (OUTPUT, LO);
-- write(lo, string'("[[[[delta phi Matrix]]]]"));
-- writeline(output, lo);
-- for r in 0 to 3 loop
-- for c in 0 to 3 loop
-- -- write (LO,string'(" "));
-- -- write (LO,r);
-- -- write (LO,string'(" "));
-- -- write (LO,c);
-- write (LO,string'(" "));
-- write (LO, TO_INTEGER(SIGNED(DeltaPhiMatrix(r,c))));
-- end loop; -- c
-- writeline (OUTPUT, LO);
-- end loop; -- r
-- writeline (OUTPUT, LO);
-- write(lo, string'("[[[[MQ Matrix]]]]"));
-- writeline(output, lo);
-- for r in 0 to 3 loop
-- for c in 0 to 3 loop
-- -- write (LO,string'(" "));
-- -- write (LO,r);
-- -- write (LO,string'(" "));
-- -- write (LO,c);
-- write (LO,string'(" "));
-- write (LO, TO_INTEGER(UNSIGNED(MQMatrix_notempty(r,c))));
-- end loop; -- c
-- writeline (OUTPUT, LO);
-- end loop; -- r
-- writeline (OUTPUT, LO);
-- write(lo, string'("[[[[MQ Matrix before empty check]]]]"));
-- writeline(output, lo);
-- for r in 0 to 3 loop
-- for c in 0 to 3 loop
-- -- write (LO,string'(" "));
-- -- write (LO,r);
-- -- write (LO,string'(" "));
-- -- write (LO,c);
-- write (LO,string'(" "));
-- write (LO, TO_INTEGER(UNSIGNED(MQMatrix(r,c))));
-- end loop; -- c
-- writeline (OUTPUT, LO);
-- end loop; -- r
-- writeline (OUTPUT, LO);
-- write(lo, string'("[[[[Pair Matrix (previous)]]]]"));
-- writeline(output, lo);
-- for r in 0 to 3 loop
-- for c in 0 to 3 loop
-- -- write (LO,string'(" "));
-- -- write (LO,r);
-- -- write (LO,string'(" "));
-- -- write (LO,c);
-- write (LO,string'(" "));
-- write (LO, TO_BIT((PairMatrix_i(r,c))));
-- end loop; -- c
-- writeline (OUTPUT, LO);
-- end loop; -- r
-- writeline (OUTPUT, LO);
-- end if;
-- end process xx;
-- MAX-DIS-PAIR logic
pairlogic: entity work.LFPairLogic
port map (
iMQMatrix => MQMatrix_notempty,
oPairMatrix => PairMatrix_i,
clk => clk);
reg_pm : process (clk) is
begin
if clk'event and clk = calc_lf_edge(match_unit_lat_start+LF_RLAT_MU_MQPAIR) then
oPairMatrix <= PairMatrix_i;
for i in 0 to 3 loop
oFirstIsMatched(i) <= PairMatrix_i(i,0) or PairMatrix_i(i,1) or PairMatrix_i(i,2) or PairMatrix_i(i,3);
oSecondIsMatched(i) <= PairMatrix_i(0,i) or PairMatrix_i(1,i) or PairMatrix_i(2,i) or PairMatrix_i(3,i);
end loop; -- i
end if;
end process reg_pm;
-- non registered first is matched for other chip
matched_nr: for i in 0 to 3 generate
begin -- generate matched_nr
oFirstIsMatched_nr(i) <= PairMatrix_i(i,0) or PairMatrix_i(i,1) or PairMatrix_i(i,2) or PairMatrix_i(i,3);
end generate matched_nr;
-- multiplex vme_data_output
mux_vme(vme_data_out_i, vme_en_out_i, vme_data_out, vme_en_out);
end architecture behavioral;