#ifdef SYSTEMC
/*
 * $Id: Commit_unit_genMealy_commit.cpp 100 2009-01-08 13:06:27Z rosiere $
 *
 * [ Description ]
 * 
 */

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

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace commit_unit {


#undef  FUNCTION
#define FUNCTION "Commit_unit::genMealy_commit"
  void Commit_unit::genMealy_commit (void)
  {
    log_begin(Commit_unit,FUNCTION);
    log_function(Commit_unit,FUNCTION,_name.c_str());

#ifdef STATISTICS
    internal_BANK_COMMIT_CONFLIT_ACCESS = 0;
#endif

    uint32_t           bank_nb_access    [_param->_nb_bank];
    Tcontrol_t         commit_ack        [_param->_nb_inst_commit];

    // Initialisation
    for (uint32_t i=0; i<_param->_nb_bank; i++)
      {
	bank_nb_access            [i] = 0;
	for (uint32_t j=0; j<_param->_nb_bank_access_commit; j++)
	  internal_BANK_COMMIT_VAL  [i][j] = false;
      }

    // commit interface -> scan all entry (Out of Order)
    for (uint32_t i=0; i<_param->_nb_inst_commit; i++)
      {
        commit_ack        [i] = false;

	// Test if have valid instruction
	if (PORT_READ(in_COMMIT_VAL [i]))
	  {
            // packet_id number can 
	    Tpacket_t packet_id       = (_param->_have_port_rob_ptr  )?PORT_READ(in_COMMIT_PACKET_ID [i]):0;
	    uint32_t  num_bank        = packet_id >> _param->_shift_num_bank;
	    uint32_t  num_bank_access = bank_nb_access [num_bank];
            
	    // test if bank is not busy (previous access)
	    if (num_bank_access < _param->_nb_bank_access_commit)
	      {
		// find
		bank_nb_access    [num_bank] ++;
		commit_ack        [i] = true;

		internal_BANK_COMMIT_VAL      [num_bank][num_bank_access] = true;
		internal_BANK_COMMIT_NUM_INST [num_bank][num_bank_access] = i;
                
                Tpacket_t num_packet = packet_id & _param->_mask_size_bank;
                
                // find the good entry !!!
                entry_t* entry = NULL;
                for (std::list<entry_t*>::iterator it=_rob[num_bank].begin();
                     it!=_rob[num_bank].end();
                     it++)
                  if ((*it)->ptr == num_packet)
                    {
                      entry = (*it);
                      break;
                    }

#ifdef DEBUG_TEST
                if (entry == NULL)
                  throw ERRORMORPHEO(FUNCTION,_("Commit : Packet_id miss match in the Re Order Buffer.\n"));
#endif

                internal_BANK_COMMIT_ENTRY    [num_bank][num_bank_access] = entry;

//              PORT_WRITE(out_COMMIT_NUM_REG_RD [i],(entry->rename_unit_id << _param->_size_general_register)+entry->num_reg_rd_phy_new);
                PORT_WRITE(out_COMMIT_NUM_REG_RD [i],entry->num_reg_rd_phy_new);
	      }
#ifdef STATISTICS
	    else
	      {
		internal_BANK_COMMIT_CONFLIT_ACCESS ++;
	      }
#endif
	  }
      }
    
    for (uint32_t i=0; i<_param->_nb_inst_commit; i++)
      PORT_WRITE(out_COMMIT_ACK [i],commit_ack [i]);
    
    log_end(Commit_unit,FUNCTION);
  };

}; // end namespace commit_unit
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core
}; // end namespace behavioural
}; // end namespace morpheo              
#endif
