-------------------------------------------------------------------------------
-- Module Name: HitSort
-- Author     : Naoki Kimura (naoki.kimura@cern.ch)
-- Created    : 25-Jun-2014
-- Comments   : Pixel hit sorting by SS # base from colum base
-- Change Log 
-- 25-Jun-214 : Start
-- 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Library
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_MISC.ALL;
use IEEE.NUMERIC_STD.ALL;

-------------------------------------------------------------------------------
-- Port for HitSort (FSM)
-------------------------------------------------------------------------------
entity HitSort is
  generic (
    c_n_mod_bucket  : integer :=3;
    c_nb_address    : integer := 9;
    c_nSS_RAW       : integer := 22;
    c_nSS_COLUMN    : integer := 4;    
    c_nb_RAW        : integer := 6;  -- need to chenge also buff fifo size 
    c_nb_COLUMN     : integer := 4;  -- need to chenge also buff fifo size 
    c_nb_indata     : integer := 32; -- 42 changed by Rui
        -- Bucket size...
--     c_RAW_depth     : integer := 540;      -- posibllly maximum
--     c_COLUMN_depth     : integer := 2970   -- posibllly maximum
     c_RAW_depth     : integer := 63;    -- temp
     c_COLUMN_depth     : integer := 255  --temp

    );
  port(
    -- General
    CLOCK: in std_logic;
    CLOCK_FAST: in std_logic;      
    RESET : in std_logic;  
    -- Input   sorted by column base
    IN_HIT_DATA                         : in std_logic_vector(c_nb_indata-1 downto 0);  
    IN_HIT_DATA_VALID                   : in std_logic;  
    HOLD_DOWN                           : in std_logic;  
    -- Output  sorted by SS # base
    OUT_HIT_DATA                        : out std_logic_vector(c_nb_indata-1 downto 0);
    OUT_HIT_DATA_VALID                  : out std_logic;
    HOLD_UP                             : out std_logic;  --almost full
    FULL                                : out std_logic;
    SortERROR                           : out std_logic_vector(31 downto 0)
    );
end HitSort;

-------------------------------------------------------------------------------
-- Behaviorl HitSort
-------------------------------------------------------------------------------
architecture Behavioral of HitSort is
-------------------------------------------------------------------------------
-- signal declaration
-------------------------------------------------------------------------------
  signal checkbit: std_logic_vector(31 downto 0);  -- for debug
  signal clk : std_logic;
  signal clk_fast : std_logic;  
  signal rst : std_logic;
-- infifo
  signal infifo_data : std_logic_vector(c_nb_indata-1 downto 0);
  signal infifo_dv : std_logic;
  signal infifo_rd_en : std_logic;
  signal infifo_wr_en : std_logic;  
  signal infifo_empty : std_logic;
  signal infifo_prog_full : std_logic;
  signal infifo_wrusedw: std_logic_vector(10 downto 0);

  signal bufifo_rd_en : std_logic;
  signal bufifo_wr_en : std_logic;  
  signal bufifo_empty : std_logic;


-- control
  signal stopraw_read : std_logic;

  signal stopraw_write : std_logic;  
  signal stopcolumn_read : std_logic;

  signal stopcolumn_write : std_logic;  

