/*
 * $Id: Parameters.cpp 101 2009-01-15 17:19:08Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Register_unit/include/Parameters.h"

namespace morpheo {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace register_unit {


#undef  FUNCTION
#define FUNCTION "Register_unit::Parameters"
  Parameters::Parameters (uint32_t    nb_ooo_engine            ,
			  uint32_t    size_general_data        ,
			  uint32_t    size_special_data        ,
			  uint32_t    nb_gpr_read              ,
			  uint32_t    nb_gpr_write             ,
			  uint32_t    nb_gpr_bank              ,
			  uint32_t    nb_gpr_port_read_by_bank ,
			  uint32_t    nb_gpr_port_write_by_bank,
			  uint32_t    nb_spr_read              ,
			  uint32_t    nb_spr_write             ,
			  uint32_t    nb_spr_bank              ,
			  uint32_t    nb_spr_port_read_by_bank ,
			  uint32_t    nb_spr_port_write_by_bank,
			  uint32_t  * nb_general_register      ,
			  uint32_t  * nb_special_register      ,
			  uint32_t  * nb_inst_insert_rob       ,
			  uint32_t  * nb_inst_retire_rob       ,
                          bool        is_toplevel              )
  {
    log_printf(FUNC,Register_unit,FUNCTION,"Begin");


    _nb_ooo_engine             = nb_ooo_engine            ;
    _nb_gpr_read               = nb_gpr_read              ;
    _nb_gpr_write              = nb_gpr_write             ;
    _nb_gpr_bank               = nb_gpr_bank              ;
    _nb_gpr_port_read_by_bank  = nb_gpr_port_read_by_bank ;
    _nb_gpr_port_write_by_bank = nb_gpr_port_write_by_bank;
    _nb_spr_read               = nb_spr_read              ;
    _nb_spr_write              = nb_spr_write             ;
    _nb_spr_bank               = nb_spr_bank              ;
    _nb_spr_port_read_by_bank  = nb_spr_port_read_by_bank ;
    _nb_spr_port_write_by_bank = nb_spr_port_write_by_bank;
    _nb_general_register       = nb_general_register      ;
    _nb_special_register       = nb_special_register      ;
    _nb_inst_insert_rob        = nb_inst_insert_rob       ;
    _nb_inst_retire_rob        = nb_inst_retire_rob       ;

    _size_gpr_address = log2(nb_general_register [0]);

    for (uint32_t i=1; i<nb_ooo_engine; i++)
      {
	uint32_t new_size = log2(nb_general_register [i]);
	if (new_size > _size_gpr_address)
	  _size_gpr_address = new_size;
      }

    _size_spr_address = log2(nb_special_register [0]);

    for (uint32_t i=1; i<nb_ooo_engine; i++)
      {
	uint32_t new_size = log2(nb_special_register [i]);
	if (new_size > _size_spr_address)
	  _size_spr_address = new_size;
      }

    _param_gpr         = new morpheo::behavioural::generic::registerfile::Parameters * [_nb_ooo_engine];
    _param_gpr_status  = new morpheo::behavioural::generic::registerfile::Parameters * [_nb_ooo_engine];
    _param_spr         = new morpheo::behavioural::generic::registerfile::Parameters * [_nb_ooo_engine];
    _param_spr_status  = new morpheo::behavioural::generic::registerfile::Parameters * [_nb_ooo_engine];
    
    __param_gpr        = new morpheo::behavioural::generic::registerfile::registerfile_multi_banked::Parameters * [_nb_ooo_engine];
    __param_gpr_status = new morpheo::behavioural::generic::registerfile::registerfile_monolithic  ::Parameters * [_nb_ooo_engine];
    __param_spr        = new morpheo::behavioural::generic::registerfile::registerfile_multi_banked::Parameters * [_nb_ooo_engine];
    __param_spr_status = new morpheo::behavioural::generic::registerfile::registerfile_monolithic  ::Parameters * [_nb_ooo_engine];
    
    for (uint32_t i=0; i<_nb_ooo_engine; i++)
      {
        Tcrossbar_t crossbar = PARTIAL_CROSSBAR;
        
        __param_gpr        [i] = new morpheo::behavioural::generic::registerfile::registerfile_multi_banked::Parameters 
          (_nb_gpr_read              ,
           _nb_gpr_write             ,
           _nb_general_register[i]   ,
            size_general_data        ,
           _nb_gpr_bank              ,
           _nb_gpr_port_read_by_bank ,
           _nb_gpr_port_write_by_bank,
           crossbar                  );
        
        __param_gpr_status [i] = new morpheo::behavioural::generic::registerfile::registerfile_monolithic  ::Parameters 
          (_nb_gpr_read ,
//         _nb_gpr_write+_nb_inst_insert_rob[i]+2*_nb_inst_retire_rob[i],
           _nb_gpr_write+_nb_inst_insert_rob[i],
           0,
           nb_general_register[i],
           1,
           "1");
        
        __param_spr        [i] = new morpheo::behavioural::generic::registerfile::registerfile_multi_banked::Parameters 
          (_nb_spr_read              ,
           _nb_spr_write             ,
           _nb_special_register[i]   ,
            size_special_data        ,
           _nb_spr_bank              ,
           _nb_spr_port_read_by_bank ,
           _nb_spr_port_write_by_bank,
           crossbar                  );
        
        __param_spr_status [i] = new morpheo::behavioural::generic::registerfile::registerfile_monolithic  ::Parameters 
          (_nb_spr_read ,
//         _nb_spr_write+_nb_inst_insert_rob[i]+2*_nb_inst_retire_rob[i],
           _nb_spr_write+_nb_inst_insert_rob[i],
           0,
           nb_special_register[i],
           1,
           "1");	 
        
        _param_gpr        [i] = new morpheo::behavioural::generic::registerfile::Parameters (__param_gpr        [i]);
        _param_gpr_status [i] = new morpheo::behavioural::generic::registerfile::Parameters (__param_gpr_status [i]);
        _param_spr        [i] = new morpheo::behavioural::generic::registerfile::Parameters (__param_spr        [i]);
        _param_spr_status [i] = new morpheo::behavioural::generic::registerfile::Parameters (__param_spr_status [i]);
      }
   
    _param_glue       = new morpheo::behavioural::core::multi_execute_loop::execute_loop::register_unit::register_unit_glue::Parameters  (_nb_ooo_engine        ,
                                                                                                                                           size_general_data    ,
                                                                                                                                           size_special_data    ,
                                                                                                                                          _nb_gpr_read          ,
                                                                                                                                          _nb_spr_read          ,    
                                                                                                                                          _nb_gpr_write         ,
                                                                                                                                          _nb_spr_write         ,
                                                                                                                                          _nb_inst_insert_rob   ,
                                                                                                                                          _nb_inst_retire_rob   );
    
    test();
    
    if (is_toplevel)
      {
        _size_ooo_engine_id        = log2(nb_ooo_engine);
        _size_general_data         = size_general_data;
        _size_special_data         = size_special_data;
        
        _have_port_ooo_engine_id   = _size_ooo_engine_id > 0;

        copy();
      }
    
   log_printf(FUNC,Register_unit,FUNCTION,"End");
  };
  
// #undef  FUNCTION
// #define FUNCTION "Register_unit::Parameters (copy)"
//   Parameters::Parameters (Parameters & param):
//     _nb_ooo_engine             (param._nb_ooo_engine            ),
//     _size_general_data         (param._size_general_data        ),
//     _size_special_data         (param._size_special_data        ),
//     _nb_gpr_read               (param._nb_gpr_read              ),
//     _nb_gpr_write              (param._nb_gpr_write             ),
//     _nb_gpr_bank               (param._nb_gpr_bank              ),
//     _nb_gpr_port_read_by_bank  (param._nb_gpr_port_read_by_bank ),
//     _nb_gpr_port_write_by_bank (param._nb_gpr_port_write_by_bank),
//     _nb_spr_read               (param._nb_spr_read              ),
//     _nb_spr_write              (param._nb_spr_write             ),
//     _nb_spr_bank               (param._nb_spr_bank              ),
//     _nb_spr_port_read_by_bank  (param._nb_spr_port_read_by_bank ),
//     _nb_spr_port_write_by_bank (param._nb_spr_port_write_by_bank),
//     _nb_general_register       (param._nb_general_register      ),
//     _nb_special_register       (param._nb_special_register      ),
//     _nb_inst_insert_rob        (param._nb_inst_insert_rob       ),
//     _nb_inst_retire_rob        (param._nb_inst_retire_rob       ),
//     _have_port_ooo_engine_id   (param._have_port_ooo_engine_id  )
//   {
//     log_printf(FUNC,Register_unit,FUNCTION,"Begin");

//     _size_gpr_address = param._size_gpr_address;
//     _size_spr_address = param._size_spr_address;

//     __param_gpr        = param.__param_gpr       ;
//     __param_gpr_status = param.__param_gpr_status;
//     __param_spr        = param.__param_spr       ;
//     __param_spr_status = param.__param_spr_status;
//     _param_gpr         = param._param_gpr       ;
//     _param_gpr_status  = param._param_gpr_status;
//     _param_spr         = param._param_spr       ;
//     _param_spr_status  = param._param_spr_status;
//     _param_glue        = param._param_glue      ;

//     test();
//     log_printf(FUNC,Register_unit,FUNCTION,"End");
//   };

#undef  FUNCTION
#define FUNCTION "Register_unit::~Parameters"
  Parameters::~Parameters (void) 
  {
    log_printf(FUNC,Register_unit,FUNCTION,"Begin");

    for (uint32_t i=0; i<_nb_ooo_engine; i++)
      {
        delete _param_gpr         [i];
        delete _param_gpr_status  [i];
        delete _param_spr         [i];
        delete _param_spr_status  [i];
        delete __param_gpr        [i];
        delete __param_gpr_status [i];
        delete __param_spr        [i];
        delete __param_spr_status [i];
      }
    delete [] _param_gpr        ;
    delete [] _param_gpr_status ;
    delete [] _param_spr        ;
    delete [] _param_spr_status ;
    delete [] __param_gpr       ;
    delete [] __param_gpr_status;
    delete [] __param_spr       ;
    delete [] __param_spr_status;
    delete    _param_glue;
    
    log_printf(FUNC,Register_unit,FUNCTION,"End");
  };

#undef  FUNCTION
#define FUNCTION "Register_unit::copy"
  void Parameters::copy (void) 
  {
    log_printf(FUNC,Register_unit,FUNCTION,"Begin");

    for (uint32_t i=0; i<_nb_ooo_engine; i++)
      {
        COPY(__param_gpr        [i]);
        COPY(__param_gpr_status [i]);
        COPY(__param_spr        [i]);
        COPY(__param_spr_status [i]);
      }
    COPY(_param_glue);
    
    log_printf(FUNC,Register_unit,FUNCTION,"End");
  };

}; // end namespace register_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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