--******************************************************************************
--* @short      Sort Rank Merger. merges the sort ranks 
--******************************************************************************
--* @author  SAKULIN Hannes  <hsakulin@dsy-srv3.cern.ch>
--* @date    $Date: 2005/01/31 15:17:30 $
--* @version $Revision: 1.3 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
use WORK.GMTTypes.all;
use WORK.LFTypes.all;
use work.LFVMEAddrMap.all;
use work.LFTiming.all;
--use work.VMEMux.all;

entity LFSortRankMerger is
  
  generic (
    sort_rank_merger_lat_start : integer := 4);  -- start latency

  port (
    -- INPUTS
    iSortRanksDTCSC        : in TSortRank_vector(0 to 3);  

    iSortRanksMatchedDTCSC : in TSortRank_vector(0 to 3);
    iSortRanksMatchedRPC   : in TSortRank_vector(0 to 3);

    iPairMatrix            : in TPairMatrix;
    iSelectMatrix_SRK      : in TPairMatrix;  -- 1 for DT/CSC
    
    -- OUTPUTS
    oSortRanksMerged       : out TSortRank_vector(0 to 3);

    -- Clock and control
    clk            : in    std_logic;
    sinit          : in    std_logic
  );  
  
end entity LFSortRankMerger;

architecture behavioral of LFSortRankMerger is

    signal sSortRanksMerged       : TSortRank_vector(0 to 3);


begin  -- architecture behavioral

  merger_unit: for i in 0 to 3 generate
    signal pmslice,selslice : std_logic_vector(0 to 3);
  begin  -- generate merger_unit
    pmslice <= which_rpc(iPairMatrix, i);
    selslice <= which_rpc(iSelectMatrix_SRK, i);
    mu: entity work.LFSortRankMergeUnit
      port map (
        iSortRankDTCSC        => iSortRanksDTCSC(i),
        iSortRankMatchedDTCSC => iSortRanksMatchedDTCSC(i),
        iSortRanksMatchedRPC  => iSortRanksMatchedRPC,
        iWhichRPC             => pmslice,
        iSelectBits           => selslice,
        oSortRank             => sSortRanksMerged(i),
        
        clk                   => clk,
        sinit                 => sinit);
  end generate merger_unit;

  -- register outputs
  reg_rank: process (clk) is
  begin  
    if clk'event and clk = calc_lf_edge(sort_rank_merger_lat_start + LF_RLAT_SRM_DONE) then  
      oSortRanksMerged <= sSortRanksMerged;
    end if;
  end process reg_rank;

end architecture behavioral;