-- lut
  signal addra_RAW : std_logic_vector(c_nb_address-1 downto 0);
  signal addra_COLUMN : std_logic_vector(c_nb_address-1 downto 0);
  signal SSID_RAW : std_logic_vector(c_nb_RAW-1 downto 0);
  signal SSID_COLUMN : std_logic_vector(c_nb_COLUMN-1 downto 0);
  signal SSID_RAW_0 : std_logic_vector(c_nb_RAW-1 downto 0);
  signal SSID_COLUMN_0 : std_logic_vector(c_nb_COLUMN-1 downto 0);
  
  signal infifo_data_reg0 : std_logic_vector(c_nb_indata-1 downto 0);
  signal infifo_data_reg1 : std_logic_vector(c_nb_indata-1 downto 0);  

  signal infifo_data_dv_reg0 : std_logic;
  signal infifo_data_dv_reg1 : std_logic;

  signal indata_wSSID : std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  signal indata_wSSID_dv : std_logic;

  signal indata_wSSID_reg0 : std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  signal indata_wSSID_dv_reg0 : std_logic;

  signal indata_wSSID_reg1 : std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  signal indata_wSSID_dv_reg1 : std_logic;

  signal indata_wSSID_reg2 : std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  signal indata_wSSID_dv_reg2 : std_logic;
  
  signal indata_wSSID_AfterRAWSort : std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  signal indata_wSSID_AfterRAWSort_dv : std_logic;

  signal indata_wSSID_AfterRAWSort_reg0 : std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  signal indata_wSSID_AfterRAWSort_dv_reg0 : std_logic;
  
  signal indata_wSSID_AfterCOLUMNSort : std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  signal indata_wSSID_AfterCOLUMNSort_dv : std_logic;
  
  -- special for read part 
  signal reading_raw : std_logic;
  signal reading_column : std_logic;  

  signal prioraw_add : std_logic_vector(23 downto 0); ---Rui:why not 21 downto 0?
  signal prioraw_valid : std_logic;
  signal int_prioraw_add : integer range 0 to 23;-- changed from 255 Naoki
  signal prioraw_in : std_logic_vector(23 downto 0) := X"000000";

  signal priocolumn_add : std_logic_vector(3 downto 0);
  signal priocolumn_valid : std_logic;
  signal int_priocolumn_add : integer range 0 to 3;  -- changed from 255 Naoki
  signal priocolumn_in : std_logic_vector(3 downto 0) := X"0";
  
  -- signal Array
  -- N.B. currentry only 22 for RAW and 4 for COLUM SSID  depth is 135*4 or 135*22 (328x152/ (22*4 raw) or (4*4 col) should be *2?) 
  type t_RAWBucket                is array(21   downto 0) of std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  type t_RAWBucketArray           is array(c_RAW_depth  downto 0) of t_RAWBucket;  -- 9 is depth of bucket (more than 135*4
  type t_COLUMNBucket             is array(3    downto 0) of std_logic_vector(c_nb_indata+c_nb_RAW+c_nb_COLUMN-1 downto 0);
  type t_COLUMNBucketArray        is array(c_COLUMN_depth downto 0) of t_COLUMNBucket;  -- 11 is depth of bucket for coum 135*22

  -- 2 is n_mod_in_Bucket 
  signal write_done_RAW : std_logic;
  signal write_done_COLUMN : std_logic;
  signal write_done_RAW_two : std_logic;
  signal write_done_COLUMN_two : std_logic;
  signal pre_write_done_RAW : std_logic;
  signal pre_write_done_COLUMN : std_logic;
  signal read_done_RAW : std_logic;
  signal read_done_COLUMN : std_logic;
--  signal int_nModRAWPac : integer range 0 to 31;
--  signal int_nModCOLUMNPac : integer range 0 to 31;     
  signal int_nModRAWPac : integer range 0 to 3;
  signal int_nModCOLUMNPac : integer range 0 to 3;     

  type t_RAWDataExistVector       is array(3 downto 0) of std_logic_vector(21 downto 0); --22 ss for raw
  type t_RAWCounterArray          is array(21 downto 0) of std_logic_vector(9 downto 0);
  type t_RAWCounterArrayVector    is array(3  downto 0) of t_RAWCounterArray; --4 event
  type t_COLUMNDataExistVector    is array(3 downto 0) of std_logic_vector(3 downto 0);  --4 ss for column
  type t_COLUMNCounterArray       is array(3  downto 0) of std_logic_vector(11 downto 0);
  type t_COLUMNCounterArrayVector is array(3  downto 0) of t_COLUMNCounterArray;--4 event
  signal RAWDataExistVector    : t_RAWDataExistVector;  
  signal RAWBucketArray      : t_RAWBucketArray     ;
  signal RAWCounterArrayVector     : t_RAWCounterArrayVector    ;
  signal COLUMNDataExistVector : t_COLUMNDataExistVector;
  signal COLUMNBucketArray   : t_COLUMNBucketArray  ;
  signal COLUMNCounterArrayVector  : t_COLUMNCounterArrayVector ;

  type t_RAWBucket_Depth is array(21 downto 0) of integer range 0 to c_COLUMN_depth*3;---c_RAW_depth*2; --*2;
  type t_COLUMNBucket_Depth is array(3 downto 0) of integer range 0 to c_COLUMN_depth*2;--*2;  

  signal int_RAWBucketArray_RdPo : t_RAWBucket_Depth;
  signal int_RAWBucketArray_WrPo : t_RAWBucket_Depth;
  signal int_RAWBucket_AFull_Counter : t_RAWBucket_Depth;  -- if I add that. ISim clk stop at 10 usec... why. try other way
  signal int_COLUMNBucketArray_RdPo : t_COLUMNBucket_Depth;
  signal int_COLUMNBucketArray_WrPo : t_COLUMNBucket_Depth;
  signal int_COLUMNBucket_AFull_Counter : t_RAWBucket_Depth;

  signal int_ssid_raw : integer range 0 to 21; --changed from 255 Sep24-2014 Naoki
  signal int_ssid_column : integer range 0 to 3; --changed from 255 Sep24-2014 Naoki

  signal int_module_id_wr_raw : integer range 0 to 7; --changed 8oct18 from 255 Sep24-2014 Naoki
  signal int_module_id_rd_raw : integer range 0 to 7; --changed 8oct18 from 255 Sep24-2014 Naoki    
  signal nbit_raw : integer range 0 to 31; --changed from 255 Sep24-2014 Naoki
  signal shifted_data_raw : std_logic_vector(31 downto 0);

--  signal int_module_id_wr_column : integer range 0 to 31; --changed from 255 Sep24-2014 Naoki
--  signal int_module_id_rd_column : integer range 0 to 31; --changed from 255 Sep24-2014 Naoki    
  signal int_module_id_wr_column : integer range 0 to 7; --changed 8 cot19 from 255 Sep24-2014 Naoki
  signal int_module_id_rd_column : integer range 0 to 7; --changed 8 cot19 from 255 Sep24-2014 Naoki    
  signal nbit_column : integer range 0 to 31; --changed from 255 Sep24-2014 Naoki
  signal shifted_data_column : std_logic_vector(31 downto 0);

  signal xxx : std_logic;
  
  type state_type is (s0,s1,s2,s3);  --type of state machine.
  signal current_s,next_s: state_type;  --current and next state declaration.
-------------------------------------------------------------------------------
-- Port for Sorting
-------------------------------------------------------------------------------
  -- port for the fifo_sort
 component FIFO_SORT_ALTERA
    port (
    aclr : IN STD_LOGIC  := '0';
    data : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
    rdclk: IN STD_LOGIC ;
    rdreq: IN STD_LOGIC ;
    wrclk: IN STD_LOGIC ;
    wrreq: IN STD_LOGIC ;
    q: OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
    rdempty: OUT STD_LOGIC ;
    wrfull: OUT STD_LOGIC ;
    wrusedw : OUT STD_LOGIC_VECTOR (10 DOWNTO 0)
      );                
  end component;        
  component BUFIFO_Sort_Altera
    port (
    aclr : IN STD_LOGIC ;
    clock: IN STD_LOGIC ;
    data: IN STD_LOGIC_VECTOR (41 DOWNTO 0);
    rdreq : IN STD_LOGIC ;
    wrreq : IN STD_LOGIC ;
    empty : OUT STD_LOGIC ;
    full: OUT STD_LOGIC ;
    q: OUT STD_LOGIC_VECTOR (41 DOWNTO 0)
      );
  end component;
  -- port for the LUT Raw
  component LUT_Raw_Sort_Altera
    port (
    data : IN STD_LOGIC_VECTOR (5 DOWNTO 0);
    rdaddress : IN STD_LOGIC_VECTOR (8 DOWNTO 0);
    rdclock: IN STD_LOGIC ;
    wraddress: IN STD_LOGIC_VECTOR (8 DOWNTO 0);
    wrclock: IN STD_LOGIC  := '1';
    wren: IN STD_LOGIC  := '0';
    q: OUT STD_LOGIC_VECTOR (5 DOWNTO 0)
      );                
  end component;        
  -- port for the LUT Column
  component LUT_Column_Sort_Altera
    port (
    data : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
    rdaddress : IN STD_LOGIC_VECTOR (8 DOWNTO 0);
    rdclock: IN STD_LOGIC ;
    wraddress: IN STD_LOGIC_VECTOR (8 DOWNTO 0);
    wrclock: IN STD_LOGIC  := '1';
    wren: IN STD_LOGIC  := '0';
    q: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
      );                
  end component;               
  -- priorawrity encoder
  component priority_encoder_raw 
    generic(
      output_width: integer := 24
      );
    port ( 
      Dec_addr: in  STD_LOGIC_VECTOR(output_width-1 downto 0);
      Addr : out STD_LOGIC_VECTOR(output_width-1 downto 0);
      Valid: out STD_LOGIC
      );
  end component;
  component priority_encoder_column 
    generic(
      output_width: integer := 4
      );
    port ( 
      Dec_addr: in  STD_LOGIC_VECTOR(output_width-1 downto 0);
      Addr : out STD_LOGIC_VECTOR(output_width-1 downto 0);
      Valid: out STD_LOGIC
      );
  end component;

  -- bit shifter
  component bitshifter_logicvector
    generic(
      output_width: integer := 32
      );
    port ( 
      nbit  : in integer range 0 to 255;
      shifted_data  : out STD_LOGIC_VECTOR(output_width-1 downto 0)
      );
  end component;

-------------------------------------------------------------------------------
-- Begin HitSort
-------------------------------------------------------------------------------
begin
  clk <= CLOCK;
  clk_fast <= CLOCK_FAST;  
  rst <= RESET;

-------------------------------------------------------------------------------
-- Port map for Sorting
-------------------------------------------------------------------------------
  -- infifo
   infifo_sort:  FIFO_SORT_ALTERA
    port map(
      wrclk => clk_fast,
      rdclk => clk,      
      aclr => rst,
      data => IN_HIT_DATA,
      wrreq => infifo_wr_en, -- IN_HIT_DATA_VALID,    -- it should be...stupid way
      rdreq => infifo_rd_en,
      q => infifo_data,
      wrfull => FULL,
      rdempty => infifo_empty,
      wrusedw => infifo_wrusedw -- HOLD_UP           --same reason...
      );
      
  buffifo_sort: BUFIFO_Sort_Altera
    port map(
      clock   => clk,
      aclr   => rst,
      data   => indata_wSSID_reg0,
      wrreq => indata_wSSID_dv_reg0,
      rdreq => bufifo_rd_en,
      q  => indata_wSSID,
      full  => open,
      empty => bufifo_empty
      );

  -- LUT Raw
  rawlut: LUT_Raw_Sort_Altera
    port map(
      wrclock => clk,  --     wren => "0",                       -- do not write
      wraddress => "000000000",
      data => "000000",
      rdclock => clk,
      rdaddress => addra_RAW,
      q => SSID_RAW_0
      );    
  -- LUT Column
  columnlut: LUT_Column_Sort_Altera
    port map(
      wrclock => clk,  --     wren => "0",                       -- do not write
      wraddress => "000000000",
      data => "0000",
      rdclock => clk,
      rdaddress => addra_COLUMN,
      q => SSID_COLUMN_0
      );    

-- priority
  RAWencoder: priority_encoder_raw
    generic map (
      output_width =>24
      )
    port map( 
      Dec_addr => prioraw_in,
      Addr => prioraw_add,
      Valid => prioraw_valid
      );
  COLUMNencoder: priority_encoder_column
    generic map (
      output_width =>4
      )
    port map( 
      Dec_addr => priocolumn_in,
      Addr => priocolumn_add,
      Valid => priocolumn_valid
      );

-- bit shifter 
  bitshift_raw: bitshifter_logicvector
    generic map (
      output_width =>32
      )
    port map(
      nbit => int_ssid_raw,
      shifted_data => shifted_data_raw
      );
  bitshift_column: bitshifter_logicvector
    generic map (
      output_width =>32
      )
    port map(
--      nbit => nbit_column,
      nbit => int_ssid_column,
      shifted_data => shifted_data_column
      );
-------------------------------------------------------------------------------
-- Simultaneous connections
-------------------------------------------------------------------------------
  infifo_prog_full <= infifo_wrusedw(10);
  -- error bits
   SortERROR <=  infifo_prog_full  & stopraw_read & stopraw_write & stopcolumn_read & stopcolumn_write & HOLD_DOWN & "00" &
                 std_logic_vector(to_unsigned(int_nModRAWPac,2)) & std_logic_vector(to_unsigned(int_nModCOLUMNPac,2)) &
                 X"00000";

--
  -- because grid system send contineously send dv=1 in hold......
  infifo_wr_en <= '1' when ( (IN_HIT_DATA_VALID='1') and (infifo_prog_full='0') ) else '0';
  HOLD_UP <= infifo_prog_full;
  -- max is 21. 21> is trailer 1111111
  int_ssid_raw <= to_integer(unsigned(indata_wSSID(41 downto 36))) when to_integer(unsigned(indata_wSSID(41 downto 36))) < 22 else 21; --
  -- max is 3
  int_ssid_column <= to_integer(unsigned(indata_wSSID_AfterRAWSort(35 downto 32))) when to_integer(unsigned(indata_wSSID_AfterRAWSort(35 downto 32))) < 4 else 3;
  -- only solution to good "done" timing . not good //stopraw_write
  read_done_RAW<='1' when (reading_raw = '1' and int_prioraw_add=21 and unsigned(RAWCounterArrayVector(int_module_id_rd_raw)(int_prioraw_add))=1 and
                           stopraw_write = '0' ) else '0';
  read_done_COLUMN<='1' when (reading_column = '1' and int_priocolumn_add=3 and
                              unsigned(COLUMNCounterArrayVector(int_module_id_rd_column)(int_priocolumn_add))=1 and stopcolumn_write='0' ) else '0';  
  --backpresure


  -- hold_up for raw_sorting
  stopraw_read <='1'when ((int_nModRAWPac > 1) or -- stop if there are more then 3 modules in the bucket
--                          (int_nModRAWPac=2  and  write_done_RAW = '1') or  -- stupid --change later
                          ( int_RAWBucket_AFull_Counter( 0) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 0 ) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 0) < c_RAW_depth and int_RAWBucket_AFull_Counter( 0 ) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 1) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 1) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 1) < c_RAW_depth and int_RAWBucket_AFull_Counter( 1) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 2) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 2) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 2) < c_RAW_depth and int_RAWBucket_AFull_Counter( 2) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 3) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 3) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 3) < c_RAW_depth and int_RAWBucket_AFull_Counter( 3) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 4) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 4) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 4) < c_RAW_depth and int_RAWBucket_AFull_Counter( 4) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 5) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 5) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 5) < c_RAW_depth and int_RAWBucket_AFull_Counter( 5) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 6) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 6) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 6) < c_RAW_depth and int_RAWBucket_AFull_Counter( 6) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 7) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 7) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 7) < c_RAW_depth and int_RAWBucket_AFull_Counter( 7) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 8) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 8) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 8) < c_RAW_depth and int_RAWBucket_AFull_Counter( 8) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter( 9) >= c_RAW_depth and int_RAWBucket_AFull_Counter( 9) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter( 9) < c_RAW_depth and int_RAWBucket_AFull_Counter( 9) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(10) >= c_RAW_depth and int_RAWBucket_AFull_Counter(10) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(10) < c_RAW_depth and int_RAWBucket_AFull_Counter(10) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(11) >= c_RAW_depth and int_RAWBucket_AFull_Counter(11) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(11) < c_RAW_depth and int_RAWBucket_AFull_Counter(11) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(12) >= c_RAW_depth and int_RAWBucket_AFull_Counter(12) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(12) < c_RAW_depth and int_RAWBucket_AFull_Counter(12) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(13) >= c_RAW_depth and int_RAWBucket_AFull_Counter(13) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(13) < c_RAW_depth and int_RAWBucket_AFull_Counter(13) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(14) >= c_RAW_depth and int_RAWBucket_AFull_Counter(14) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(14) < c_RAW_depth and int_RAWBucket_AFull_Counter(14) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(15) >= c_RAW_depth and int_RAWBucket_AFull_Counter(15) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(15) < c_RAW_depth and int_RAWBucket_AFull_Counter(15) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(16) >= c_RAW_depth and int_RAWBucket_AFull_Counter(16) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(16) < c_RAW_depth and int_RAWBucket_AFull_Counter(16) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(17) >= c_RAW_depth and int_RAWBucket_AFull_Counter(17) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(17) < c_RAW_depth and int_RAWBucket_AFull_Counter(17) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(18) >= c_RAW_depth and int_RAWBucket_AFull_Counter(18) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(18) < c_RAW_depth and int_RAWBucket_AFull_Counter(18) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(19) >= c_RAW_depth and int_RAWBucket_AFull_Counter(19) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(19) < c_RAW_depth and int_RAWBucket_AFull_Counter(19) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(20) >= c_RAW_depth and int_RAWBucket_AFull_Counter(20) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(20) < c_RAW_depth and int_RAWBucket_AFull_Counter(20) > c_RAW_depth-3  ) or
                          ( int_RAWBucket_AFull_Counter(21) >= c_RAW_depth and int_RAWBucket_AFull_Counter(21) > c_RAW_depth+c_RAW_depth-3 ) or
                          ( int_RAWBucket_AFull_Counter(21) < c_RAW_depth and int_RAWBucket_AFull_Counter(21) > c_RAW_depth-3  ) ) else '0';


  stopcolumn_read <= '1' when((int_nModCOLUMNPac > 1) or -- stop if there are more then 3 event in the bucket
           -- not checked yet... and stupid...
                             ( int_COLUMNBucket_AFull_Counter( 0) >= c_COLUMN_depth and int_COLUMNBucket_AFull_Counter( 0) > c_COLUMN_depth+c_COLUMN_depth-3 ) or
                             ( int_COLUMNBucket_AFull_Counter( 0) < c_COLUMN_depth and int_COLUMNBucket_AFull_Counter( 0) > c_COLUMN_depth-3 ) or
                             ( int_COLUMNBucket_AFull_Counter( 1) >= c_COLUMN_depth and int_COLUMNBucket_AFull_Counter( 1) > c_COLUMN_depth+c_COLUMN_depth-3 ) or
                             ( int_COLUMNBucket_AFull_Counter( 1) < c_COLUMN_depth and int_COLUMNBucket_AFull_Counter( 1) > c_COLUMN_depth-3 ) or
                             ( int_COLUMNBucket_AFull_Counter( 2) >= c_COLUMN_depth and int_COLUMNBucket_AFull_Counter( 2) > c_COLUMN_depth+c_COLUMN_depth-3 ) or
                             ( int_COLUMNBucket_AFull_Counter( 2) < c_COLUMN_depth and int_COLUMNBucket_AFull_Counter( 2) > c_COLUMN_depth-3 ) or
                             ( int_COLUMNBucket_AFull_Counter( 3) >= c_COLUMN_depth and int_COLUMNBucket_AFull_Counter( 3) > c_COLUMN_depth+c_COLUMN_depth-3 ) or
                             ( int_COLUMNBucket_AFull_Counter( 3) < c_COLUMN_depth and int_COLUMNBucket_AFull_Counter( 3) > c_COLUMN_depth-3 ) )else '0';

  stopraw_write<=stopcolumn_read;
  stopcolumn_write <= HOLD_DOWN;
