#ifdef SYSTEMC
/*
 * $Id$
 *
 * [ Description ]
 * 
 */

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

using namespace std;
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
