/*
 * $Id: Update_Prediction_Table_deallocation.cpp 128 2009-06-26 08:43:23Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/include/Update_Prediction_Table.h"
#include "Behavioural/include/Allocation.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace prediction_unit {
namespace update_prediction_table {


#undef  FUNCTION
#define FUNCTION "Update_Prediction_Table::deallocation"
  void Update_Prediction_Table::deallocation (void)
  {
    log_printf(FUNC,Update_Prediction_Table,FUNCTION,"Begin");

    if (_usage & USE_SYSTEMC)
      {
	delete    in_CLOCK ;
	delete    in_NRESET;

        // ~~~~~[ Interface : "predict" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DELETE1_SIGNAL( in_PREDICT_VAL                 ,_param->_nb_inst_predict,1);
        DELETE1_SIGNAL(out_PREDICT_ACK                 ,_param->_nb_inst_predict,1);
        DELETE1_SIGNAL( in_PREDICT_CONTEXT_ID          ,_param->_nb_inst_predict,_param->_size_context_id);
        DELETE1_SIGNAL(out_PREDICT_UPDATE_PREDICTION_ID,_param->_nb_inst_predict,_param->_size_depth);
        DELETE1_SIGNAL( in_PREDICT_BTB_ADDRESS_SRC     ,_param->_nb_inst_predict,_param->_size_instruction_address);
        DELETE1_SIGNAL( in_PREDICT_BTB_ADDRESS_DEST    ,_param->_nb_inst_predict,_param->_size_instruction_address);
        DELETE1_SIGNAL( in_PREDICT_BTB_CONDITION       ,_param->_nb_inst_predict,_param->_size_branch_condition);
        DELETE1_SIGNAL( in_PREDICT_BTB_LAST_TAKE       ,_param->_nb_inst_predict,1);
        DELETE1_SIGNAL( in_PREDICT_BTB_IS_ACCURATE     ,_param->_nb_inst_predict,1);
        DELETE1_SIGNAL( in_PREDICT_DIR_HISTORY         ,_param->_nb_inst_predict,_param->_size_history);
        DELETE1_SIGNAL( in_PREDICT_RAS_ADDRESS         ,_param->_nb_inst_predict,_param->_size_instruction_address);
        DELETE1_SIGNAL( in_PREDICT_RAS_INDEX           ,_param->_nb_inst_predict,_param->_max_size_ras_index);

        // ~~~~~[ Interface : "decod" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DELETE1_SIGNAL( in_DECOD_VAL                 ,_param->_nb_inst_decod,1);
        DELETE1_SIGNAL(out_DECOD_ACK                 ,_param->_nb_inst_decod,1);
        DELETE1_SIGNAL( in_DECOD_CONTEXT_ID          ,_param->_nb_inst_decod,_param->_size_context_id);
        DELETE1_SIGNAL( in_DECOD_BTB_ADDRESS_SRC     ,_param->_nb_inst_decod,_param->_size_instruction_address);
        DELETE1_SIGNAL( in_DECOD_BTB_ADDRESS_DEST    ,_param->_nb_inst_decod,_param->_size_instruction_address);
        DELETE1_SIGNAL( in_DECOD_BTB_CONDITION       ,_param->_nb_inst_decod,_param->_size_branch_condition);
        DELETE1_SIGNAL( in_DECOD_BTB_LAST_TAKE       ,_param->_nb_inst_decod,1);
        DELETE1_SIGNAL( in_DECOD_RAS_ADDRESS         ,_param->_nb_inst_decod,_param->_size_instruction_address);
        DELETE1_SIGNAL( in_DECOD_RAS_INDEX           ,_param->_nb_inst_decod,_param->_max_size_ras_index);
        DELETE1_SIGNAL( in_DECOD_MISS_IFETCH         ,_param->_nb_inst_decod,1);
        DELETE1_SIGNAL( in_DECOD_MISS_DECOD          ,_param->_nb_inst_decod,1);
        DELETE1_SIGNAL( in_DECOD_UPDATE_PREDICTION_ID,_param->_nb_inst_decod,_param->_size_depth);
//      DELETE1_SIGNAL(out_DECOD_DEPTH               ,_param->_nb_inst_decod,_param->_size_depth);
        DELETE1_SIGNAL( in_DECOD_IS_ACCURATE         ,_param->_nb_inst_decod,1);
        DELETE1_SIGNAL(out_DECOD_CAN_CONTINUE        ,_param->_nb_inst_decod,1);

        // ~~~~~[ Interface : "branch_complete" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DELETE1_SIGNAL( in_BRANCH_COMPLETE_VAL            ,_param->_nb_inst_branch_complete,1);
        DELETE1_SIGNAL(out_BRANCH_COMPLETE_ACK            ,_param->_nb_inst_branch_complete,1);
        DELETE1_SIGNAL( in_BRANCH_COMPLETE_CONTEXT_ID     ,_param->_nb_inst_branch_complete,_param->_size_context_id);
        DELETE1_SIGNAL( in_BRANCH_COMPLETE_DEPTH          ,_param->_nb_inst_branch_complete,_param->_size_depth);
        DELETE1_SIGNAL( in_BRANCH_COMPLETE_ADDRESS        ,_param->_nb_inst_branch_complete,_param->_size_instruction_address);
        DELETE1_SIGNAL( in_BRANCH_COMPLETE_NO_SEQUENCE    ,_param->_nb_inst_branch_complete,1);
        DELETE1_SIGNAL(out_BRANCH_COMPLETE_MISS_PREDICTION,_param->_nb_inst_branch_complete,1);
//      DELETE1_SIGNAL(out_BRANCH_COMPLETE_TAKE           ,_param->_nb_inst_branch_complete,1);
//      DELETE1_SIGNAL(out_BRANCH_COMPLETE_ADDRESS_SRC    ,_param->_nb_inst_branch_complete,_param->_size_instruction_address);
//      DELETE1_SIGNAL(out_BRANCH_COMPLETE_ADDRESS_DEST   ,_param->_nb_inst_branch_complete,_param->_size_instruction_address);

	// ~~~~~[ Interface : "branch_event" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DELETE1_SIGNAL(out_BRANCH_EVENT_VAL              ,_param->_nb_context,1);
        DELETE1_SIGNAL( in_BRANCH_EVENT_ACK              ,_param->_nb_context,1);
//      DELETE1_SIGNAL(out_BRANCH_EVENT_CONTEXT_ID       ,_param->_nb_context,_param->_size_context_id);
        DELETE1_SIGNAL(out_BRANCH_EVENT_DEPTH            ,_param->_nb_context,_param->_size_depth);
//      DELETE1_SIGNAL(out_BRANCH_EVENT_MISS_PREDICTION  ,_param->_nb_context,1);
        DELETE1_SIGNAL(out_BRANCH_EVENT_ADDRESS_SRC      ,_param->_nb_context,_param->_size_instruction_address);
        DELETE1_SIGNAL(out_BRANCH_EVENT_ADDRESS_DEST_VAL ,_param->_nb_context,1);
        DELETE1_SIGNAL(out_BRANCH_EVENT_ADDRESS_DEST     ,_param->_nb_context,_param->_size_instruction_address);
        DELETE1_SIGNAL(out_BRANCH_EVENT_CAN_CONTINUE     ,_param->_nb_context,1);

        // ~~~~~[ Interface : "update" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DELETE1_SIGNAL(out_UPDATE_VAL                  ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL( in_UPDATE_ACK                  ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_CONTEXT_ID           ,_param->_nb_inst_update,_param->_size_context_id);
        DELETE1_SIGNAL(out_UPDATE_MISS_PREDICTION      ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_DIRECTION_GOOD       ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_PREDICTION_IFETCH    ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_BTB_VAL              ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_BTB_ADDRESS_SRC      ,_param->_nb_inst_update,_param->_size_instruction_address);
        DELETE1_SIGNAL(out_UPDATE_BTB_ADDRESS_DEST     ,_param->_nb_inst_update,_param->_size_instruction_address);
        DELETE1_SIGNAL(out_UPDATE_BTB_CONDITION        ,_param->_nb_inst_update,_param->_size_branch_condition);
        DELETE1_SIGNAL(out_UPDATE_DIR_VAL              ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_DIR_HISTORY          ,_param->_nb_inst_update,_param->_size_history);
        DELETE1_SIGNAL(out_UPDATE_RAS_VAL              ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_RAS_FLUSH            ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_RAS_PUSH             ,_param->_nb_inst_update,1);
        DELETE1_SIGNAL(out_UPDATE_RAS_ADDRESS          ,_param->_nb_inst_update,_param->_size_instruction_address);
        DELETE1_SIGNAL(out_UPDATE_RAS_INDEX            ,_param->_nb_inst_update,_param->_max_size_ras_index);

        // ~~~~~[ Interface : "event" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DELETE1_SIGNAL( in_EVENT_VAL    ,_param->_nb_context,1);
        DELETE1_SIGNAL(out_EVENT_ACK    ,_param->_nb_context,1);
        DELETE1_SIGNAL( in_EVENT_TYPE   ,_param->_nb_context,_param->_size_event_type );
        DELETE1_SIGNAL( in_EVENT_DEPTH  ,_param->_nb_context,_param->_size_depth      );

	// ~~~~~[ Interface : "depth" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DELETE1_SIGNAL(out_DEPTH_VAL          ,_param->_nb_context,1);
        DELETE1_SIGNAL(out_DEPTH_CURRENT      ,_param->_nb_context,_param->_size_depth);
        DELETE1_SIGNAL(out_DEPTH_MIN          ,_param->_nb_context,_param->_size_depth);
        DELETE1_SIGNAL(out_DEPTH_MAX          ,_param->_nb_context,_param->_size_depth);
        DELETE1_SIGNAL(out_DEPTH_FULL         ,_param->_nb_context,1);

        // ~~~~~[ Internal ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DELETE1(internal_PREDICT_ACK                     ,_param->_nb_inst_predict);
        DELETE1(internal_PREDICT_UPDATE_PREDICTION_ID    ,_param->_nb_inst_predict);
        DELETE1(internal_DECOD_ACK                       ,_param->_nb_inst_decod);
        DELETE1(internal_DECOD_UPT_PTR_WRITE             ,_param->_nb_inst_decod);
        DELETE1(internal_BRANCH_COMPLETE_ACK             ,_param->_nb_inst_branch_complete);
        DELETE1(internal_BRANCH_COMPLETE_MISS_PREDICTION ,_param->_nb_inst_branch_complete);
        DELETE1(internal_BRANCH_COMPLETE_TAKE            ,_param->_nb_inst_branch_complete);
        DELETE1(internal_BRANCH_COMPLETE_ADDRESS_DEST    ,_param->_nb_inst_branch_complete);
        DELETE1(internal_BRANCH_EVENT_VAL                ,_param->_nb_context);
        DELETE1(internal_BRANCH_EVENT_DEPTH              ,_param->_nb_context);
        DELETE1(internal_UPDATE_VAL                      ,_param->_nb_inst_update);
        DELETE1(internal_UPDATE_VAL_WITHOUT_ACK          ,_param->_nb_inst_update);
        DELETE1(internal_UPDATE_CONTEXT_ID               ,_param->_nb_inst_update);
        DELETE1(internal_UPDATE_FROM_UFPT                ,_param->_nb_inst_update);
        DELETE1(internal_UPDATE_DEPTH                    ,_param->_nb_inst_update);
        DELETE1(internal_UPDATE_RAS                      ,_param->_nb_inst_update);
        DELETE1(internal_EVENT_ACK                       ,_param->_nb_context);
        
        // ~~~~~[ Register ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
        DELETE1(reg_IS_ACCURATE                  ,_param->_nb_context);
        
        DELETE2(reg_UPDATE_FETCH_PREDICTION_TABLE,_param->_nb_context,_param->_size_ufpt_queue[it1]);
        DELETE1(reg_UFPT_BOTTOM                  ,_param->_nb_context);
        DELETE1(reg_UFPT_TOP                     ,_param->_nb_context);
        DELETE1(reg_UFPT_UPDATE                  ,_param->_nb_context);
        DELETE1(reg_UFPT_NB_NEED_UPDATE          ,_param->_nb_context);
        DELETE1(reg_UFPT_NB_UPDATE               ,_param->_nb_context);
        
        DELETE2(reg_UPDATE_PREDICTION_TABLE      ,_param->_nb_context,_param->_size_upt_queue[it1]);
        DELETE1(reg_UPT_BOTTOM                   ,_param->_nb_context);
        DELETE1(reg_UPT_TOP                      ,_param->_nb_context);
        DELETE1(reg_UPT_TOP_EVENT                ,_param->_nb_context);
        DELETE1(reg_UPT_UPDATE                   ,_param->_nb_context);
        DELETE1(reg_UPT_EMPTY                    ,_param->_nb_context);
        
        DELETE1(reg_UFPT_EVENT_STATE             ,_param->_nb_context);
        DELETE1(reg_UPT_EVENT_STATE              ,_param->_nb_context);

//         DELETE1(reg_EVENT_VAL                    ,_param->_nb_context);
        DELETE1(reg_EVENT_UPT_PTR                ,_param->_nb_context);
        DELETE1(reg_EVENT_UPT_FULL               ,_param->_nb_context);

//         DELETE1(reg_EVENT_STATE                  ,_param->_nb_context);
//         DELETE1(reg_EVENT_IS_BRANCH              ,_param->_nb_context);
        DELETE1(reg_EVENT_DEPTH                  ,_param->_nb_context);
        DELETE1(reg_EVENT_ADDRESS_SRC            ,_param->_nb_context);
        DELETE1(reg_EVENT_ADDRESS_DEST_VAL       ,_param->_nb_context);
        DELETE1(reg_EVENT_ADDRESS_DEST           ,_param->_nb_context);
        DELETE1(reg_EVENT_CAN_CONTINUE           ,_param->_nb_context);
       }

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

    delete _component;

#if defined(DEBUG) and defined(DEBUG_Update_Prediction_Table) and (DEBUG_Update_Prediction_Table == true)
    {
      for (uint32_t i=0; i<_param->_nb_thread; ++i)
        if (_param->_have_thread [i])
          {
            branchement_log_file [i].close();
          }
      delete [] branchement_log_file;
    }
#endif

    log_printf(FUNC,Update_Prediction_Table,FUNCTION,"End");
  };

}; // end namespace update_prediction_table
}; // end namespace prediction_unit
}; // end namespace front_end
}; // end namespace multi_front_end
}; // end namespace core

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