--  stopcolumn_read <= HOLD_DOWN;  
  int_RAWBucket_AFull_Counter( 0)<= c_RAW_depth + int_RAWBucketArray_WrPo( 0)  -  int_RAWBucketArray_RdPo( 0);
  int_RAWBucket_AFull_Counter( 1)<= c_RAW_depth + int_RAWBucketArray_WrPo( 1)  -  int_RAWBucketArray_RdPo( 1);
  int_RAWBucket_AFull_Counter( 2)<= c_RAW_depth + int_RAWBucketArray_WrPo( 2)  -  int_RAWBucketArray_RdPo( 2);
  int_RAWBucket_AFull_Counter( 3)<= c_RAW_depth + int_RAWBucketArray_WrPo( 3)  -  int_RAWBucketArray_RdPo( 3);
  int_RAWBucket_AFull_Counter( 4)<= c_RAW_depth + int_RAWBucketArray_WrPo( 4)  -  int_RAWBucketArray_RdPo( 4);
  int_RAWBucket_AFull_Counter( 5)<= c_RAW_depth + int_RAWBucketArray_WrPo( 5)  -  int_RAWBucketArray_RdPo( 5);
  int_RAWBucket_AFull_Counter( 6)<= c_RAW_depth + int_RAWBucketArray_WrPo( 6)  -  int_RAWBucketArray_RdPo( 6);
  int_RAWBucket_AFull_Counter( 7)<= c_RAW_depth + int_RAWBucketArray_WrPo( 7)  -  int_RAWBucketArray_RdPo( 7);
  int_RAWBucket_AFull_Counter( 8)<= c_RAW_depth + int_RAWBucketArray_WrPo( 8)  -  int_RAWBucketArray_RdPo( 8);
  int_RAWBucket_AFull_Counter( 9)<= c_RAW_depth + int_RAWBucketArray_WrPo( 9)  -  int_RAWBucketArray_RdPo( 9);
  int_RAWBucket_AFull_Counter(10)<= c_RAW_depth + int_RAWBucketArray_WrPo(10)  -  int_RAWBucketArray_RdPo(10);
  int_RAWBucket_AFull_Counter(11)<= c_RAW_depth + int_RAWBucketArray_WrPo(11)  -  int_RAWBucketArray_RdPo(11);
  int_RAWBucket_AFull_Counter(12)<= c_RAW_depth + int_RAWBucketArray_WrPo(12)  -  int_RAWBucketArray_RdPo(12);
  int_RAWBucket_AFull_Counter(13)<= c_RAW_depth + int_RAWBucketArray_WrPo(13)  -  int_RAWBucketArray_RdPo(13);
  int_RAWBucket_AFull_Counter(14)<= c_RAW_depth + int_RAWBucketArray_WrPo(14)  -  int_RAWBucketArray_RdPo(14);
  int_RAWBucket_AFull_Counter(15)<= c_RAW_depth + int_RAWBucketArray_WrPo(15)  -  int_RAWBucketArray_RdPo(15);
  int_RAWBucket_AFull_Counter(16)<= c_RAW_depth + int_RAWBucketArray_WrPo(16)  -  int_RAWBucketArray_RdPo(16);
  int_RAWBucket_AFull_Counter(17)<= c_RAW_depth + int_RAWBucketArray_WrPo(17)  -  int_RAWBucketArray_RdPo(17);
  int_RAWBucket_AFull_Counter(18)<= c_RAW_depth + int_RAWBucketArray_WrPo(18)  -  int_RAWBucketArray_RdPo(18);
  int_RAWBucket_AFull_Counter(19)<= c_RAW_depth + int_RAWBucketArray_WrPo(19)  -  int_RAWBucketArray_RdPo(19);
  int_RAWBucket_AFull_Counter(20)<= c_RAW_depth + int_RAWBucketArray_WrPo(20)  -  int_RAWBucketArray_RdPo(20);
  int_RAWBucket_AFull_Counter(21)<= c_RAW_depth + int_RAWBucketArray_WrPo(21)  -  int_RAWBucketArray_RdPo(21);

  int_COLUMNBucket_AFull_Counter( 0)<= c_COLUMN_depth + int_COLUMNBucketArray_WrPo( 0)  -  int_COLUMNBucketArray_RdPo( 0);
  int_COLUMNBucket_AFull_Counter( 1)<= c_COLUMN_depth + int_COLUMNBucketArray_WrPo( 1)  -  int_COLUMNBucketArray_RdPo( 1);
  int_COLUMNBucket_AFull_Counter( 2)<= c_COLUMN_depth + int_COLUMNBucketArray_WrPo( 2)  -  int_COLUMNBucketArray_RdPo( 2);
  int_COLUMNBucket_AFull_Counter( 3)<= c_COLUMN_depth + int_COLUMNBucketArray_WrPo( 3)  -  int_COLUMNBucketArray_RdPo( 3);

  
  -- shold be changed to better way. not good.
  int_prioraw_add <= 0 when prioraw_add = X"000000" else
                     0 when prioraw_add = X"000001" else
                     1 when prioraw_add = X"000002" else                  
                     2 when prioraw_add = X"000004" else
                     3 when prioraw_add = X"000008" else                  
                     4 when prioraw_add = X"000010" else
                     5 when prioraw_add = X"000020" else                  
                     6 when prioraw_add = X"000040" else
                     7 when prioraw_add = X"000080" else                  
                     8 when prioraw_add = X"000100" else
                     9 when prioraw_add = X"000200" else                  
                     10 when prioraw_add = X"000400" else
                     11 when prioraw_add = X"000800" else                  
                     12 when prioraw_add = X"001000" else
                     13 when prioraw_add = X"002000" else                  
                     14 when prioraw_add = X"004000" else
                     15 when prioraw_add = X"008000" else                  
                     16 when prioraw_add = X"010000" else
                     17 when prioraw_add = X"020000" else                  
                     18 when prioraw_add = X"040000" else
                     19 when prioraw_add = X"080000" else                  
                     20 when prioraw_add = X"100000" else  
                     21 when prioraw_add = X"200000" else  -- need to stop exact size. 
                     0;

  int_priocolumn_add <= 0 when priocolumn_add = X"0" else
                        0 when priocolumn_add = X"1" else
                        1 when priocolumn_add = X"2" else                  
                        2 when priocolumn_add = X"4" else
                        3 when priocolumn_add = X"8" else                  
                        0;
