/*
 * $Id: Load_store_unit.cpp 138 2010-05-12 17:34:01Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/include/Load_store_unit.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace multi_execute_unit {
namespace execute_unit {
namespace load_store_unit {


#undef  FUNCTION
#define FUNCTION "Load_store_unit::Load_store_unit"
  Load_store_unit::Load_store_unit 
  (
#ifdef SYSTEMC
   sc_module_name name,
#else
   std::string name,
#endif
#ifdef STATISTICS
   morpheo::behavioural::Parameters_Statistics * param_statistics,
#endif
   morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Parameters * param ,
   morpheo::behavioural::Tusage_t usage
   ):
    _name              (name)
    ,_param            (param)
    ,_usage (usage)
  {
    log_printf(FUNC,Load_store_unit,FUNCTION,"Begin");

// #if DEBUG_Load_store_unit == true
//     log_printf(INFO,Load_store_unit,FUNCTION,_("<%s> Parameters"),_name.c_str());

//     std::cout << *param << std::endl;
// #endif    

#ifdef SYSTEMC
    log_printf(INFO,Load_store_unit,FUNCTION,"Allocation");

    allocation ();
#endif

#ifdef STATISTICS
    if (usage_is_set(_usage,USE_STATISTICS))
      {	
        log_printf(INFO,Load_store_unit,FUNCTION,"Allocation of statistics");
        
        statistics_allocation(param_statistics);
      }
#endif

#ifdef VHDL
    if (usage_is_set(_usage,USE_VHDL))
      {	
        // generate the vhdl
        log_printf(INFO,Load_store_unit,FUNCTION,"Generate the vhdl");
        
        vhdl();
      }
#endif

#ifdef SYSTEMC
    if (usage_is_set(_usage,USE_SYSTEMC))
      {	

    // Function pointer
    switch (_param->_speculative_load)
      {
      case SPECULATIVE_LOAD_ACCESS :
	{
	  function_transition      = &morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Load_store_unit::function_speculative_load_access_transition     ;
	  function_genMoore        = &morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Load_store_unit::function_speculative_load_access_genMoore       ;
	  function_genMealy_dcache = &morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Load_store_unit::function_speculative_load_access_genMealy_dcache;
	  function_genMealy_insert = &morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Load_store_unit::function_speculative_load_access_genMealy_insert;
	  function_genMealy_retire = &morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Load_store_unit::function_speculative_load_access_genMealy_retire;
	  break;
	}
      case NO_SPECULATIVE_LOAD     :
      // case SPECULATIVE_LOAD_COMMIT :
      //case SPECULATIVE_LOAD_BYPASS :
      default                      :
	{
	  break;
	}
      }

#ifdef SYSTEMCASS_SPECIFIC
        constant();
#else
    log_printf(INFO,Load_store_unit,FUNCTION,"Method - constant");

    SC_METHOD (constant);
//     dont_initialize ();

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
#endif    
#endif

    log_printf(INFO,Load_store_unit,FUNCTION,"Method - transition");

    SC_METHOD (transition);
    dont_initialize ();
    sensitive << (*(in_CLOCK)).pos();

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
#endif    

    log_printf(INFO,Load_store_unit,FUNCTION,"Method - genMoore");

    SC_METHOD (genMoore);
    dont_initialize ();
    sensitive << (*(in_CLOCK)).neg();

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
#endif    

    log_printf(INFO,Load_store_unit,FUNCTION,"Method - genMealy_insert");

    SC_METHOD (genMealy_insert);
    dont_initialize ();
    sensitive << (*(in_CLOCK)).neg()
	      << (*(in_NRESET));
    for (uint32_t i=0; i<_param->_nb_inst_memory; i++)
      sensitive << (*(in_MEMORY_IN_VAL       [i]))
		<< (*(in_MEMORY_IN_OPERATION [i]));

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
    for (uint32_t i=0; i<_param->_nb_inst_memory; i++)
//       for (uint32_t x=0; x<_param->_nb_inst_memory; x++)
	{
	  (*(out_MEMORY_IN_ACK [i])) (*(in_MEMORY_IN_VAL       [i]));
	  (*(out_MEMORY_IN_ACK [i])) (*(in_MEMORY_IN_OPERATION [i]));
	}
#endif    

    log_printf(INFO,Load_store_unit,FUNCTION,"Method - genMealy_retire");

    SC_METHOD (genMealy_retire);
    dont_initialize ();
    sensitive << (*(in_CLOCK)).neg()
	      << (*(in_NRESET));

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
#endif    

    log_printf(INFO,Load_store_unit,FUNCTION,"Method - genMealy_dcache");

    SC_METHOD (genMealy_dcache);
    dont_initialize ();
    sensitive << (*(in_CLOCK)).neg()
	      << (*(in_NRESET));

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
#endif    
      }
#endif
    log_printf(FUNC,Load_store_unit,FUNCTION,"End");
  };
  
#undef  FUNCTION
#define FUNCTION "Load_store_unit::~Load_store_unit"
  Load_store_unit::~Load_store_unit (void)
  {
    log_printf(FUNC,Load_store_unit,FUNCTION,"Begin");

#ifdef STATISTICS
    if (usage_is_set(_usage,USE_STATISTICS))
      statistics_deallocation ();
#endif

#ifdef SYSTEMC
    log_printf(INFO,Load_store_unit,FUNCTION,"Deallocation");

    deallocation ();
#endif

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

}; // end namespace load_store_unit
}; // end namespace execute_unit
}; // end namespace multi_execute_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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