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

#include "Behavioural/Generic/Shifter/include/Shifter.h"

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


#ifdef SYSTEMC
  Shifter::Shifter (sc_module_name name,
#else
  Shifter::Shifter (string name,
#endif
#ifdef STATISTICS
		    morpheo::behavioural::Parameters_Statistics             param_statistics,
#endif
		    morpheo::behavioural::generic::shifter::Parameters param ):
		    _name   (name)
		    ,_param (param)
  {
#ifdef STATISTICS
    // Allocation of statistics
    _stat = new Statistics (static_cast<string>(_name),
			    param_statistics          ,
			    param);
#endif

#ifdef VHDL_TESTBENCH
    // Creation of a testbench
    //  -> port
    //  -> clock's signals
    _vhdl_testbench = new Vhdl_Testbench (_name);
    vhdl_testbench_port           (*_vhdl_testbench);
    _vhdl_testbench->set_clock    ("in_CLOCK",false);
#endif

#ifdef VHDL
    // generate the vhdl
    vhdl();
#endif

#ifdef SYSTEMC
    allocation ();

#if (defined(STATISTICS) || defined (VHDL_TESTBENCH))
    SC_METHOD (transition);
    dont_initialize ();
    sensitive_pos << *(in_CLOCK);
#endif

    SC_METHOD (genMealy_shift);
    dont_initialize ();
    sensitive_neg << *(in_CLOCK);
    for (uint32_t i=0; i<param._nb_port; i++)
      {
	sensitive << (*(in_SHIFTER_DATA      [i]));
	if (param._shift_value == 0)
	sensitive << (*(in_SHIFTER_SHIFT     [i]));
	if (param._direction   == external_direction)
	sensitive << (*(in_SHIFTER_DIRECTION [i]));
	if (_param._rotate     == external_rotate)
	sensitive << (*(in_SHIFTER_TYPE      [i]));
	if (param._carry       == external_carry)
	sensitive << (*(in_SHIFTER_CARRY     [i]));
	if (param._carry       == external_completion)
	  if (_param._type_completion_bool == true)
	    sensitive << (*(in_SHIFTER_CARRY_IN  [i]));
	  else
	    sensitive << (*(in_SHIFTER_COMPLETION[i]));
      }

#ifdef SYSTEMCASS_SPECIFIC
    // List dependency information
    for (uint32_t i=0; i<param._nb_port; i++)
      {
	(*(out_SHIFTER_DATA [i])) (*(in_SHIFTER_DATA      [i]));
	if (param._shift_value == 0)
	(*(out_SHIFTER_DATA [i])) (*(in_SHIFTER_SHIFT     [i]));
	if (param._direction   == external_direction)
	(*(out_SHIFTER_DATA [i])) (*(in_SHIFTER_DIRECTION [i]));
	if (_param._rotate     == external_rotate)
	(*(out_SHIFTER_DATA [i])) (*(in_SHIFTER_TYPE      [i]));
	if (param._carry       == external_carry)
	(*(out_SHIFTER_DATA [i])) (*(in_SHIFTER_CARRY     [i]));
	if (param._carry       == external_completion)
	if (_param._type_completion_bool == true)
	(*(out_SHIFTER_DATA [i])) (*(in_SHIFTER_CARRY_IN  [i]));
	else
	(*(out_SHIFTER_DATA [i])) (*(in_SHIFTER_COMPLETION[i]));
      }
#endif    

#endif
  };
  
  Shifter::~Shifter (void)
  {
#ifdef SYSTEMC
    deallocation ();
#endif

#ifdef VHDL_TESTBENCH
    // generate the test bench
    _vhdl_testbench->generate_file();
    delete _vhdl_testbench;
#endif

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

}; // end namespace shifter
}; // end namespace generic

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