/*
 * $Id: Parameters.cpp 117 2009-05-16 14:42:39Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Commit_unit/include/Parameters.h"
#include "Behavioural/include/Allocation.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_nb_inst_decod                 ,
			  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              ,
                          uint32_t            nb_thread                          ,
                          uint32_t         ** translate_num_context_to_num_thread,
                          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              ;
    _nb_thread                           = nb_thread                          ;
    _translate_num_context_to_num_thread = translate_num_context_to_num_thread;

    _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           = 0;
    _mask_num_bank            = gen_mask<Tpacket_t>(log2(_nb_bank));
    _shift_num_slot           = log2(_nb_bank);
//  _mask_num_slot            = gen_mask<Tpacket_t>(log2(_size_bank));

    _have_port_rename_unit_id = _size_rename_unit_id > 0;

    ALLOC2(_array_size_depth,uint32_t,_nb_front_end,_nb_context [it1]);
    for (uint32_t i=0; i<_nb_front_end; 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();

    ALLOC1(_have_thread,bool,_nb_thread);
    for (uint32_t i=0; i<_nb_thread; i++)
      _have_thread[i] = false;
    for (uint32_t i=0; i<_nb_front_end; i++)
      for (uint32_t j=0; j<_nb_context [i]; j++)
        _have_thread[_translate_num_context_to_num_thread [i][j]] = true;

    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;
        _size_nb_inst_decod       = size_nb_inst_decod;
        
        _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);

    DELETE1(_have_thread     ,_nb_thread);
    DELETE2(_array_size_depth,_nb_front_end,_nb_context [it1]);

    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              