-------------------------------------------------------------------------------
-- Main code Start
-------------------------------------------------------------------------------
  infifo_rd_en <= '0' when (infifo_empty='1' or stopraw_read='1' ) else '1'; 
  --infifo_rd_en <= '1';
  bufifo_rd_en <= '0' when (bufifo_empty='1' or stopraw_read='1' ) else '1';


 main_sorting_process : process(clk, rst)
  
  variable v : integer range 0 to 5;
  variable vv : integer range 0 to 5;
  
  begin
---------------------------------------------------------------------------
-- Reset
---------------------------------------------------------------------------
    if rising_edge(clk) then
      if (rst = '1') then
        --current_s <= s0;
	  int_module_id_wr_raw <= 0;
        int_module_id_rd_raw <= 0;                
        int_module_id_wr_column <= 0;
        int_module_id_rd_column <= 0;                
        write_done_RAW <= '0';
        write_done_COLUMN <= '0';
        write_done_RAW_two <= '0';
        write_done_COLUMN_two <= '0';
        pre_write_done_RAW <= '0';
        pre_write_done_COLUMN <= '0';
--        read_done_RAW <= '0';         -- went to simul
--        read_done_COLUMN <= '0';      
        int_nModRAWPac <=0;
        int_nModCOLUMNPac <=0;        
