-- **************************************************
--
--   Package: GMTTypes
--
--   Description: Types for signals on board and chip I/Os
--
--
--   $Date: 2004/08/06 12:42:11 $
--   $Revision: 1.9 $
--
--   Author :
--   H. Sakulin                CERN EP 
--
-- **************************************************

library IEEE;
use IEEE.Std_logic_1164.all;
use STD.TEXTIO.all;


package GMTTypes is

subtype TInMuon is std_logic_vector(31 downto 0);
type TInMuons_vec is array (integer range <>) of TInMuon;
subtype TFourInMuons_flat is std_logic_vector(127 downto 0);

function InMuons_vec_from_flat (signal flat : TFourInMuons_flat) return TInMuons_vec;
function InMuons_vec_to_flat (signal mus : TInMuons_vec) return TFourInMuons_flat;

-----------------------------------------------------------------------------
-- Synchronized muon that goes from Input Chip to MipIsoAU chip or Logic chip
-------------------------------------------------------------------------------
type TSyncedMu is record
  ch_valid : Std_logic;                    -- charge valid bit
  charge   : Std_logic;                    -- charge bit (1= plus)
  finehalo : Std_logic;                    -- eta is fine bit (DT) or halo bit
                                           -- (CSC)
  eta      : Std_logic_vector(5 downto 0); -- 6 bit eta
  qual     : Std_logic_vector(2 downto 0); -- 3 bit quality
  pt       : Std_logic_vector(4 downto 0); -- 5 bit pt
  phi      : Std_logic_vector(7 downto 0); -- 8 bit phi
end record;

-- synopsys translate_off
procedure Write (
  variable L     : inout Line;          -- Line
  variable value : in    TSyncedMu);    -- muon
-- synopsys translate_on

type TSyncedMu_vector is array (integer range <>) of TSyncedMu;
subtype TSyncedMu_vector4 is TSyncedMu_vector(0 to 3);

-- flat version of synced muons for chip I/O
subtype TSyncedMu_flat is std_logic_vector(24 downto 0);
subtype TFourSyncedMu_flat is std_logic_vector(100 downto 0); -- includes one spare bit

function SyncedMu_from_flat (constant flat : TSyncedMu_flat) return TSyncedMu;
function SyncedMu_vec_from_flat (signal flat : TFourSyncedMu_flat) return TSyncedMu_vector4;
function SyncedMu_to_flat (constant mu : TSyncedMu) return TSyncedMu_flat;
function SyncedMu_vec_to_flat (signal mus : TSyncedMu_vector4) return TFourSyncedMu_flat;

-------------------------------------------------------------------------------
-- GMT muon at the output of the GMT and between Logic FPGA and Sorter FPGA
-------------------------------------------------------------------------------
type TGMTMu is record
  sysign   : Std_logic_vector(1 downto 0); -- charge bit (1= plus)
  mip      : Std_logic;                        
  isol     : Std_logic;                        
  eta      : Std_logic_vector(5 downto 0); -- 6 bit eta
  qual     : Std_logic_vector(2 downto 0); -- 3 bit quality
  pt       : Std_logic_vector(4 downto 0); -- 5 bit pt
  phi      : Std_logic_vector(7 downto 0); -- 8 bit phi
end record;


type TGMTMu_vector is array (integer range <>) of TGMTMu;
subtype TGMTMu_vector4 is TGMTMu_vector(0 to 3);

-- flat version of GMT muons for chip I/O
subtype TGMTMu_flat is std_logic_vector(25 downto 0);
subtype TFourGMTMu_flat is std_logic_vector(104 downto 0);  -- includes spare bit
function GMTMu_from_flat (constant flat : TGMTMu_flat) return TGMTMu;
function GMTMu_vec_from_flat (signal flat : TFourGMTMu_flat) return TGMTMu_vector4;
function GMTMu_to_flat (signal mu : TGMTMu) return TGMTMu_flat;
function GMTMu_vec_to_flat (signal mus : TGMTMu_vector4) return TFourGMTMu_flat;

