/*
 * $Id: Update_Prediction_Table_deallocation.cpp 111 2009-02-27 18:37:40Z 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" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	delete []  in_PREDICT_VAL                 ;
	delete [] out_PREDICT_ACK                 ;
	if (_param->_have_port_context_id)
	delete []  in_PREDICT_CONTEXT_ID          ;
	delete []  in_PREDICT_BTB_ADDRESS_SRC     ;
	delete []  in_PREDICT_BTB_ADDRESS_DEST    ;
	delete []  in_PREDICT_BTB_CONDITION       ;
	delete []  in_PREDICT_BTB_LAST_TAKE       ;
	delete []  in_PREDICT_BTB_IS_ACCURATE     ;
	if (_param->_have_port_history)
	delete []  in_PREDICT_DIR_HISTORY         ;
	delete []  in_PREDICT_RAS_ADDRESS         ;
	delete []  in_PREDICT_RAS_INDEX           ;
 	if (_param->_have_port_depth)
 	delete [] out_PREDICT_UPDATE_PREDICTION_ID;
	
	// ~~~~~[ Interface : "decod" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	delete []  in_DECOD_VAL                   ;
	delete [] out_DECOD_ACK                   ;
	if (_param->_have_port_context_id)
	delete []  in_DECOD_CONTEXT_ID            ;
	delete []  in_DECOD_BTB_ADDRESS_SRC       ;
	delete []  in_DECOD_BTB_ADDRESS_DEST      ;
	delete []  in_DECOD_BTB_CONDITION         ;
	delete []  in_DECOD_BTB_LAST_TAKE         ;
	delete []  in_DECOD_RAS_ADDRESS           ;
	delete []  in_DECOD_RAS_INDEX             ;
	delete []  in_DECOD_MISS_IFETCH           ;
	delete []  in_DECOD_MISS_DECOD            ;
	if (_param->_have_port_depth)
	delete []  in_DECOD_UPDATE_PREDICTION_ID  ;
// 	if (_param->_have_port_depth)
// 	delete [] out_DECOD_DEPTH                 ;
	delete []  in_DECOD_IS_ACCURATE           ;
	delete [] out_DECOD_CAN_CONTINUE          ;
	
	// ~~~~~[ Interface : "branch_complete" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	delete []  in_BRANCH_COMPLETE_VAL            ;
	delete [] out_BRANCH_COMPLETE_ACK            ;
	if (_param->_have_port_context_id)
	delete []  in_BRANCH_COMPLETE_CONTEXT_ID     ;
	if (_param->_have_port_depth)
	delete []  in_BRANCH_COMPLETE_DEPTH          ;
	delete []  in_BRANCH_COMPLETE_ADDRESS        ;
	delete []  in_BRANCH_COMPLETE_NO_SEQUENCE    ;
	delete [] out_BRANCH_COMPLETE_MISS_PREDICTION;
// 	delete [] out_BRANCH_COMPLETE_TAKE           ;
// 	delete [] out_BRANCH_COMPLETE_ADDRESS_SRC    ;
// 	delete [] out_BRANCH_COMPLETE_ADDRESS_DEST   ;

	// ~~~~~[ 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);

	// ~~~~~[ Interface : "update" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	delete [] out_UPDATE_VAL                  ;
	delete []  in_UPDATE_ACK                  ;
	if (_param->_have_port_context_id)
	delete [] out_UPDATE_CONTEXT_ID           ;
	delete [] out_UPDATE_MISS_PREDICTION      ;
	delete [] out_UPDATE_DIRECTION_GOOD       ;
	delete [] out_UPDATE_BTB_VAL              ;
	delete [] out_UPDATE_BTB_ADDRESS_SRC      ;
	delete [] out_UPDATE_BTB_ADDRESS_DEST     ;
	delete [] out_UPDATE_BTB_CONDITION        ;
	delete [] out_UPDATE_DIR_VAL              ;
	if (_param->_have_port_history)
	delete [] out_UPDATE_DIR_HISTORY          ;
	delete [] out_UPDATE_RAS_VAL              ;
	delete [] out_UPDATE_RAS_FLUSH            ;
	delete [] out_UPDATE_RAS_PUSH             ;
	delete [] out_UPDATE_RAS_ADDRESS          ;
	delete [] out_UPDATE_RAS_INDEX            ;
	delete [] out_UPDATE_RAS_PREDICTION_IFETCH;

        // ~~~~~[ 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_EVENT_VAL                    ,_param->_nb_context);
        DELETE1(reg_EVENT_UPT_PTR                ,_param->_nb_context);

        DELETE1(reg_EVENT_STATE                  ,_param->_nb_context);
        DELETE1(reg_EVENT_SOURCE                 ,_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);
       }

    // ~~~~~[ 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();
        }
#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              