--         indata_wSSID_dv<='0';
--         indata_wSSID<=(others => '0');
--         indata_wSSID_dv_reg0<='0';
--         indata_wSSID_reg0<=(others => '0');
        indata_wSSID_dv_reg1<='0';
        indata_wSSID_reg1<=(others => '0');
        indata_wSSID_dv_reg2<='0';
        indata_wSSID_reg2<=(others => '0');
        indata_wSSID_AfterRAWSort_dv<='0';
        indata_wSSID_AfterRAWSort<=(others => '0');
        indata_wSSID_AfterRAWSort_dv_reg0<='0';
        indata_wSSID_AfterRAWSort_reg0<=(others => '0');
        indata_wSSID_AfterCOLUMNSort_dv<='0';
        indata_wSSID_AfterCOLUMNSort<=(others => '0');
        reading_raw<='0';
        reading_column<='0';

        -- Reset for the arrays
        for jj in 0 to 21 loop
          int_RAWBucketArray_RdPo(jj)<=0;
          int_RAWBucketArray_WrPo(jj)<=0;           
        end loop;
        for kk in 0 to 3 loop
          int_COLUMNBucketArray_RdPo(kk)<=0;
          int_COLUMNBucketArray_WrPo(kk)<=0;           
        end loop;

        for ii in 0 to 3 loop           -- event
          RAWDataExistVector(ii)<="0000000000000000000000";        --          
          COLUMNDataExistVector(ii)<="0000";
          for jj in 0 to 21 loop
            RAWCounterArrayVector(ii)(jj) <= "0000000000";
          end loop;
          for kk in 0 to 3 loop
            COLUMNCounterArrayVector(ii)(kk)<="000000000000";
          end loop;
        end loop;

-------------------------------------------------------------------------------
-- IF Not Reset
-------------------------------------------------------------------------------
      else
        
        infifo_dv <= infifo_rd_en;
        indata_wSSID_dv <= bufifo_rd_en;