-- output quality codes
constant QCODE_MATCHED : integer := 7;
constant QCODE_DTCSC   : integer := 6;
constant QCODE_RPC     : integer := 5;
constant QCODE_VLQ3    : integer := 4;
constant QCODE_VLQ2    : integer := 3;
constant QCODE_VLQ1    : integer := 2;
constant QCODE_HALO    : integer := 1;

-- phi and eta for cancel-out
type TPhiCOU_vec is array (integer range <>) of std_logic_vector(7 downto 0);
type TEtaCOU_vec is array (integer range <>) of std_logic_vector(5 downto 0);
type TEta4_vec is array (integer range <>) of std_logic_vector(3 downto 0);

type TPhi_vec is array (integer range <>) of std_logic_vector(7 downto 0);
 

-- synopsys translate_off
procedure Write (
  variable L     : inout Line;          -- Line
  constant value : in    TGMTMu);    -- muon
-- synopsys translate_on

-- MIP and ISO bits are stored in rings of 18 segments in phi
subtype TCaloRing is Std_logic_vector(0 to 17); -- 18 slices in phi
type TCaloRing_vector is array (integer range <>) of TCaloRing;


-- Sort Rank
subtype TSortRank is Std_logic_vector(7 downto 0);
type TSortRank_vector is array (integer range <>) of TSortRank;


-- Index bits (RPC index in upper bits, DT/CSC index in lower bits)
subtype TIndexBits is std_logic_vector(3 downto 0);
type TIndexBits_vector is array (integer range <>) of TIndexBits;

-- Very low quality bits
subtype TVLQbits is Std_logic_vector(1 downto 0);
type TVLQbits_vector is array (integer range <>) of TVLQbits;

-- Select bits
subtype TSelBits_1_of_8 is std_logic_vector(0 to 7);
type TSelBits_1_of_8_vec is array (integer range <>) of TSelBits_1_of_8;

-- flat version
function CaloRing_vec_from_flat (signal flat : std_logic_vector) return TCaloRing_vector;
function CaloRing_vec_to_flat (signal b: TCaloRing_vector) return std_logic_vector;

type vme_dout_vec is array (integer range <>) of std_logic_vector(15 downto 0);
type vme_enout_vec is array (integer range <>) of std_logic;


subtype TPhiSelBits is  std_logic_vector(17 downto 0);
subtype TEtaSelBits is  std_logic_vector(9 downto 0);
type TPhiSelBits_vec is array (integer range<>) of TPhiSelBits;
type TEtaSelBits_vec is array (integer range<>) of TEtaSelBits;

type TPairMatrix is array (integer range 0 to 3, integer range 0 to 3) of std_logic;
type TPairMatrix_vec is array (integer range <>) of TPairMatrix;

-- get a slice of the pair matrix
function which_rpc (
  constant pm : TPairMatrix;
  constant idxdt : integer)
  return std_logic_vector;


-- Match Quality Matrix:
subtype TMatchQual is std_logic_vector(5 downto 0);
type TMQMatrix is array (integer range 0 to 3, integer range 0 to 3) of TMatchQual;
--type TMQMatrix is array (0 to 3, 0 to 3) of TMatchQual;
type TMQMatrix_vec is array (integer range<>) of TMQMatrix;

subtype TCancelBits is std_logic_vector(0 to 7);
type TCancelBits_vec is array (integer range <>) of TCancelBits;

end;


package body GMTTypes is

-------------------------------------------------------------------------------
-- Synced Input muons
-------------------------------------------------------------------------------

function InMuons_vec_from_flat (signal flat : TFourInMuons_flat) return TInMuons_vec is
  variable xx : TInMuons_vec(0 to 3);
  begin
    xx(0) := flat(31 downto 0);
    xx(1) := flat(63 downto 32);
    xx(2) := flat(95 downto 64);
    xx(3) := flat(127 downto 96);
    return xx;
  end;
    
