#ifdef SYSTEMC
/*
 * $Id: Shifter_genMealy_shift.cpp 82 2008-05-01 16:48:45Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Generic/Shifter/include/Shifter.h"
#include "Common/include/BitManipulation.h"
#include <bitset>

namespace morpheo {
namespace behavioural {
namespace generic {
namespace shifter {

  void Shifter::genMealy_shift (void)
  {
    for (uint32_t i=0; i<_param->_nb_port; i++)
      {
	// Read
	Tdata_t      data_in     = PORT_READ(in_SHIFTER_DATA [i]);
	Tdata_t      data_out    = data_in;
	Tshift_t     shift_value = _param->_shift_value;
	if (shift_value == 0)
	  shift_value = PORT_READ(in_SHIFTER_SHIFT [i]);

 	Tdirection_t direction; 
 	if (_param->_direction == external_direction)
	  direction = PORT_READ(in_SHIFTER_DIRECTION [i]);
	else
	  direction = _param->_internal_direction;

	Ttype_t      type;
	if (_param->_rotate    == external_rotate)
	  type      = PORT_READ(in_SHIFTER_TYPE      [i]);
	else
	  type      = _param->_internal_type; 

	Tcarry_t     carry;	
	if (_param->_carry     == external_carry)
	  carry     = PORT_READ(in_SHIFTER_CARRY     [i]);
	else
	  carry     = _param->_internal_carry; 
	
	if (type == _shift)
	  {
	    data_out = shift  <Tdata_t> (_param->_size_data, data_in, shift_value, direction == _left, carry == _arithmetic);

	    if (_param->_size_data_completion > 0)
	      {
		Tdata_t completion;

		if (_param->_type_completion_bool == true)
		  completion = (PORT_READ(in_SHIFTER_CARRY_IN   [i])==true)?1:0;
		else
		  completion = PORT_READ(in_SHIFTER_COMPLETION [i]);

		Tdata_t mask       ;

		if (direction == _left)
		  {
		    mask       = gen_mask<Tdata_t> (shift_value);
		  }
		else
		  {
		    mask       = gen_mask<Tdata_t> (shift_value)      << (_param->_size_data-shift_value);
		  }
		  
		data_out = (data_out & ~mask) | (completion & mask);
	      }
	  }
	else
	  data_out = rotate <Tdata_t> (_param->_size_data, data_in, shift_value, direction == _left);

	// Write
	PORT_WRITE(out_SHIFTER_DATA [i], data_out);
      }
  };

}; // end namespace shifter
}; // end namespace generic
}; // end namespace behavioural
}; // end namespace morpheo              
#endif
