/*
 * $Id$
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Read_unit/Read_unit/Read_queue/include/Read_queue.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace multi_read_unit {
namespace read_unit {
namespace read_queue {


#ifdef SYSTEMC
  Read_queue::Read_queue (sc_module_name name,
#else
  Read_queue::Read_queue (string name,
#endif
#ifdef STATISTICS
			      morpheo::behavioural::Parameters_Statistics            * param_statistics,
#endif
			      morpheo::behavioural::core::multi_execute_loop::execute_loop::multi_read_unit::read_unit::read_queue::Parameters * param ):
			      _name              (name)
			      ,_param            (param)
  {
    log_printf(FUNC,Read_queue,"Read_queue","Begin");

#ifdef SYSTEMC
    log_printf(INFO,Read_queue,"Read_queue","Allocation");

    allocation ();
#endif

#ifdef STATISTICS
    log_printf(INFO,Read_queue,"Read_queue","Allocation of statistics");

    // Allocation of statistics
    _stat = new Statistics (static_cast<string>(_name),
			    param_statistics          ,
			    param);
#endif

#ifdef VHDL
    // generate the vhdl
    log_printf(INFO,Read_queue,"Read_queue","Generate the vhdl");

    vhdl();
#endif

#ifdef SYSTEMC
    log_printf(INFO,Read_queue,"Read_queue","Method - transition");

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

    log_printf(INFO,Read_queue,"Read_queue","Method - genMoore");

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

    log_printf(INFO,Read_queue,"Read_queue","Method - genMealy_read_queue_out_val");

    SC_METHOD (genMealy_read_queue_out_val);
    dont_initialize ();
    sensitive_neg << *(in_CLOCK);
    for (uint32_t i=0; i<_param->_nb_gpr_read ; i++)
      sensitive << *(in_GPR_READ_ACK      [i]);
    for (uint32_t i=0; i<_param->_nb_spr_read ; i++)
      sensitive << *(in_SPR_READ_ACK      [i]);
    for (uint32_t i=0; i<_param->_nb_gpr_write; i++)
      {
	if (_param->_have_port_ooo_engine_id)
	  sensitive << *(in_GPR_WRITE_OOO_ENGINE_ID [i]);

	sensitive << *(in_GPR_WRITE_VAL        [i])
		  << *(in_GPR_WRITE_NUM_REG    [i]);
      }
    for (uint32_t i=0; i<_param->_nb_spr_write; i++)
      {
	if (_param->_have_port_ooo_engine_id)
	  sensitive << *(in_SPR_WRITE_OOO_ENGINE_ID [i]);
	sensitive << *(in_SPR_WRITE_VAL        [i])
		  
		  << *(in_SPR_WRITE_NUM_REG    [i]);
      }
#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information

    (*(out_READ_QUEUE_OUT_VAL)) (*(in_GPR_READ_ACK                [0]));
    (*(out_READ_QUEUE_OUT_VAL)) (*(in_SPR_READ_ACK                [0]));
    
    for (uint32_t i=0; i<_param->_nb_gpr_write ; i++)
      {
	(*(out_READ_QUEUE_OUT_VAL)) (*(in_GPR_WRITE_VAL        [i]));
	if (_param->_have_port_ooo_engine_id)
	(*(out_READ_QUEUE_OUT_VAL)) (*(in_GPR_WRITE_OOO_ENGINE_ID [i]));
	(*(out_READ_QUEUE_OUT_VAL)) (*(in_GPR_WRITE_NUM_REG    [i]));
      }
    for (uint32_t i=0; i<_param->_nb_spr_write ; i++)
      {
	(*(out_READ_QUEUE_OUT_VAL)) (*(in_SPR_WRITE_VAL        [i]));
	if (_param->_have_port_ooo_engine_id)
	(*(out_READ_QUEUE_OUT_VAL)) (*(in_SPR_WRITE_OOO_ENGINE_ID [i]));
	(*(out_READ_QUEUE_OUT_VAL)) (*(in_SPR_WRITE_NUM_REG    [i]));
      }
#endif    
    
    log_printf(INFO,Read_queue,"Read_queue","Method - genMealy_read_queue_out_gpr");

    SC_METHOD (genMealy_read_queue_out_gpr);
    dont_initialize ();
    sensitive_neg << *(in_CLOCK);
    for (uint32_t i=0; i<_param->_nb_gpr_read ; i++)
      sensitive << *(in_GPR_READ_ACK      [i])
		<< *(in_GPR_READ_DATA     [i])
		<< *(in_GPR_READ_DATA_VAL [i]);
    for (uint32_t i=0; i<_param->_nb_gpr_write; i++)
      {
	if (_param->_have_port_ooo_engine_id)
	  sensitive << *(in_GPR_WRITE_OOO_ENGINE_ID [i]);
	sensitive << *(in_GPR_WRITE_VAL        [i])
		  << *(in_GPR_WRITE_NUM_REG    [i])
		  << *(in_GPR_WRITE_DATA       [i]);
      }
#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information

    (*(out_READ_QUEUE_OUT_DATA_RA_VAL)) (*(in_GPR_READ_ACK                [0]));
    (*(out_READ_QUEUE_OUT_DATA_RA_VAL)) (*(in_GPR_READ_DATA_VAL           [0]));
    (*(out_READ_QUEUE_OUT_DATA_RB_VAL)) (*(in_GPR_READ_ACK                [1]));
    (*(out_READ_QUEUE_OUT_DATA_RB_VAL)) (*(in_GPR_READ_DATA_VAL           [1]));
    
    (*(out_READ_QUEUE_OUT_DATA_RA    )) (*(in_GPR_READ_DATA               [0]));
    (*(out_READ_QUEUE_OUT_DATA_RB    )) (*(in_GPR_READ_DATA               [1]));
    
    for (uint32_t i=0; i<_param->_nb_gpr_write ; i++)
      {
	(*(out_READ_QUEUE_OUT_DATA_RA_VAL)) (*(in_GPR_WRITE_VAL        [i]));
	if (_param->_have_port_ooo_engine_id)
	  (*(out_READ_QUEUE_OUT_DATA_RA_VAL)) (*(in_GPR_WRITE_OOO_ENGINE_ID [i]));
	(*(out_READ_QUEUE_OUT_DATA_RA_VAL)) (*(in_GPR_WRITE_NUM_REG    [i]));
	(*(out_READ_QUEUE_OUT_DATA_RB_VAL)) (*(in_GPR_WRITE_VAL        [i]));
	if (_param->_have_port_ooo_engine_id)
	  (*(out_READ_QUEUE_OUT_DATA_RB_VAL)) (*(in_GPR_WRITE_OOO_ENGINE_ID [i]));
	(*(out_READ_QUEUE_OUT_DATA_RB_VAL)) (*(in_GPR_WRITE_NUM_REG    [i]));

	(*(out_READ_QUEUE_OUT_DATA_RA    )) (*(in_GPR_WRITE_VAL        [i]));
	if (_param->_have_port_ooo_engine_id)
	  (*(out_READ_QUEUE_OUT_DATA_RA    )) (*(in_GPR_WRITE_OOO_ENGINE_ID [i]));
	(*(out_READ_QUEUE_OUT_DATA_RA    )) (*(in_GPR_WRITE_NUM_REG    [i]));
	(*(out_READ_QUEUE_OUT_DATA_RA    )) (*(in_GPR_WRITE_DATA       [i]));
	(*(out_READ_QUEUE_OUT_DATA_RB    )) (*(in_GPR_WRITE_VAL        [i]));
	if (_param->_have_port_ooo_engine_id)
	  (*(out_READ_QUEUE_OUT_DATA_RB    )) (*(in_GPR_WRITE_OOO_ENGINE_ID [i]));
	(*(out_READ_QUEUE_OUT_DATA_RB    )) (*(in_GPR_WRITE_NUM_REG    [i]));
	(*(out_READ_QUEUE_OUT_DATA_RB    )) (*(in_GPR_WRITE_DATA       [i]));
      }
#endif    

    log_printf(INFO,Read_queue,"Read_queue","Method - genMealy_read_queue_out_spr");

    SC_METHOD (genMealy_read_queue_out_spr);
    dont_initialize ();
    sensitive_neg << *(in_CLOCK);
    for (uint32_t i=0; i<_param->_nb_spr_read ; i++)
      sensitive << *(in_SPR_READ_ACK      [i])
		<< *(in_SPR_READ_DATA     [i])
		<< *(in_SPR_READ_DATA_VAL [i]);
    for (uint32_t i=0; i<_param->_nb_spr_write; i++)
      {
	if (_param->_have_port_ooo_engine_id)
	  sensitive << *(in_SPR_WRITE_OOO_ENGINE_ID [i]);
	sensitive << *(in_SPR_WRITE_VAL        [i])
		  << *(in_SPR_WRITE_NUM_REG    [i])
		  << *(in_SPR_WRITE_DATA       [i]);
      }
#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information

    (*(out_READ_QUEUE_OUT_DATA_RC_VAL)) (*(in_SPR_READ_ACK                [0]));
    (*(out_READ_QUEUE_OUT_DATA_RC_VAL)) (*(in_SPR_READ_DATA_VAL           [0]));
    
    (*(out_READ_QUEUE_OUT_DATA_RC    )) (*(in_SPR_READ_DATA               [0]));
    
    for (uint32_t i=0; i<_param->_nb_spr_write ; i++)
      {
	(*(out_READ_QUEUE_OUT_DATA_RC_VAL)) (*(in_SPR_WRITE_VAL        [i]));
	if (_param->_have_port_ooo_engine_id)
	  (*(out_READ_QUEUE_OUT_DATA_RC_VAL)) (*(in_SPR_WRITE_OOO_ENGINE_ID [i]));
	(*(out_READ_QUEUE_OUT_DATA_RC_VAL)) (*(in_SPR_WRITE_NUM_REG    [i]));

	(*(out_READ_QUEUE_OUT_DATA_RC    )) (*(in_SPR_WRITE_VAL        [i]));
	if (_param->_have_port_ooo_engine_id)
	  (*(out_READ_QUEUE_OUT_DATA_RC    )) (*(in_SPR_WRITE_OOO_ENGINE_ID [i]));
	(*(out_READ_QUEUE_OUT_DATA_RC    )) (*(in_SPR_WRITE_NUM_REG    [i]));
	(*(out_READ_QUEUE_OUT_DATA_RC    )) (*(in_SPR_WRITE_DATA       [i]));
      }
#endif    

#endif
    log_printf(FUNC,Read_queue,"Read_queue","End");
  };
  
  Read_queue::~Read_queue (void)
  {
    log_printf(FUNC,Read_queue,"~Read_queue","Begin");

#ifdef STATISTICS
    log_printf(INFO,Read_queue,"~Read_queue","Generate Statistics file");

    _stat->generate_file(statistics(0));
    
    delete _stat;
#endif

#ifdef SYSTEMC
    log_printf(INFO,Read_queue,"~Read_queue","Deallocation");

    deallocation ();
#endif

    log_printf(FUNC,Read_queue,"~Read_queue","End");
  };

}; // end namespace read_queue
}; // end namespace read_unit
}; // end namespace multi_read_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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