/*
 * $Id: Instance.cpp 112 2009-03-18 22:36:26Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Configuration/include/Instance.h"
#include "Behavioural/include/Allocation.h"

namespace morpheo {
namespace behavioural {
namespace configuration {

#undef  FUNCTION
#define FUNCTION "Instance::Instance"
  Instance::Instance  (std::string filename, 
                       Generator * generator,
                       behavioural::custom::custom_information_t (*get_custom_information) (void))
  {
    log_begin(Configuration,FUNCTION);

    _name      = "";
    _filename  = filename;

    _list_parameters = new list_parameters_t;
    _list_links      = new list_links_t;
    _list_components = new list_components_t;

    _generator = generator;
    _param     = new Parameters;
    _param->_get_custom_information = get_custom_information;

    fromFile (filename);

    log_end(Configuration,FUNCTION);
  };

#undef  FUNCTION
#define FUNCTION "Instance::~Instance"
  Instance::~Instance () 
  {
    log_begin(Configuration,FUNCTION);

    for (list_parameters_t::iterator it = _list_parameters->begin();
         it != _list_parameters->end();
         ++it)
      delete it->second;
    delete _list_parameters;

    for (list_links_t::iterator it1 = _list_links->begin();
         it1 != _list_links->end();
         ++it1)
      for (list_link_t::iterator it2 = it1->second.begin();
           it2 != it1->second.end();
           ++it2)
        delete it2->second;
    delete _list_links;
    
    for (list_components_t::iterator it1 = _list_components->begin();
         it1 != _list_components->end();
         ++it1)
      for (list_instances_t::iterator it2 = it1->second.begin();
           it2 != it1->second.end();
           ++it2)
        delete it2->second;
    delete _list_components;

    if (_param != NULL) // TEST A ENLEVER
      {
        DELETE2(_param->_link_dcache_port_with_load_store_unit  ,_param->_nb_load_store_unit,_param->_nb_cache_port[it1]);
        DELETE1(_param->_link_icache_port_with_thread           ,_param->_nb_thread);
        DELETE2(_param->_link_thread_and_functionnal_unit       ,_param->_nb_thread,_param->_nb_functionnal_unit);
        DELETE1(_param->_link_load_store_unit_with_thread       ,_param->_nb_thread);
        DELETE2(_param->_link_write_bloc_and_functionnal_unit   ,_param->_nb_write_bloc,_param->_nb_functionnal_unit);
        DELETE2(_param->_link_write_bloc_and_load_store_unit    ,_param->_nb_write_bloc,_param->_nb_load_store_unit);
        DELETE2(_param->_link_read_bloc_and_functionnal_unit    ,_param->_nb_read_bloc,_param->_nb_functionnal_unit);
        DELETE2(_param->_link_read_bloc_and_load_store_unit     ,_param->_nb_read_bloc,_param->_nb_load_store_unit);
        DELETE3(_param->_table_dispatch                         ,_param->_nb_ooo_engine,_param->_nb_inst_issue[it1],_param->_nb_read_bloc);
        DELETE1(_param->_link_rename_bloc_with_front_end        ,_param->_nb_front_end);
        DELETE1(_param->_link_decod_bloc_with_thread            ,_param->_nb_thread);
        DELETE1(_param->_link_execute_unit_with_load_store_unit ,_param->_nb_load_store_unit);
        DELETE1(_param->_link_execute_unit_with_functionnal_unit,_param->_nb_functionnal_unit);
        DELETE1(_param->_link_write_unit_with_write_bloc        ,_param->_nb_write_bloc);
        DELETE1(_param->_link_read_unit_with_read_bloc          ,_param->_nb_read_bloc);
        DELETE1(_param->_link_rename_unit_with_rename_bloc      ,_param->_nb_rename_bloc);
        DELETE1(_param->_link_decod_unit_with_decod_bloc        ,_param->_nb_decod_bloc);
        DELETE1(_param->_link_context_with_thread               ,_param->_nb_thread);
        DELETE1(_param->_read_unit_to_execution_unit_priority   ,_param->_nb_execute_loop);
        DELETE1(_param->_execution_unit_to_write_unit_priority  ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_spr_port_write_by_bank              ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_spr_port_read_by_bank               ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_spr_bank                            ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_gpr_port_write_by_bank              ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_gpr_port_read_by_bank               ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_gpr_bank                            ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_write_unit                          ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_execute_unit                        ,_param->_nb_execute_loop);
        DELETE1(_param->_nb_read_unit                           ,_param->_nb_execute_loop);
        DELETE1(_param->_reexecute_load_balancing               ,_param->_nb_ooo_engine);
        DELETE1(_param->_reexecute_priority                     ,_param->_nb_ooo_engine);
        DELETE1(_param->_size_reexecute_queue                   ,_param->_nb_ooo_engine);
        DELETE1(_param->_issue_load_balancing                   ,_param->_nb_ooo_engine);
        DELETE1(_param->_issue_priority                         ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_issue_queue_bank                    ,_param->_nb_ooo_engine);
        DELETE1(_param->_issue_queue_scheme                     ,_param->_nb_ooo_engine);
        DELETE1(_param->_size_issue_queue                       ,_param->_nb_ooo_engine);
        DELETE1(_param->_commit_load_balancing                  ,_param->_nb_ooo_engine);
        DELETE1(_param->_commit_priority                        ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_re_order_buffer_bank                ,_param->_nb_ooo_engine);
        DELETE1(_param->_size_re_order_buffer                   ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_execute_loop_select                 ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_rename_unit_select                  ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_inst_branch_complete                ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_inst_commit                         ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_inst_reexecute                      ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_inst_issue                          ,_param->_nb_ooo_engine);
        DELETE1(_param->_nb_rename_unit                         ,_param->_nb_ooo_engine); 
        DELETE2(_param->_dir_pht_size_address_share             ,_param->_nb_front_end,3);
        DELETE2(_param->_dir_pht_nb_counter                     ,_param->_nb_front_end,3);
        DELETE2(_param->_dir_pht_size_counter                   ,_param->_nb_front_end,3);
        DELETE2(_param->_dir_have_pht                           ,_param->_nb_front_end,3);
        DELETE2(_param->_dir_bht_nb_shifter                     ,_param->_nb_front_end,3);
        DELETE2(_param->_dir_bht_size_shifter                   ,_param->_nb_front_end,3);
        DELETE2(_param->_dir_have_bht                           ,_param->_nb_front_end,3);
        DELETE1(_param->_dir_predictor_scheme                   ,_param->_nb_front_end);
        DELETE1(_param->_btb_victim_scheme                      ,_param->_nb_front_end);
        DELETE1(_param->_btb_size_counter                       ,_param->_nb_front_end);
        DELETE1(_param->_btb_associativity                      ,_param->_nb_front_end);
        DELETE1(_param->_btb_size_queue                         ,_param->_nb_front_end);
        DELETE1(_param->_nb_inst_branch_update                  ,_param->_nb_front_end);
        DELETE1(_param->_nb_inst_branch_decod                   ,_param->_nb_front_end);
        DELETE1(_param->_nb_inst_branch_predict                 ,_param->_nb_front_end);
        DELETE1(_param->_nb_decod_unit                          ,_param->_nb_front_end);
        DELETE1(_param->_nb_context                             ,_param->_nb_front_end);
        DELETE3(_param->_timing                                 ,_param->_nb_functionnal_unit,MAX_TYPE,MAX_OPERATION);
        DELETE1(_param->_nb_inst_functionnal_unit               ,_param->_nb_functionnal_unit);
        DELETE1(_param->_speculative_load                       ,_param->_nb_load_store_unit);
        DELETE1(_param->_nb_inst_memory                         ,_param->_nb_load_store_unit);
        DELETE1(_param->_nb_cache_port                          ,_param->_nb_load_store_unit);
        DELETE1(_param->_nb_bypass_memory                       ,_param->_nb_load_store_unit);
        DELETE1(_param->_nb_port_check                          ,_param->_nb_load_store_unit);
        DELETE1(_param->_size_speculative_access_queue          ,_param->_nb_load_store_unit);
        DELETE1(_param->_size_load_queue                        ,_param->_nb_load_store_unit);
        DELETE1(_param->_size_store_queue                       ,_param->_nb_load_store_unit);
        DELETE1(_param->_nb_bypass_write                        ,_param->_nb_write_bloc);
        DELETE1(_param->_size_execute_queue                     ,_param->_nb_write_bloc);
        DELETE1(_param->_size_write_queue                       ,_param->_nb_write_bloc);
        DELETE1(_param->_nb_inst_retire_reservation_station     ,_param->_nb_read_bloc);
        DELETE1(_param->_size_reservation_station               ,_param->_nb_read_bloc);
        DELETE1(_param->_size_read_queue                        ,_param->_nb_read_bloc);
//         DELETE1(_param->_size_read_counter                      ,_param->_nb_rename_bloc);
        DELETE1(_param->_nb_rename_unit_bank                    ,_param->_nb_rename_bloc);
        DELETE1(_param->_nb_reg_free                            ,_param->_nb_rename_bloc);
        DELETE1(_param->_nb_special_register                    ,_param->_nb_rename_bloc);
        DELETE1(_param->_nb_general_register                    ,_param->_nb_rename_bloc);
        DELETE1(_param->_rename_select_nb_front_end_select      ,_param->_nb_rename_bloc);
        DELETE1(_param->_rename_select_load_balancing           ,_param->_nb_rename_bloc);
        DELETE1(_param->_rename_select_priority                 ,_param->_nb_rename_bloc);
        DELETE1(_param->_nb_inst_retire                         ,_param->_nb_rename_bloc);
        DELETE1(_param->_nb_inst_insert                         ,_param->_nb_rename_bloc);
        DELETE1(_param->_context_select_load_balancing          ,_param->_nb_decod_bloc);
        DELETE1(_param->_context_select_priority                ,_param->_nb_decod_bloc);
        DELETE1(_param->_nb_context_select                      ,_param->_nb_decod_bloc);
        DELETE1(_param->_nb_inst_decod                          ,_param->_nb_decod_bloc);
        DELETE1(_param->_decod_queue_scheme                     ,_param->_nb_decod_bloc);
        DELETE1(_param->_size_decod_queue                       ,_param->_nb_decod_bloc);
        DELETE1(_param->_ufpt_size_queue                        ,_param->_nb_thread);
        DELETE1(_param->_upt_size_queue                         ,_param->_nb_thread);
        DELETE1(_param->_ras_size_queue                         ,_param->_nb_thread);
        DELETE2(_param->_implement_group                        ,_param->_nb_thread,NB_GROUP);
        DELETE1(_param->_nb_inst_fetch                          ,_param->_nb_thread);
        DELETE1(_param->_size_ifetch_queue                      ,_param->_nb_thread);
       
        delete _param;
      }
    log_end(Configuration,FUNCTION);
  };

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