function InMuons_vec_to_flat (signal mus : TInMuons_vec) return TFourInMuons_flat is
  variable flat: TFourInMuons_flat;
  begin
    flat(31 downto 0)   := mus(0);
    flat(63 downto 32)  := mus(1);
    flat(95 downto 64)  := mus(2);
    flat(127 downto 96) := mus(3);
    return flat;
  end;

--
-- unpack
--  
function SyncedMu_from_flat (constant flat : TSyncedMu_flat) return TSyncedMu is
  variable xx : TSyncedMu;
  begin
    xx.ch_valid   := flat(24);           
    xx.charge     := flat(23);           
    xx.finehalo   := flat(22);           
    xx.eta        := flat(21 downto 16);
    xx.qual       := flat(15 downto 13);
    xx.pt         := flat(12 downto 8);  
    xx.phi        := flat(7 downto 0);   
    return xx;
  end function SyncedMu_from_flat;
  
function SyncedMu_vec_from_flat (signal flat : TFourSyncedMu_flat) return TSyncedMu_vector4 is
  variable xx : TSyncedMu_vector4;
  begin
    xx(0) := SyncedMu_from_flat ( flat(24 downto 0) );
    xx(1) := SyncedMu_from_flat ( flat(49 downto 25) );
    xx(2) := SyncedMu_from_flat ( flat(74 downto 50) );
    xx(3) := SyncedMu_from_flat ( flat(99 downto 75) );
    return xx;
  end function SyncedMu_vec_from_flat;

--
-- pack
--
function SyncedMu_to_flat (constant mu : TSyncedMu) return TSyncedMu_flat is
  variable yy : TSyncedMu_flat;
  begin
    yy(24)           := mu.ch_valid;
    yy(23)           := mu.charge;       
    yy(22)           := mu.finehalo;     
    yy(21 downto 16) := mu.eta;     
    yy(15 downto 13) := mu.qual;    
    yy(12 downto 8)  := mu.pt;      
    yy(7 downto 0)   := mu.phi;         
    return yy;
  end function SyncedMu_to_flat;


function SyncedMu_vec_to_flat (signal mus : TSyncedMu_vector4) return TFourSyncedMu_flat is
  variable yy  : TFourSyncedMu_flat;
  begin
    yy(24 downto 0) := SyncedMu_to_flat (mus(0));
    yy(49 downto 25):= SyncedMu_to_flat (mus(1));
    yy(74 downto 50):= SyncedMu_to_flat (mus(2));
    yy(99 downto 75):= SyncedMu_to_flat (mus(3));
    yy(100) := '0';                     -- spare bit
    return yy;
  end function SyncedMu_vec_to_flat;
  
-------------------------------------------------------------------------------
-- GMT muons
-------------------------------------------------------------------------------

--
-- unpack
--  
function GMTMu_from_flat (constant flat : TGMTMu_flat) return TGMTMu is
  variable xx : TGMTMu;
  begin
    xx.sysign     := flat(25 downto 24);           
    xx.mip        := flat(23);           
    xx.isol       := flat(22);           
    xx.eta        := flat(21 downto 16);
    xx.qual       := flat(15 downto 13);
    xx.pt         := flat(12 downto 8);  
    xx.phi        := flat(7 downto 0);   
    return xx;
  end function GMTMu_from_flat;
  
function GMTMu_vec_from_flat (signal flat : TFourGMTMu_flat) return TGMTMu_vector4 is
  variable xx : TGMTMu_vector4;
  begin
    xx(0) := GMTMu_from_flat ( flat(25 downto 0) );
    xx(1) := GMTMu_from_flat ( flat(51 downto 26) );
    xx(2) := GMTMu_from_flat ( flat(77 downto 52) );
    xx(3) := GMTMu_from_flat ( flat(103 downto 78) );
    return xx;
  end function GMTMu_vec_from_flat;