-------------------------------------------------------------------------------
-- trailer  
-------------------------------------------------------------------------------
        -- case :01 l1id 
        if(infifo_dv = '1' and  infifo_data(31 downto 0) = X"b0f00000") then
	infifo_data_reg0<=infifo_data;
	infifo_data_dv_reg0<=infifo_dv;
	addra_RAW<="000000000";
	addra_COLUMN<="000000000"; 
	v := 1;
	elsif (infifo_dv = '1' and v < 5 and v > 0) then
	if (infifo_data_reg0 = infifo_data) then
	v := v;
	else
	   v := v + 1;
	   end if;
	   infifo_data_reg0<=infifo_data;
	   infifo_data_dv_reg0<=infifo_dv;
	   addra_RAW<="000000000";
	   addra_COLUMN<="000000000"; 
--	   if  (IN_HIT_DATA_VALID = '1') then
--	   end if;
        elsif(infifo_dv ='1' and infifo_data(31 downto 0)=X"FF1234FF" ) then
	   infifo_data_reg0<=infifo_data;
	   infifo_data_dv_reg0<=infifo_dv;
	   addra_RAW<="000000000";
	   addra_COLUMN<="000000000"; 
	   v := 2;
	     elsif(infifo_dv = '1' and infifo_data(31 downto 0)=X"e0da0000") then
	     infifo_data_reg0<=infifo_data;
	     infifo_data_dv_reg0<=infifo_dv;
            addra_RAW<="111111111";       -- for the end mark
            addra_COLUMN<="111111111";
	       vv := 1; 
	       elsif (infifo_dv = '1' and vv < 5 and vv > 0) then
	       if (infifo_data_reg0 = infifo_data) then
	       vv := vv;
	       else
	          vv := vv + 1;
		  end if;
		     infifo_data_reg0<=infifo_data;
		     infifo_data_dv_reg0<=infifo_dv;
		     addra_RAW<="111111111";
		     addra_COLUMN<="111111111"; 
		     
		     elsif (infifo_dv = '1' and infifo_data(31 downto 0)=X"e0f00000") then
		        infifo_data_reg0<=infifo_data;
			infifo_data_dv_reg0<=infifo_dv;
			addra_RAW<="111111111";       -- for the end mark
            addra_COLUMN<="111111111";
--	    if  (IN_HIT_DATA_VALID = '1') then
--	    end if;

-------------------------------------------------------------------------------
-- module data        (module set to SSid  0)
-------------------------------------------------------------------------------
        elsif(infifo_dv = '1' and infifo_data(31) = '1') then
          infifo_data_reg0<=infifo_data;
          infifo_data_dv_reg0<=infifo_dv;
          addra_RAW<="000000000";
          addra_COLUMN<="000000000";
-------------------------------------------------------------------------------
-- hit data
-------------------------------------------------------------------------------
        elsif (infifo_dv = '1' and infifo_data(31) = '0') then  --pixel cluster
          infifo_data_reg0<=infifo_data;
          infifo_data_dv_reg0<=infifo_dv;
          addra_RAW<=infifo_data(11 downto 3);
          addra_COLUMN<=infifo_data(27 downto 19);

        else
          infifo_data_reg0<= (others => '0');
          infifo_data_dv_reg0<='0';
        end if;  -- end of valid input data

	     infifo_data_reg1<=infifo_data_reg0;  -- wait the LUT
        infifo_data_dv_reg1<=infifo_data_dv_reg0;-- wait the LUT
	  
	    SSID_COLUMN <= addra_COLUMN (8 downto 5);
	      SSID_RAW <= addra_RAW(8 downto 3);

        indata_wSSID_reg0<=SSID_RAW & SSID_COLUMN & infifo_data_reg1;
        indata_wSSID_dv_reg0<=infifo_data_dv_reg1;       

-------------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
-- RAW Sorting
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

-----------------------------------------------------------------------
-- Valid indata w SSID
-----------------------------------------------------------------------
        if(indata_wSSID_dv ='1') then
---------------------------------------------------------------------
-- if trailer (40000000) or trailer and end event (40000 then 10 l1id) , count up module n and reset older one
---------------------------------------------------------------------
          if( ((indata_wSSID(31 downto 0)=X"e0da0000") ) and int_nModRAWPac > 1 ) then  --
            pre_write_done_RAW<='1';

          -- normal 
          elsif(( ((indata_wSSID(31 downto 0)=X"e0da0000") )and int_nModRAWPac < 2) or            
                 ( pre_write_done_RAW = '1' and int_nModRAWPac < 2) ) then
            pre_write_done_RAW<= '0';
            write_done_RAW<='1';
            if(write_done_RAW='1') then
              write_done_RAW_two<='1';
            end if;
            
            if(int_module_id_wr_raw = 3) then
              int_module_id_wr_raw <= 0;
              for jj in 0 to 21 loop
                RAWCounterArrayVector(0)(jj) <= "0000000000";
                RAWDataExistVector(0)<= (others =>'0');
              end loop;
            else
              int_module_id_wr_raw <= int_module_id_wr_raw+1;
              for jj in 0 to 21 loop
                RAWCounterArrayVector(int_module_id_wr_raw+1)(jj) <= "0000000000";
                RAWDataExistVector(int_module_id_wr_raw+1)<= (others =>'0');
              end loop;
            end if;
          -- not done
          else 
            write_done_RAW<='0';
--            RAWDataExistVector(int_module_id_wr_raw)<= RAWDataExistVector(int_module_id_wr_raw) OR shifted_data_raw(21 downto 0);
          end if;                       -- end of trailer


---------------------------------------------------------------------
-- Fill the data to RAW bucket and priority box and dataexist array
---------------------------------------------------------------------
          -- 50 downto 46 is 5 bits (currently) RAW SSID 
          if(pre_write_done_RAW/='1') then
            if(int_RAWBucketArray_WrPo(int_ssid_raw)=c_RAW_depth) then
              int_RAWBucketArray_WrPo(int_ssid_raw)<=0;
            else
              int_RAWBucketArray_WrPo(int_ssid_raw)<=int_RAWBucketArray_WrPo(int_ssid_raw)+1;
            end if;
            RAWBucketArray(int_RAWBucketArray_WrPo(int_ssid_raw)) (int_ssid_raw)<=indata_wSSID; --          
            RAWCounterArrayVector(int_module_id_wr_raw)(int_ssid_raw) <= std_logic_vector(unsigned(RAWCounterArrayVector(int_module_id_wr_raw)(int_ssid_raw)) + 1);
