--******************************************************************************
--* @short 8->4 Sorter based on sort ranks
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv3.cern.ch>
--* @date $Date: 2005/01/31 15:17:30 $
--* @version $Revision: 1.5 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_std.all;
use WORK.GMTTypes.all;
use work.LFTiming.all;
use work.SorterUnit.all;
entity LFSortStage1 is
generic (
sorter_lat_start : integer := 6); -- start latency
port (iSortRanksOther : in TSortRank_vector(0 to 3);
iSortRanksRPC : in TSortRank_vector(0 to 3);
iEmptyOther : in std_logic_vector(0 to 3); -- arrive 1/2 bx later
iEmptyRPC : in std_logic_vector(0 to 3); -- arrive 1/2 bx later
iCancelOther_A : in std_logic_vector(0 to 3); -- arrive 1/2 bx later
iCancelRPC_A : in std_logic_vector(0 to 3); -- arrive 1/2 bx later
iCancelOther_B : in std_logic_vector(0 to 3); -- arrive 1/2 bx later
iCancelRPC_B : in std_logic_vector(0 to 3); -- arrive 1/2 bx later
iMuonsOther : in TGMTMu_vector(0 to 3); -- arrive 1/2 bx later
iMuonsRPC : in TGMTMu_vector(0 to 3); -- arrive 1/2 bx later
--
iIdxBitsOther : in TIndexBits_vector(0 to 3); -- arrive 1/2 bx later
-- iIdxBitsRPC : in TIndexBits_vector(0 to 3); -- arrive 1/2 bx later
-- (generate RPC indices, automatically)
oMuons : out TGMTMu_vector(0 to 3);
oSortRanks : out TSortRank_vector(0 to 3);
oIdxBits : out TIndexBits_vector(0 to 3);
oIsRPCMu : out std_logic_vector(0 to 3);
-- Clock and control
clk : in std_logic;
sinit : in std_logic);
end;
architecture behavioral of LFSortStage1 is
attribute syn_useioff : boolean;
attribute syn_useioff of behavioral : architecture is true;
component comp8
port (
A: IN std_logic_VECTOR(7 downto 0);
B: IN std_logic_VECTOR(7 downto 0);
A_GE_B: OUT std_logic);
end component;
-- Synplicity black box declaration
attribute syn_black_box : boolean;
attribute syn_black_box of comp8: component is true;
signal GEMatrix, GEMatrix_reg : TGEMatrix;
signal sSortRanks : TSortRank_vector(0 to 7);
signal sSortRanks_reg : TSortRank_vector(0 to 7);
signal sDisable : std_logic_vector(0 to 7);
signal sSelBits : TSelBits_1_of_8_vec (0 to 3);
begin -- architecture behavioral
sSortRanks(0 to 3) <= iSortRanksOther;
sSortRanks(4 to 7) <= iSortRanksRPC;
sDisable(0 to 3) <= iEmptyOther or iCancelOther_A or iCancelOther_B;
sDisable(4 to 7) <= iEmptyRPC or iCancelRPC_A or iCancelRPC_B;
-----------------------------------------------------------------------------
-- calculate GE Matrix
-----------------------------------------------------------------------------
g1: for i in 0 to 7 generate
g2: for j in i+1 to 7 generate
x: comp8
port map (
A => sSortRanks(i),
B => sSortRanks(j),
A_GE_B => GEMatrix(i,j));
-- in case of equal ranks the lower index muon wins
GEMatrix(j,i) <= not GEMatrix(i,j);
end generate;
end generate;
-----------------------------------------------------------------------------
-- register the result and the empty inputs
-----------------------------------------------------------------------------
reg_ge: process (clk) is
begin -- process reg_ge
if clk'event and clk = calc_lf_edge(sorter_lat_start + LF_RLAT_SORT_GEMatrix) then
GEMatrix_reg <= GEMatrix;
sSortRanks_reg <= sSortRanks;
end if;
end process reg_ge;
-----------------------------------------------------------------------------
-- sort and four 8 to 1 Muxes
-----------------------------------------------------------------------------
count_wins(GEMatrix_reg, sDisable, sSelBits);
mux: process (clk) is
begin
if clk'event and clk = calc_lf_edge(sorter_lat_start + LF_RLAT_SORT_DONE) then
for iplace in 0 to 3 loop
case sSelBits(iplace) is
when "10000000" => oMuons(iplace) <= iMuonsOther(0);
when "01000000" => oMuons(iplace) <= iMuonsOther(1);
when "00100000" => oMuons(iplace) <= iMuonsOther(2);
when "00010000" => oMuons(iplace) <= iMuonsOther(3);
when "00001000" => oMuons(iplace) <= iMuonsRPC(0);
when "00000100" => oMuons(iplace) <= iMuonsRPC(1);
when "00000010" => oMuons(iplace) <= iMuonsRPC(2);
when "00000001" => oMuons(iplace) <= iMuonsRPC(3);
when others => oMuons(iplace) <= ( "00", '0', '0', "000000", "000", "00000", "00000000" );
end case;
case sSelBits(iplace) is
when "10000000" => oSortRanks(iplace) <= sSortRanks_reg(0);
when "01000000" => oSortRanks(iplace) <= sSortRanks_reg(1);
when "00100000" => oSortRanks(iplace) <= sSortRanks_reg(2);
when "00010000" => oSortRanks(iplace) <= sSortRanks_reg(3);
when "00001000" => oSortRanks(iplace) <= sSortRanks_reg(4);
when "00000100" => oSortRanks(iplace) <= sSortRanks_reg(5);
when "00000010" => oSortRanks(iplace) <= sSortRanks_reg(6);
when "00000001" => oSortRanks(iplace) <= sSortRanks_reg(7);
when others => oSortRanks(iplace) <= (others => '0');
end case;
case sSelBits(iplace) is
when "10000000" => oIdxBits(iplace) <= iIdxBitsOther(0);
when "01000000" => oIdxBits(iplace) <= iIdxBitsOther(1);
when "00100000" => oIdxBits(iplace) <= iIdxBitsOther(2);
when "00010000" => oIdxBits(iplace) <= iIdxBitsOther(3);
when "00001000" => oIdxBits(iplace) <= "0000";
when "00000100" => oIdxBits(iplace) <= "0100";
when "00000010" => oIdxBits(iplace) <= "1000";
when "00000001" => oIdxBits(iplace) <= "1100";
when others => oIdxBits(iplace) <= (others => '0');
end case;
case sSelBits(iplace) is
when "10000000" => oIsRPCMu(iplace) <= '0';
when "01000000" => oIsRPCMu(iplace) <= '0';
when "00100000" => oIsRPCMu(iplace) <= '0';
when "00010000" => oIsRPCMu(iplace) <= '0';
when "00001000" => oIsRPCMu(iplace) <= '1';
when "00000100" => oIsRPCMu(iplace) <= '1';
when "00000010" => oIsRPCMu(iplace) <= '1';
when "00000001" => oIsRPCMu(iplace) <= '1';
when others => oIsRPCMu(iplace) <= '0';
end case;
end loop; -- iplace
end if;
end process mux;
end architecture behavioral;