#ifdef SYSTEMC
/*
 * $Id: Dependency_checking_unit_genMealy.cpp 123 2009-06-08 20:43:30Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Dependency_checking_unit/include/Dependency_checking_unit.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace rename_unit {
namespace register_translation_unit {
namespace dependency_checking_unit {


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

    if (PORT_READ(in_NRESET))
      {
//     Tcontrol_t         val                [_param->_nb_inst_insert];
//     Tcontrol_t         ack                [_param->_nb_inst_insert];
    Tcontext_t         front_end_id       [_param->_nb_inst_insert];
    Tcontext_t         context_id         [_param->_nb_inst_insert];
    Tcontrol_t         read_ra            [_param->_nb_inst_insert];
    Tgeneral_address_t num_reg_ra_log     [_param->_nb_inst_insert];
    Tgeneral_address_t num_reg_ra_phy     [_param->_nb_inst_insert];
    Tcontrol_t         read_rb            [_param->_nb_inst_insert];
    Tgeneral_address_t num_reg_rb_log     [_param->_nb_inst_insert];
    Tgeneral_address_t num_reg_rb_phy     [_param->_nb_inst_insert];
    Tcontrol_t         read_rc            [_param->_nb_inst_insert];
    Tspecial_address_t num_reg_rc_log     [_param->_nb_inst_insert];
    Tspecial_address_t num_reg_rc_phy     [_param->_nb_inst_insert];
    Tcontrol_t         write_rd           [_param->_nb_inst_insert];
    Tgeneral_address_t num_reg_rd_log     [_param->_nb_inst_insert];
    Tgeneral_address_t num_reg_rd_phy_old [_param->_nb_inst_insert];
    Tgeneral_address_t num_reg_rd_phy_new [_param->_nb_inst_insert];
    Tcontrol_t         write_re           [_param->_nb_inst_insert];
    Tspecial_address_t num_reg_re_log     [_param->_nb_inst_insert];
    Tspecial_address_t num_reg_re_phy_old [_param->_nb_inst_insert];
    Tspecial_address_t num_reg_re_phy_new [_param->_nb_inst_insert];

    // 4 dependency :
    //  * Read  after Read  : it's a false dependency
    //  * Write after Read  : it's inhibt by rename process
    //  * Write after Write : for the num_reg_old
    //  * Read  after Write : dependency
    for (uint32_t i=0; i<_param->_nb_inst_insert; i++)
      {
 	// =====[ Input ]==================================================
// 	val                [i] = PORT_READ(in_RENAME_IN_VAL                [i]);
// 	ack                [i] = PORT_READ(in_RENAME_OUT_ACK               [i]);
	front_end_id       [i] = (_param->_have_port_front_end_id)?PORT_READ(in_RENAME_IN_FRONT_END_ID [i]):0;
	context_id         [i] = (_param->_have_port_context_id  )?PORT_READ(in_RENAME_IN_CONTEXT_ID   [i]):0;
	read_ra            [i] = PORT_READ(in_RENAME_IN_READ_RA            [i]);
	num_reg_ra_log     [i] = PORT_READ(in_RENAME_IN_NUM_REG_RA_LOG     [i]);
	num_reg_ra_phy     [i] = PORT_READ(in_RENAME_IN_NUM_REG_RA_PHY     [i]);
	read_rb            [i] = PORT_READ(in_RENAME_IN_READ_RB            [i]);
	num_reg_rb_log     [i] = PORT_READ(in_RENAME_IN_NUM_REG_RB_LOG     [i]);
	num_reg_rb_phy     [i] = PORT_READ(in_RENAME_IN_NUM_REG_RB_PHY     [i]);
	read_rc            [i] = PORT_READ(in_RENAME_IN_READ_RC            [i]);
	num_reg_rc_log     [i] = PORT_READ(in_RENAME_IN_NUM_REG_RC_LOG     [i]);
	num_reg_rc_phy     [i] = PORT_READ(in_RENAME_IN_NUM_REG_RC_PHY     [i]);
	write_rd           [i] = PORT_READ(in_RENAME_IN_WRITE_RD           [i]);
	num_reg_rd_log     [i] = PORT_READ(in_RENAME_IN_NUM_REG_RD_LOG     [i]);
	num_reg_rd_phy_old [i] = PORT_READ(in_RENAME_IN_NUM_REG_RD_PHY_OLD [i]);
	num_reg_rd_phy_new [i] = PORT_READ(in_RENAME_IN_NUM_REG_RD_PHY_NEW [i]);
	write_re           [i] = PORT_READ(in_RENAME_IN_WRITE_RE           [i]);
	num_reg_re_log     [i] = PORT_READ(in_RENAME_IN_NUM_REG_RE_LOG     [i]);
	num_reg_re_phy_old [i] = PORT_READ(in_RENAME_IN_NUM_REG_RE_PHY_OLD [i]);
	num_reg_re_phy_new [i] = PORT_READ(in_RENAME_IN_NUM_REG_RE_PHY_NEW [i]);
	
        log_printf(TRACE,Dependency_checking_unit,FUNCTION,"  * (before) [%d] %.2d %.2d, %.1d %.2d %.5d, %.1d %.2d %.5d, %.1d %.2d %.5d, %.1d %.2d %.5d -> %.5d, %.1d %.2d %.5d -> %.5d",
                   i,
                   front_end_id       [i],
                   context_id         [i],
                   read_ra            [i],
                   num_reg_ra_log     [i],
                   num_reg_ra_phy     [i],
                   read_rb            [i],
                   num_reg_rb_log     [i],
                   num_reg_rb_phy     [i],
                   read_rc            [i],
                   num_reg_rc_log     [i],
                   num_reg_rc_phy     [i],
                   write_rd           [i],
                   num_reg_rd_log     [i],
                   num_reg_rd_phy_old [i],
                   num_reg_rd_phy_new [i],
                   write_re           [i],
                   num_reg_re_log     [i],
                   num_reg_re_phy_old [i],
                   num_reg_re_phy_new [i]);

	// ================================================================
	// =====[ Write after Write ]======================================
	// ================================================================
	if (write_rd [i])
	  // Inverse scan : with x < y, instruction x is before in the sequential order program that the instruction y
	  for (int32_t j=i-1; j>=0; j--)
	    if ((write_rd       [j] == 1                 ) and
		(num_reg_rd_log [j] == num_reg_rd_log [i]) and
		(front_end_id   [j] == front_end_id   [i]) and
		(context_id     [j] == context_id     [i]) )
	      {
                log_printf(TRACE,Dependency_checking_unit,FUNCTION,"    * RD :  WAW dependency with inst[%d].RD",j);
		num_reg_rd_phy_old [i] = num_reg_rd_phy_new [j];
		break; // find the most recently dependency
	      }
	
	if (write_re [i])
	  // Inverse scan : with x < y, instruction x is before in the sequential order program that the instruction y
	  for (int32_t j=i-1; j>=0; j--)
	    if ((write_re       [j] == 1                 ) and
		(num_reg_re_log [j] == num_reg_re_log [i]) and
		(front_end_id   [j] == front_end_id   [i]) and
		(context_id     [j] == context_id     [i]) )
	      {
                log_printf(TRACE,Dependency_checking_unit,FUNCTION,"    * RE : WAW dependency with inst[%d].RE",j);
		num_reg_re_phy_old [i] = num_reg_re_phy_new [j];
		break; // find the most recently dependency
	      }
	// ================================================================
	// =====[ Read  after Write ]======================================
	// ================================================================
	if (read_ra [i])
	  // Inverse scan : with x < y, instruction x is before in the sequential order program that the instruction y
	  for (int32_t j=i-1; j>=0; j--)
	    if ((write_rd       [j] == 1                 ) and
		(num_reg_rd_log [j] == num_reg_ra_log [i]) and
		(front_end_id   [j] == front_end_id   [i]) and
		(context_id     [j] == context_id     [i]) )
	      {
                log_printf(TRACE,Dependency_checking_unit,FUNCTION,"    * RA :  RAW dependency with inst[%d].RD",j);
		num_reg_ra_phy [i] = num_reg_rd_phy_new [j];
		break; // find the most recently dependency
	      }

	if (read_rb [i])
	  // Inverse scan : with x < y, instruction x is before in the sequential order program that the instruction y
	  for (int32_t j=i-1; j>=0; j--)
	    if ((write_rd       [j] == 1                 ) and
		(num_reg_rd_log [j] == num_reg_rb_log [i]) and
		(front_end_id   [j] == front_end_id   [i]) and
		(context_id     [j] == context_id     [i]) )
	      {
                log_printf(TRACE,Dependency_checking_unit,FUNCTION,"    * RB :  RAW dependency with inst[%d].RD",j);
		num_reg_rb_phy [i] = num_reg_rd_phy_new [j];
		break; // find the most recently dependency
	      }

	if (read_rc [i])
	  // Inverse scan : with x < y, instruction x is before in the sequential order program that the instruction y
	  for (int32_t j=i-1; j>=0; j--)
	    if ((write_re       [j] == 1                 ) and
		(num_reg_re_log [j] == num_reg_rc_log [i]) and
		(front_end_id   [j] == front_end_id   [i]) and
		(context_id     [j] == context_id     [i]) )
	      {
                log_printf(TRACE,Dependency_checking_unit,FUNCTION,"    * RC :  RAW dependency with inst[%d].RE",j);
		num_reg_rc_phy [i] = num_reg_re_phy_new [j];
		break; // find the most recently dependency
	      }

        log_printf(TRACE,Dependency_checking_unit,FUNCTION,"  * (after ) [%d] %.2d %.2d, %.1d %.2d %.5d, %.1d %.2d %.5d, %.1d %.2d %.5d, %.1d %.2d %.5d -> %.5d, %.1d %.2d %.5d -> %.5d",
                   i,
                   front_end_id       [i],
                   context_id         [i],
                   read_ra            [i],
                   num_reg_ra_log     [i],
                   num_reg_ra_phy     [i],
                   read_rb            [i],
                   num_reg_rb_log     [i],
                   num_reg_rb_phy     [i],
                   read_rc            [i],
                   num_reg_rc_log     [i],
                   num_reg_rc_phy     [i],
                   write_rd           [i],
                   num_reg_rd_log     [i],
                   num_reg_rd_phy_old [i],
                   num_reg_rd_phy_new [i],
                   write_re           [i],
                   num_reg_re_log     [i],
                   num_reg_re_phy_old [i],
                   num_reg_re_phy_new [i]);

 	// =====[ Output ]=================================================
// 	PORT_WRITE(out_RENAME_OUT_VAL                [i], val                [i]);
// 	PORT_WRITE(out_RENAME_IN_ACK                 [i], ack                [i]);
	if (_param->_have_port_front_end_id)
	PORT_WRITE(out_RENAME_OUT_FRONT_END_ID       [i], front_end_id       [i]);
	if (_param->_have_port_context_id)
	PORT_WRITE(out_RENAME_OUT_CONTEXT_ID         [i], context_id         [i]);
	PORT_WRITE(out_RENAME_OUT_READ_RA            [i], read_ra            [i]);
#ifdef DEBUG
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RA_LOG     [i], num_reg_ra_log     [i]);
#endif
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RA_PHY     [i], num_reg_ra_phy     [i]);
	PORT_WRITE(out_RENAME_OUT_READ_RB            [i], read_rb            [i]);
#ifdef DEBUG
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RB_LOG     [i], num_reg_rb_log     [i]);
#endif
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RB_PHY     [i], num_reg_rb_phy     [i]);
	PORT_WRITE(out_RENAME_OUT_READ_RC            [i], read_rc            [i]);
#ifdef DEBUG
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RC_LOG     [i], num_reg_rc_log     [i]);
#endif
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RC_PHY     [i], num_reg_rc_phy     [i]);
	PORT_WRITE(out_RENAME_OUT_WRITE_RD           [i], write_rd           [i]);
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RD_LOG     [i], num_reg_rd_log     [i]);
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RD_PHY_OLD [i], num_reg_rd_phy_old [i]);
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RD_PHY_NEW [i], num_reg_rd_phy_new [i]);
	PORT_WRITE(out_RENAME_OUT_WRITE_RE           [i], write_re           [i]);
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RE_LOG     [i], num_reg_re_log     [i]);
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RE_PHY_OLD [i], num_reg_re_phy_old [i]);
	PORT_WRITE(out_RENAME_OUT_NUM_REG_RE_PHY_NEW [i], num_reg_re_phy_new [i]);
      }
      }

    log_end(Dependency_checking_unit,FUNCTION);
  };

}; // end namespace dependency_checking_unit
}; // end namespace register_translation_unit
}; // end namespace rename_unit
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core
}; // end namespace behavioural
}; // end namespace morpheo              
#endif
