/*
 * $Id: Parameters.cpp 88 2008-12-10 18:31:39Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Commit_unit/include/Parameters.h"
#include "Common/include/Max.h"
#include "Common/include/BitManipulation.h"

namespace morpheo {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace commit_unit {


#undef  FUNCTION
#define FUNCTION "Commit_unit::Parameters"
  Parameters::Parameters (uint32_t            nb_front_end            ,
			  uint32_t          * nb_context              ,
			  uint32_t            nb_rename_unit          ,
			  uint32_t            size_queue              ,
			  uint32_t            nb_bank                 ,
			  uint32_t          * nb_inst_insert          ,
			  uint32_t          * nb_inst_retire          ,
			  uint32_t            nb_inst_commit          ,
			  uint32_t            nb_inst_reexecute       ,
			  uint32_t            nb_inst_branch_complete ,
			  uint32_t         ** nb_branch_speculated    ,
			  uint32_t            size_general_data       ,
			  uint32_t            size_store_queue_ptr    ,
			  uint32_t            size_load_queue_ptr     ,
			  uint32_t            size_general_register   ,
			  uint32_t            size_special_register   ,
			  Tpriority_t         priority                ,
			  Tload_balancing_t   load_balancing          ,
			  uint32_t            nb_rename_unit_select   ,
                          bool                is_toplevel):
    _nb_bank_access_commit (1              ),
    _retire_ooo            (RETIRE_IN_ORDER)
  {
    log_begin(Commit_unit,FUNCTION);

    _nb_front_end             = nb_front_end           ;
    _nb_context               = nb_context             ;
    _nb_rename_unit           = nb_rename_unit         ;
    _size_queue               = size_queue             ;
    _nb_bank                  = nb_bank                ;
    _nb_inst_insert           = nb_inst_insert         ;
    _nb_inst_retire           = nb_inst_retire         ;
    _nb_inst_commit           = nb_inst_commit         ;
    _nb_inst_reexecute        = nb_inst_reexecute      ;
    _nb_inst_branch_complete  = nb_inst_branch_complete;
    _nb_branch_speculated     = nb_branch_speculated   ;
    _priority                 = priority               ;
    _load_balancing           = load_balancing         ;
    _nb_rename_unit_select    = nb_rename_unit_select  ;

    _size_rename_unit_id      = log2(_nb_rename_unit);
    _max_nb_context           = max<uint32_t>(_nb_context,_nb_front_end);
    _max_nb_inst_insert       = max<uint32_t>(_nb_inst_insert,_nb_rename_unit);
    _max_nb_inst_retire       = max<uint32_t>(_nb_inst_retire,_nb_rename_unit);
    _size_bank                = _size_queue/_nb_bank;
    _shift_num_bank           = log2(_size_bank);
    _mask_size_bank           = gen_mask<Tpacket_t>(log2(_size_bank));

    _have_port_rename_unit_id = _size_rename_unit_id > 0;

    _array_size_depth               = new uint32_t * [_nb_front_end];
    for (uint32_t i=0; i<_nb_front_end; i++)
      {
	_array_size_depth      [i]      = new uint32_t [_nb_context [i]];
	for (uint32_t j=0; j<_nb_context [i]; j++)
          _array_size_depth      [i][j] = (_nb_branch_speculated [i][j] == 0)?0:log2(_nb_branch_speculated [i][j]);
      }

    test();

    if (is_toplevel)
      {
        _size_front_end_id        = log2(_nb_front_end);
        _size_context_id          = log2(_max_nb_context);
        _size_rob_ptr             = log2(_nb_bank)+log2(_size_bank);
        _size_instruction_address = size_general_data-2;
        _size_store_queue_ptr     = size_store_queue_ptr   ;
        _size_load_queue_ptr      = size_load_queue_ptr    ;
        _size_general_data        = size_general_data      ;
        _size_general_register    = size_general_register  ;
        _size_special_register    = size_special_register  ;
        _size_depth               = max<uint32_t>(_array_size_depth,_nb_front_end,_nb_context);
        _size_nb_inst_commit      = log2(_size_queue)+1;
        
        _have_port_front_end_id   = _size_front_end_id   > 0;
        _have_port_context_id     = _size_context_id     > 0;
        _have_port_rob_ptr        = _size_rob_ptr        > 0;
        _have_port_load_queue_ptr = _size_load_queue_ptr > 0;
        _have_port_depth          = _size_depth          > 0;
	
        copy();
      }

    log_end(Commit_unit,FUNCTION);
  };
  
// #undef  FUNCTION
// #define FUNCTION "Commit_unit::Parameters (copy)"
//   Parameters::Parameters (Parameters & param)
//   {
//     log_begin(Commit_unit,FUNCTION);
//     test();
//     log_end(Commit_unit,FUNCTION);
//   };

#undef  FUNCTION
#define FUNCTION "Commit_unit::~Parameters"
  Parameters::~Parameters (void) 
  {
    log_begin(Commit_unit,FUNCTION);

    for (uint32_t i=0; i<_nb_front_end; i++)
      {
	delete [] _array_size_depth [i];
      }
    delete [] _array_size_depth;

    log_end(Commit_unit,FUNCTION);
  };

#undef  FUNCTION
#define FUNCTION "Commit_unit::copy"
  void Parameters::copy (void) 
  {
    log_begin(Commit_unit,FUNCTION);
    log_end(Commit_unit,FUNCTION);
  };

}; // end namespace commit_unit
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core

}; // end namespace behavioural
}; // end namespace morpheo              
