#ifndef morpheo_behavioural_Interface_fifo_h
#define morpheo_behavioural_Interface_fifo_h

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

#include "Behavioural/include/Interface.h"

namespace morpheo              {
namespace behavioural          {

  typedef enum {VAL, ACK} val_ack_t;
}; // end namespace behavioural

  template<> inline std::string toString<morpheo::behavioural::val_ack_t>(const morpheo::behavioural::val_ack_t& x)
  {
    switch (x)
      {
      case morpheo::behavioural::VAL : return "val"; break;
      case morpheo::behavioural::ACK : return "ack"; break;
      default    : return ""      ; break;
      }
  }

namespace behavioural          {

  class Interface_fifo : public Interface
  {
  private   : std::list<Signal *>      * _list_signal_val;
  private   : std::list<Signal *>      * _list_signal_ack;

#ifdef VHDL_TESTBENCH
  private   : bool                  _test_exhaustive;
  private   : std::list<uint32_t>      * _list_cycle   ;
#endif

   // -----[ methods ]---------------------------------------------------
  public    :                       Interface_fifo       (std::string         name        
#ifdef POSITION
							  ,direction_t    direction   
							  ,localisation_t localisation
#endif
							  ,Tusage_t       usage=USE_ALL
							  );
    
  public    :                       Interface_fifo       (const Interface_fifo & interface_fifo);
  public    :                       ~Interface_fifo      ();

  public    : Signal *              set_signal_valack    (std::string          name     ,
							  direction_t     direction,
							  val_ack_t       val_ack  ,
							  presence_port_t presence_port = PORT_VHDL_YES_TESTBENCH_YES);

  private   : void                  save_ptr             (Signal *        signal   ,
							  val_ack_t       val_ack  );

#ifdef SYSTEMC
  public    : sc_in <bool> *        set_signal_valack_in (val_ack_t       val_ack  ,
							  presence_port_t presence_port=PORT_VHDL_YES_TESTBENCH_YES)
    {
      return set_signal_valack_in (toString(val_ack) ,val_ack, presence_port);
    }

  public    : sc_in <bool> *        set_signal_valack_in (std::string          name     ,
							  val_ack_t       val_ack  ,
							  presence_port_t presence_port=PORT_VHDL_YES_TESTBENCH_YES)
    {
      log_printf(FUNC,Behavioural,"set_signal_valack_in","Begin");

      sc_in <bool> * port = set_signal_in <bool> (name, 1, presence_port);
      
      save_ptr(_list_signal->back(), val_ack);
      
      log_printf(FUNC,Behavioural,"set_signal_valack_in","End");
      return port;
    };

  public    : sc_out<bool> *        set_signal_valack_out(val_ack_t       val_ack  ,
							  presence_port_t presence_port=PORT_VHDL_YES_TESTBENCH_YES)
    {
      return set_signal_valack_out(toString(val_ack) ,val_ack, presence_port);
    }

  public    : sc_out<bool> *        set_signal_valack_out(std::string          name     ,
							  val_ack_t       val_ack  ,
							  presence_port_t presence_port=PORT_VHDL_YES_TESTBENCH_YES)
    {
      log_printf(FUNC,Behavioural,"set_signal_valack_out","Begin");

      sc_out<bool> * port = set_signal_out<bool> (name, 1, presence_port);
      
      save_ptr(_list_signal->back(), val_ack);
      
      log_printf(FUNC,Behavioural,"set_signal_valack_out","End");
      return port;
    };
#endif

#ifdef VHDL_TESTBENCH
  public    : uint32_t              get_cycle            (void);

  public    : void                  testbench            (void);
  public    : bool                  testbench_transaction(void);
  public    : void                  testbench_cycle      (void);
  public    : std::string           testbench_test       (Vhdl   * & vhdl        ,
							  std::string     counter_name,
							  std::string     reset_name  );

  public    : std::string           testbench_test_transaction (Vhdl * & vhdl);
#endif
  };

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

#endif