--            nbit_raw<=int_ssid_raw;
            RAWDataExistVector(int_module_id_wr_raw)<= RAWDataExistVector(int_module_id_wr_raw) OR shifted_data_raw(21 downto 0);
          end if;
          -- special (not good but no way...)
        else                            -- if not indata dv
          if(pre_write_done_RAW = '1' and int_nModRAWPac < 2)then
            pre_write_done_RAW<='0';
            write_done_RAW<='1';

          if(int_module_id_wr_raw = 3) then
            int_module_id_wr_raw <= 0;
            for jj in 0 to 21 loop
              RAWCounterArrayVector(0)(jj) <= "0000000000";
              RAWDataExistVector(0)<= (others =>'0');
            end loop;
          else
            int_module_id_wr_raw <= int_module_id_wr_raw+1;
            for jj in 0 to 21 loop
              RAWCounterArrayVector(int_module_id_wr_raw+1)(jj) <= "0000000000";
              RAWDataExistVector(int_module_id_wr_raw+1)<= (others =>'0');
            end loop;
          end if;
          end if;
        end if; -- end indata_wSSID_dv 
        
---------------------------------------------------------------------
-- Read from RAW Bucketarray
---------------------------------------------------------------------
        if(int_nModRAWPac > 0 and stopraw_write/='1') then         -- start read out (There are more than 1 module in backet)
          -- set hit existing vector for a module
          -- setup the prio normal case
          if(reading_raw='0' and unsigned(RAWCounterArrayVector(int_module_id_rd_raw)(int_prioraw_add))/=1)then
            prioraw_in(21 downto 0) <= RAWDataExistVector(int_module_id_rd_raw);
            reading_raw<='1';
            -- setup the prio with SS0 is only header, skip SS0 to read with no delay 
          elsif(reading_raw='0' and unsigned(RAWCounterArrayVector(int_module_id_rd_raw)(int_prioraw_add))=1)then
            prioraw_in(21 downto 0) <= std_logic_vector(unsigned(RAWDataExistVector(int_module_id_rd_raw)) - 1);
            reading_raw<='1';
          -- read in the module
          elsif(reading_raw = '1' and unsigned(RAWCounterArrayVector(int_module_id_rd_raw)(int_prioraw_add))=1)then
            -- change bucket
            prioraw_in <= std_logic_vector(unsigned(prioraw_in) - unsigned(prioraw_add));
            if(int_prioraw_add=21) then
              reading_raw<='0';
              -- change module
              if(int_module_id_rd_raw=3) then
                int_module_id_rd_raw<=0;
              else  
                int_module_id_rd_raw<=int_module_id_rd_raw+1;
              end if;
            end if;
          end if;                       -- reading_raw 
          -- isolated trailer case. notime to find the upper. not good but no way
          if(reading_raw='0' and RAWCounterArrayVector(int_module_id_rd_raw)(int_prioraw_add)(0)='0')then
            indata_wSSID_AfterRAWSort_reg0<="000000000010111110111011111111101011001110"; --& X"beefface";
            indata_wSSID_AfterRAWSort_dv_reg0<='0';
          else
            -- output and read pointer for the bucket
            indata_wSSID_AfterRAWSort_reg0<=RAWBucketArray(int_RAWBucketArray_RdPo(int_prioraw_add))(int_prioraw_add);
            indata_wSSID_AfterRAWSort_dv_reg0<='1';
            -- read point
            RAWCounterArrayVector(int_module_id_rd_raw)(int_prioraw_add)
              <= std_logic_vector(unsigned(RAWCounterArrayVector(int_module_id_rd_raw)(int_prioraw_add))-1);
            if(int_RAWBucketArray_RdPo(int_prioraw_add)=c_RAW_depth) then
              int_RAWBucketArray_RdPo(int_prioraw_add)<=0;
            else
              int_RAWBucketArray_RdPo(int_prioraw_add)<=int_RAWBucketArray_RdPo(int_prioraw_add)+1;
            end if;

          end if;
        else 
          indata_wSSID_AfterRAWSort_reg0<="000000000000011101000111100001110100011110";--X"00000" & X"1d1e1d1e";
          indata_wSSID_AfterRAWSort_dv_reg0<='0';
        end if;                         -- end int_nmodrawpac

-------------------------------------------------------------------------------
-- counter for the existing module for the each backet
-------------------------------------------------------------------------------        
        if( (write_done_RAW_two = '1' or write_done_RAW = '1') and read_done_RAW = '0') then
          int_nModRAWPac <= int_nModRAWPac + 1;
        elsif(write_done_RAW_two = '0' and write_done_RAW = '0' and read_done_RAW = '1') then
          int_nModRAWPac <= int_nModRAWPac - 1;
        end if;
        -- to back 0, soon after count. n.b. hold freeze confule that.
        if(write_done_RAW='1')then
          write_done_RAW<='0';
        end if;

        if(write_done_RAW_two='1') then
          write_done_RAW_two<='0';
        end if;          

