/*
 * $Id: Load_store_unit.cpp 111 2009-02-27 18:37:40Z 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_COMMIT :
	{
	  function_transition      = &morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_execute_unit::execute_unit::load_store_unit::Load_store_unit::function_speculative_load_commit_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_commit_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_commit_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_commit_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_commit_genMealy_retire;
	  break;
	}
      case NO_SPECULATIVE_LOAD     :
      case SPECULATIVE_LOAD_ACCESS :
	//case SPECULATIVE_LOAD_BYPASS :
      default                      :
	{
	  break;
	}
      }

    log_printf(INFO,Load_store_unit,FUNCTION,"Constant affectation");

    internal_DCACHE_RSP_ACK = 1;
    PORT_WRITE(out_DCACHE_RSP_ACK [0], internal_DCACHE_RSP_ACK);
    for (uint32_t i=1; i<_param->_nb_cache_port; ++i)
      {
	PORT_WRITE(out_DCACHE_RSP_ACK [i], 0);
	PORT_WRITE(out_DCACHE_REQ_VAL [i], 0);
      }

    for (uint32_t i=1; i<_param->_nb_inst_memory; i++)
      {
	PORT_WRITE(out_MEMORY_OUT_VAL [i], 0);
      }

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

    SC_METHOD (transition);
    dont_initialize ();
    sensitive_pos << *(in_CLOCK);

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
#endif    

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

    SC_METHOD (genMoore);
    dont_initialize ();
    sensitive_neg << *(in_CLOCK);

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
#endif    

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

    SC_METHOD (genMealy_insert);
    dont_initialize ();
    sensitive_neg << *(in_CLOCK);
    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_neg << *(in_CLOCK);

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
#endif    

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

    SC_METHOD (genMealy_dcache);
    dont_initialize ();
    sensitive_neg << *(in_CLOCK);

#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              