--
-- pack
--
function GMTMu_to_flat (signal mu : TGMTMu) return TGMTMu_flat is
  variable yy : TGMTMu_flat;
  begin
    yy(25 downto 24) := mu.sysign;
    yy(23)           := mu.mip;       
    yy(22)           := mu.isol;     
    yy(21 downto 16) := mu.eta;     
    yy(15 downto 13) := mu.qual;    
    yy(12 downto 8)  := mu.pt;      
    yy(7 downto 0)   := mu.phi;         
    return yy;
  end function GMTMu_to_flat;


function GMTMu_vec_to_flat (signal mus : TGMTMu_vector4) return TFourGMTMu_flat is
  variable yy  : TFourGMTMu_flat;
  begin
    yy(25 downto 0) := GMTMu_to_flat (mus(0));
    yy(51 downto 26):= GMTMu_to_flat (mus(1));
    yy(77 downto 52):= GMTMu_to_flat (mus(2));
    yy(103 downto 78):= GMTMu_to_flat (mus(3));
    yy(104) := '0';
    return yy;
  end function GMTMu_vec_to_flat;
  
-------------------------------------------------------------------------------
-- Calo MIP & ISO bits
-------------------------------------------------------------------------------
  
--
-- unpack
--
function CaloRing_vec_from_flat (signal flat : std_logic_vector) return TCaloRing_vector is
    variable vec : TCaloRing_vector(0 to ((flat'high+1)/18)-1);
  begin
    for i in 0 to ((flat'high+1)/18)-1 loop
      vec(i) := flat(18*i to 18*i+17);
    end loop;  -- i
    return vec;
  end function CaloRing_vec_from_flat;

--
--pack
--
function CaloRing_vec_to_flat (signal b: TCaloRing_vector) return std_logic_vector is
    variable flat : std_logic_vector(0 to ((b'high+1)*18-1));
  begin
    for i in 0 to b'high loop
      flat(18*i to 18*i+17) := b(i);
    end loop;  -- i
    return flat;
  end function CaloRing_vec_to_flat;


  
-- synopsys translate_off
procedure Write (
  variable L     : inout Line;          -- Line
  variable value : in    TSyncedMu) is    -- muon
begin
  Write (L, TO_BIT (value.ch_valid) );
  Write (L, ' ');
  Write (L, TO_BIT (value.charge) );
  Write (L, ' ');
  Write (L, TO_BIT (value.finehalo) );
  Write (L, ' ');
  Write(L, TO_BITVECTOR (value.eta) );   
  Write (L, ' ');
  Write(L, TO_BITVECTOR (value.qual) );   
  Write (L, ' ');
  Write(L, TO_BITVECTOR (value.pt) );   
  Write (L, ' ');
  Write(L, TO_BITVECTOR (value.phi) );   
end Write;
-- synopsys translate_on
    
-- synopsys translate_off
procedure Write (
  variable L     : inout Line;          -- Line
  constant value : in    TGMTMu) is    -- muon
begin
  Write (L, TO_BITVECTOR (value.sysign) );
  Write (L, ' ');
  Write (L, TO_BIT (value.mip) );
  Write (L, ' ');
  Write (L, TO_BIT (value.isol) );
  Write (L, ' ');
  Write(L, TO_BITVECTOR (value.eta) );   
  Write (L, ' ');
  Write(L, TO_BITVECTOR (value.qual) );   
  Write (L, ' ');
  Write(L, TO_BITVECTOR (value.pt) );   
  Write (L, ' ');
  Write(L, TO_BITVECTOR (value.phi) );   
end Write;
-- synopsys translate_on
    
-------------------------------------------------------------------------------
-- get RPC select bits from pair matrix
-------------------------------------------------------------------------------
function which_rpc (
  constant pm : TPairMatrix;
  constant idxdt : integer)
  return std_logic_vector is

  variable selbits : std_logic_vector(0 to 3);
  begin
    for i in 0 to 3 loop
      selbits(i) := pm(idxdt,i);
    end loop;  -- i
    return selbits;
  end;


end GMTTypes;