-------------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
-- connection with reg (maybe we can remove when  column trailer setting improved.
-- 1 clk loss
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
          indata_wSSID_AfterRAWSort   <= indata_wSSID_AfterRAWSort_reg0;
          indata_wSSID_AfterRAWSort_dv<= indata_wSSID_AfterRAWSort_dv_reg0;
-------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- COLUMN Sorting
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
        if(indata_wSSID_AfterRAWSort_dv='1') then
---------------------------------------------------------------------
-- if trailer (40000000) or trailer and end event (40000 then 10 l1id) , count up module n and reset older one
---------------------------------------------------------------------
          if( (((indata_wSSID(31 downto 0)=X"e0da0000"))) and int_nModCOLUMNPac > 1 ) then  --
 --         if ((indata_wSSID(31)= '1') and int_nModCOLUMNPac > 1 ) then
 pre_write_done_COLUMN<='1';

          -- normal 
         elsif( (((indata_wSSID(31 downto 0)=X"e0da0000")) and int_nModCOLUMNPac < 2) or            
                 ( pre_write_done_COLUMN = '1' and int_nModCOLUMNPac < 2) ) then
		   
            pre_write_done_COLUMN<='0';
            write_done_COLUMN<='1';

            if(write_done_COLUMN='1') then
              write_done_COLUMN_two<='1';
            end if;


            if(int_module_id_wr_column = 3) then  -- check
              int_module_id_wr_column <= 0;
              for jj in 0 to 3 loop
                COLUMNCounterArrayVector(0)(jj) <= (others =>'0');
                COLUMNDataExistVector(0)<= (others =>'0');
              end loop;
            else
              int_module_id_wr_column <= int_module_id_wr_column+1;
              for jj in 0 to 3 loop
                COLUMNCounterArrayVector(int_module_id_wr_column+1)(jj) <= (others =>'0');
                COLUMNDataExistVector(int_module_id_wr_column+1)<= (others =>'0');
              end loop;
            end if;
            -- not done
          else 
            write_done_COLUMN<='0';
--            COLUMNDataExistVector(int_module_id_wr_column)<= COLUMNDataExistVector(int_module_id_wr_column) OR shifted_data_column(3 downto 0);
          end if;                       -- end of trailer
----kokomade de monndai
---------------------------------------------------------------------
-- Fill the data to COLUMN bucket and priority box and dataexist array
---------------------------------------------------------------------
        -- 50 downto 46 is 5 bits (currently) COLUMN SSID 
          if(pre_write_done_COLUMN/='1') then
            if(int_COLUMNBucketArray_WrPo(int_ssid_column)=c_COLUMN_depth) then
              int_COLUMNBucketArray_WrPo(int_ssid_column)<=0;
            else
              int_COLUMNBucketArray_WrPo(int_ssid_column)<=int_COLUMNBucketArray_WrPo(int_ssid_column)+1;
            end if;
            COLUMNBucketArray(int_COLUMNBucketArray_WrPo(int_ssid_column)) (int_ssid_column)<=indata_wSSID_AfterRAWSort; --          
            COLUMNCounterArrayVector(int_module_id_wr_column)(int_ssid_column) <= std_logic_vector(unsigned(COLUMNCounterArrayVector(int_module_id_wr_column)(int_ssid_column)) + 1);
--            nbit_column<=int_ssid_column;
            COLUMNDataExistVector(int_module_id_wr_column)<= COLUMNDataExistVector(int_module_id_wr_column) OR shifted_data_column(3 downto 0);
          end if;                         
          -- special (not good but no way...)
        else                            -- if not indata dv
          if(pre_write_done_COLUMN = '1' and int_nModCOLUMNPac < 2)then
            pre_write_done_COLUMN<='0';
            write_done_COLUMN<='1';

          if(int_module_id_wr_column = 3) then  -- check
            int_module_id_wr_column <= 0;
            for jj in 0 to 3 loop
              COLUMNCounterArrayVector(0)(jj) <= (others =>'0');
              COLUMNDataExistVector(0)<= (others =>'0');
            end loop;
          else
            int_module_id_wr_column <= int_module_id_wr_column+1;
            for jj in 0 to 3 loop
              COLUMNCounterArrayVector(int_module_id_wr_column+1)(jj) <= (others =>'0');
              COLUMNDataExistVector(int_module_id_wr_column+1)<= (others =>'0');
            end loop;
          end if;
          end if;
        end if;                        -- end indata dvv
---------------------------------------------------------------------
-- Read from COLUMN Bucketarray
---------------------------------------------------------------------
      if(int_nModCOLUMNPac > 0 and stopcolumn_write/='1') then         -- start read out (There are more than 1 module in backet)
        -- setup the prio
        if(reading_column='0'and unsigned(COLUMNCounterArrayVector(int_module_id_rd_column)(int_priocolumn_add))/=1)then
          priocolumn_in(3 downto 0) <= COLUMNDataExistVector(int_module_id_rd_column);
          reading_column<='1';
        elsif(reading_column='0' and unsigned(COLUMNCounterArrayVector(int_module_id_rd_column)(int_priocolumn_add))=1)then
          priocolumn_in(3 downto 0) <= std_logic_vector(unsigned(COLUMNDataExistVector(int_module_id_rd_column))- 1);
          reading_column<='1';
        elsif(reading_column = '1' and unsigned(COLUMNCounterArrayVector(int_module_id_rd_column)(int_priocolumn_add))=1)then                
          -- change bucket
          priocolumn_in <= std_logic_vector(unsigned(priocolumn_in) - unsigned(priocolumn_add));
          if(int_priocolumn_add=3) then
            reading_column<='0';
            -- change module
            if(int_module_id_rd_column=3) then  --check
              int_module_id_rd_column<=0;
            else 
              int_module_id_rd_column<=int_module_id_rd_column+1;
            end if;
          end if;
        end if;                       -- reading_column 
        -- stupid but no way
        if(reading_column='0' and COLUMNCounterArrayVector(int_module_id_rd_column)(int_priocolumn_add)(0)='0')then
          indata_wSSID_AfterCOLUMNSort<="000000000011011110101011011011111011101111";--X"00000" & X"deadbeef";
          indata_wSSID_AfterCOLUMNSort_dv<='0';
        else
          -- output and read pointer for the bucket
          indata_wSSID_AfterCOLUMNSort<=COLUMNBucketArray(int_COLUMNBucketArray_RdPo(int_priocolumn_add))(int_priocolumn_add);
          indata_wSSID_AfterCOLUMNSort_dv<='1';
          -- read point
          COLUMNCounterArrayVector(int_module_id_rd_column)(int_priocolumn_add)
            <= std_logic_vector(unsigned(COLUMNCounterArrayVector(int_module_id_rd_column)(int_priocolumn_add))-1);
          if(int_COLUMNBucketArray_RdPo(int_priocolumn_add)=c_COLUMN_depth) then
            int_COLUMNBucketArray_RdPo(int_priocolumn_add)<=0;
          else
            int_COLUMNBucketArray_RdPo(int_priocolumn_add)<=int_COLUMNBucketArray_RdPo(int_priocolumn_add)+1;
          end if;
        end if;
      else 
        indata_wSSID_AfterCOLUMNSort<="000000000000011101000111100001110100011110";--X"00000" & X"1d1e1d1e";
        indata_wSSID_AfterCOLUMNSort_dv<='0';
      end if;                         -- end int_nmodcolumnpac
-------------------------------------------------------------------------------
-- counter for the existing module for the each backet
-------------------------------------------------------------------------------        
        if( (write_done_COLUMN_two = '1' or write_done_COLUMN = '1') and read_done_COLUMN = '0') then
--      if(write_done_COLUMN = '1' and read_done_COLUMN = '0') then
        int_nModCOLUMNPac <= int_nModCOLUMNPac + 1;
        elsif(write_done_COLUMN_two = '0' and write_done_COLUMN = '0' and read_done_COLUMN = '1') then
--      elsif(write_done_COLUMN = '0' and read_done_COLUMN = '1') then
        int_nModCOLUMNPac <= int_nModCOLUMNPac - 1;
--       else    
--         int_nModCOLUMNPac <= int_nModCOLUMNPac;  -- temp new 
      end if;
      -- to back 0, soon after count. n.b. hold freeze confule that.
      if(write_done_COLUMN='1') then
        write_done_COLUMN<='0';
      end if;
        if(write_done_COLUMN_two='1') then
          write_done_COLUMN_two<='0';
        end if;          

-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Fill to the final output  -- 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

      OUT_HIT_DATA<=indata_wSSID_AfterCOLUMNSort(31 downto 0);  -- real output 
      OUT_HIT_DATA_VALID<=indata_wSSID_AfterCOLUMNSort_dv;  -- real output

      end if;
      end if;
      end process main_sorting_process;
      
      
end Behavioral;
-- eof