/*
 * $Id: OOO_Engine_Glue.cpp 88 2008-12-10 18:31:39Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/OOO_Engine_Glue/include/OOO_Engine_Glue.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace ooo_engine_glue {


#undef  FUNCTION
#define FUNCTION "OOO_Engine_Glue::OOO_Engine_Glue"
  OOO_Engine_Glue::OOO_Engine_Glue 
  (
#ifdef SYSTEMC
   sc_module_name name,
#else
   string name,
#endif
#ifdef STATISTICS
   morpheo::behavioural::Parameters_Statistics * param_statistics,
#endif
   morpheo::behavioural::core::multi_ooo_engine::ooo_engine::ooo_engine_glue::Parameters * param,
   morpheo::behavioural::Tusage_t usage
   ):
    _name              (name)
    ,_param            (param)
    ,_usage            (usage)
  {
    log_begin(OOO_Engine_Glue,FUNCTION);

    usage_environment(_usage);

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

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

    log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Allocation"),_name.c_str());

    allocation (
#ifdef STATISTICS
		param_statistics
#endif
		);

#ifdef STATISTICS
    if (usage_is_set(_usage,USE_STATISTICS))
      {	
	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Allocation of statistics"),_name.c_str());

	statistics_allocation(param_statistics);
      }
#endif

#ifdef VHDL
    if (usage_is_set(_usage,USE_VHDL))
      {
	// generate the vhdl
	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Generate the vhdl"),_name.c_str());
	
	vhdl();
      }
#endif

#ifdef SYSTEMC
    if (usage_is_set(_usage,USE_SYSTEMC))
      {
	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Method - transition"),_name.c_str());

	SC_METHOD (transition);
	dont_initialize ();
	sensitive << (*(in_CLOCK)).pos();
	
# ifdef SYSTEMCASS_SPECIFIC
	// List dependency information
# endif    

// 	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Method - genMoore"),_name.c_str());

// 	SC_METHOD (genMoore);
// 	dont_initialize ();
// 	sensitive << (*(in_CLOCK)).neg(); // need internal register
	
// # ifdef SYSTEMCASS_SPECIFIC
// 	// List dependency information
// # endif    

        if (_param->_have_port_front_end_id)
          {
	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Method - genMealy_rename"),_name.c_str());

	SC_METHOD (genMealy_rename);
	dont_initialize ();
	//sensitive << (*(in_CLOCK)).neg(); // don't need internal register
        for (uint32_t i=0; i<_param->_nb_front_end; ++i)
          for (uint32_t j=0; j<_param->_nb_inst_decod[i]; ++j)
            sensitive << (*(in_RENAME_FRONT_END_ID [i][j]));

# ifdef SYSTEMCASS_SPECIFIC
	// List dependency information
# endif    
          }

	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Method - genMealy_insert_valack"),_name.c_str());

	SC_METHOD (genMealy_insert_valack);
	dont_initialize ();
	//sensitive << (*(in_CLOCK)).neg(); // don't need internal register
        {
          uint32_t x=0;
          for (uint32_t i=0; i<_param->_nb_rename_unit; ++i)
            for (uint32_t j=0; j<_param->_nb_inst_insert[i]; ++j)
              sensitive << (*(in_INSERT_ACK                    [x++] ))
                        << (*(in_INSERT_RENAME_UNIT_VAL        [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NO_EXECUTE [i][j]))
                        << (*(in_INSERT_COMMIT_UNIT_ACK        [i][j]))
                        << (*(in_INSERT_ISSUE_QUEUE_ACK        [i][j]));
        }

# ifdef SYSTEMCASS_SPECIFIC
	// List dependency information
# endif    

	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Method - genMealy_insert"),_name.c_str());

	SC_METHOD (genMealy_insert);
	dont_initialize ();
	//sensitive << (*(in_CLOCK)).neg(); // don't need internal register

        for (uint32_t i=0; i<_param->_nb_rename_unit; ++i)
          for (uint32_t j=0; j<_param->_nb_inst_insert[i];++j)
            {
              if (_param->_have_port_front_end_id)
              sensitive << (*(in_INSERT_RENAME_UNIT_FRONT_END_ID          [i][j]));
              if (_param->_have_port_context_id)
              sensitive << (*(in_INSERT_RENAME_UNIT_CONTEXT_ID            [i][j]));
              if (_param->_have_port_load_queue_ptr)
              sensitive << (*(in_INSERT_RENAME_UNIT_LOAD_QUEUE_PTR_WRITE  [i][j]));
              sensitive << (*(in_INSERT_RENAME_UNIT_TYPE                  [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_OPERATION             [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NO_EXECUTE            [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_HAS_IMMEDIAT          [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_IMMEDIAT              [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_STORE_QUEUE_PTR_WRITE [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_READ_RA               [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NUM_REG_RA_PHY        [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_READ_RB               [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NUM_REG_RB_PHY        [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_READ_RC               [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NUM_REG_RC_PHY        [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_WRITE_RD              [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NUM_REG_RD_PHY_OLD    [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NUM_REG_RD_PHY_NEW    [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_WRITE_RE              [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NUM_REG_RE_PHY_OLD    [i][j]))
                        << (*(in_INSERT_RENAME_UNIT_NUM_REG_RE_PHY_NEW    [i][j]));
            }

# ifdef SYSTEMCASS_SPECIFIC
	// List dependency information
# endif    

// 	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Method - genMealy_retire_valack"),_name.c_str());

// 	SC_METHOD (genMealy_retire_valack);
// 	dont_initialize ();
// 	//sensitive << (*(in_CLOCK)).neg(); // don't need internal register
//         {
//           uint32_t x=0;
//           for (uint32_t i=0; i<_param->_nb_rename_unit; ++i)
//             for (uint32_t j=0; j<_param->_nb_inst_retire[i]; ++j)
//               sensitive 
//              << (*(in_RETIRE_ACK             [x++]))  
//                 << (*(in_RETIRE_RENAME_UNIT_ACK [i][j])) 
//                 << (*(in_RETIRE_COMMIT_UNIT_VAL [i][j]));
//         }

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

// 	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Method - genMealy_retire"),_name.c_str());

// 	SC_METHOD (genMealy_retire);
// 	dont_initialize ();
// 	//sensitive << (*(in_CLOCK)).neg(); // don't need internal register
//         for (uint32_t i=0; i<_param->_nb_rename_unit; ++i)
//           for (uint32_t j=0; j<_param->_nb_inst_retire[i]; ++j)
//             {
//               if (_param->_have_port_front_end_id)
//               sensitive << (*( in_RETIRE_COMMIT_UNIT_FRONT_END_ID       [i][j]));
//               sensitive << (*( in_RETIRE_COMMIT_UNIT_WRITE_RD           [i][j]))
//                         << (*( in_RETIRE_COMMIT_UNIT_NUM_REG_RD_PHY_OLD [i][j]))
//                         << (*( in_RETIRE_COMMIT_UNIT_NUM_REG_RD_PHY_NEW [i][j]))
//                         << (*( in_RETIRE_COMMIT_UNIT_WRITE_RE           [i][j]))
//                         << (*( in_RETIRE_COMMIT_UNIT_NUM_REG_RE_PHY_OLD [i][j]))
//                         << (*( in_RETIRE_COMMIT_UNIT_NUM_REG_RE_PHY_NEW [i][j]))
//                         << (*( in_RETIRE_COMMIT_UNIT_EVENT_STATE        [i][j]));
//             }


# ifdef SYSTEMCASS_SPECIFIC
	// List dependency information
# endif    

	log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Method - genMealy_spr"),_name.c_str());

	SC_METHOD (genMealy_spr);
	dont_initialize ();
	//sensitive << (*(in_CLOCK)).neg(); // don't need internal register
        for (uint32_t i=0; i<_param->_nb_front_end; ++i)
          for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
            sensitive << (*(in_SPR_SPECIAL_REGISTER_UNIT_SR [i][j]));

# ifdef SYSTEMCASS_SPECIFIC
	// List dependency information
# endif    

	
#endif
      }
    log_end(OOO_Engine_Glue,FUNCTION);
  };
    
#undef  FUNCTION
#define FUNCTION "OOO_Engine_Glue::~OOO_Engine_Glue"
  OOO_Engine_Glue::~OOO_Engine_Glue (void)
  {
    log_begin(OOO_Engine_Glue,FUNCTION);

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

    log_printf(INFO,OOO_Engine_Glue,FUNCTION,_("<%s> : Deallocation"),_name.c_str());
    deallocation ();

    log_end(OOO_Engine_Glue,FUNCTION);
  };

}; // end namespace ooo_engine_glue
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core

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