#ifndef morpheo_behavioural_Allocation_h
#define morpheo_behavioural_Allocation_h

/*
 * $Id: Allocation.h 128 2009-06-26 08:43:23Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Common/include/Debug.h"

// ======================================================================
// =====[ ALLOCATION / DELETE of ARRAY ]=================================
// ======================================================================
#define ALLOC0(var,type)                        \
  do                                            \
    {                                           \
      var = new type;                           \
    } while (0)

#define ALLOC1(var,type,s1)                     \
  do                                            \
    {                                           \
      var = new type [s1];                      \
    } while (0)

#define ALLOC2(var,type,s1,s2)                   \
  do                                             \
    {                                            \
      var = new type * [s1];                     \
      for (uint32_t it1=0; it1<s1; ++it1)        \
        {                                        \
          var [it1] = new type [s2];             \
        }                                        \
    } while (0)

#define ALLOC3(var,type,s1,s2,s3)                \
  do                                             \
    {                                            \
      var = new type ** [s1];                    \
      for (uint32_t it1=0; it1<s1; ++it1)        \
        {                                        \
          var [it1] = new type * [s2];           \
          for (uint32_t it2=0; it2<s2; ++it2)    \
            {                                    \
              var [it1][it2] = new type [s3];    \
            }                                    \
        }                                        \
    } while (0)

#define ALLOC4(var,type,s1,s2,s3,s4)                    \
  do                                                    \
    {                                                   \
      var = new type *** [s1];                          \
      for (uint32_t it1=0; it1<s1; ++it1)               \
        {                                               \
          var [it1] = new type ** [s2];                 \
          for (uint32_t it2=0; it2<s2; ++it2)           \
            {                                           \
              var [it1][it2] = new type * [s3];         \
              for (uint32_t it3=0; it3<s3; ++it3)       \
                {                                       \
                  var [it1][it2][it3] = new type [s4];  \
                }                                       \
            }                                           \
        }                                               \
    } while (0)

#define DELETE0(var)                            \
  do                                            \
    {                                           \
      delete var;                               \
    } while (0)

#define DELETE1(var,s1)                         \
  do                                            \
    {                                           \
      delete [] var;                            \
    } while (0)

#define DELETE2(var,s1,s2)                      \
  do                                            \
    {                                            \
      for (uint32_t it1=0; it1<s1; ++it1)        \
        {                                        \
          delete [] var [it1];                   \
        }                                        \
      delete [] var;                             \
    } while (0)

#define DELETE3(var,s1,s2,s3)                    \
  do                                             \
    {                                            \
      for (uint32_t it1=0; it1<s1; ++it1)        \
        {                                        \
          for (uint32_t it2=0; it2<s2; ++it2)    \
            {                                    \
              delete [] var [it1][it2];          \
            }                                    \
          delete [] var [it1];                   \
        }                                        \
      delete [] var;                             \
    } while (0)

#define DELETE4(var,s1,s2,s3,s4)                        \
  do                                                    \
    {                                                   \
      for (uint32_t it1=0; it1<s1; ++it1)               \
        {                                               \
          for (uint32_t it2=0; it2<s2; ++it2)           \
            {                                           \
              for (uint32_t it3=0; it3<s3; ++it3)       \
                {                                       \
                  delete [] var [it1][it2][it3];        \
                }                                       \
              delete [] var [it1][it2];                 \
            }                                           \
          delete [] var [it1];                          \
        }                                               \
      delete [] var;                                    \
    } while (0)

// ======================================================================
// =====[ ALLOCATION / DELETE of SIGNAL]=================================
// ======================================================================

// Help to allocate interface
#define INTERFACE_PRINT(name) log_printf(TRACE,Allocation,FUNCTION,"<%s> : Interface's creation : %s (%s, %d)",_name.c_str(),name,__FILE__,__LINE__);
#define PRINT_SIGNAL_ADDRESS(name,address) log_printf(TRACE,Allocation,FUNCTION,"Signal : %s 0x%.8x(%s, %d)",name,(uint32_t)((uint64_t)(address)),__FILE__,__LINE__);
#define PRINT_SIZE_NUL(component,interface,signal) log_printf(TRACE,Allocation,FUNCTION,_("<%s> %s.%s.%s : size is nul."),_name.c_str(),component->get_name().c_str(),interface->get_name().c_str(),signal);
#define TEST_SIGNAL(name,address) PRINT_SIGNAL_ADDRESS(name,address); TEST_PTR(address)
#define INSTANCE_FOREIGN_PRINT(name) log_printf(TRACE,Allocation,FUNCTION,"<%s> : %s (%s, %d)",_name.c_str(),name,__FILE__,__LINE__);

// ----------------------------------------------------------------------
// -----[ NO ITERATION ]-------------------------------------------------
// ----------------------------------------------------------------------

#define __ALLOC0_SIGNAL(sig, name, type)        \
  do                                            \
    {                                           \
      sig = new type (name);                    \
    } while (0)

#ifdef POSITION
#define ALLOC0_INTERFACE_BEGIN( name, direction, localisation, str)     \
  INTERFACE_PRINT(name);                                                \
  morpheo::behavioural::Interface_fifo * interface = _interfaces->set_interface( name, direction, localisation, str);
#else
#define ALLOC0_INTERFACE_BEGIN( name, direction, localisation, str)     \
  INTERFACE_PRINT(name);                                                \
  morpheo::behavioural::Interface_fifo * interface = _interfaces->set_interface( name);
#endif

#define ALLOC0_INTERFACE_END()

#define ALLOC0_VAL_ACK_IN(  sig, name, type)                            \
  do                                                                    \
    {                                                                   \
      sig = interface->set_signal_valack_in (name, type);               \
    } while (0)

#define ALLOC0_VAL_ACK_OUT( sig, name, type)                            \
  do                                                                    \
    {                                                                   \
      sig = interface->set_signal_valack_out(name, type);               \
    } while (0)
                                                                  
#define ALLOC0_VALACK_IN(     sig, type)                                \
  do                                                                    \
    {                                                                   \
      sig = interface->set_signal_valack_in (type);                     \
    } while (0)
                                                                    
#define ALLOC0_VALACK_OUT(    sig, type)                                \
  do                                                                    \
    {                                                                   \
      sig = interface->set_signal_valack_out(type);                     \
    } while (0)
                                                                     
#define ALLOC0_SIGNAL_IN(  sig, name, type, size)                       \
  do                                                                    \
    {                                                                   \
      if (size > 0)                                                     \
        {                                                               \
          sig = interface->set_signal_in <type> (name, size);           \
        }                                                               \
      else                                                              \
        {                                                               \
          PRINT_SIZE_NUL(_component,interface,name);                    \
        }                                                               \
    } while (0)

#define ALLOC0_SIGNAL_OUT( sig, name, type, size)                       \
  do                                                                    \
    {                                                                   \
      if (size > 0)                                                     \
        {                                                               \
          sig = interface->set_signal_out<type> (name, size);           \
        }                                                               \
      else                                                              \
        {                                                               \
          PRINT_SIZE_NUL(_component,interface,name);                    \
        }                                                               \
    } while (0)

#define DELETE0_SIGNAL( sig, size)                                      \
  do                                                                    \
    {                                                                   \
      if (size > 0)                                                     \
        {                                                               \
          delete sig;                                                   \
        }                                                               \
    } while (0)

#define ALLOC0_FOREIGN_SIGNAL_IN(  sig, interface, name, type, size)    \
  do                                                                    \
    {                                                                   \
      if (size > 0)                                                     \
        {                                                               \
          std::string str = (toString("in")+"_"+((interface!="")?(toString(interface)+"_"):toString(""))+toString(name)); \
          sig = new SC_IN    (type) (str.c_str());                      \
        }                                                               \
    } while (0)

#define ALLOC0_FOREIGN_SIGNAL_OUT( sig, interface, name, type, size)    \
  do                                                                    \
    {                                                                   \
      if (size > 0)                                                     \
        {                                                               \
          std::string str = (toString("out")+"_"+((interface!="")?(toString(interface)+"_"):toString(""))+toString(name)); \
          sig = new SC_OUT   (type) (str.c_str());                      \
        }                                                               \
    } while (0)

#define DELETE0_FOREIGN_SIGNAL( sig, size)                              \
  do                                                                    \
    {                                                                   \
      DELETE0_SIGNAL(sig,size);                                         \
    } while (0)

#define INSTANCE0_FOREIGN_SIGNAL(component, sig, type, name, size)      \
  do                                                                    \
    {                                                                   \
      if (size > 0)                                                     \
        {                                                               \
          INSTANCE_FOREIGN_PRINT(name);                                 \
          _component->set_sc_signal<type>(_name,name,static_cast<void*>(component->sig)); \
        }                                                               \
    } while (0)

#define ALLOC0_SC_SIGNAL(  sig, name, type)                             \
  do                                                                    \
    {                                                                   \
      sig = new sc_signal<type> (name);                                 \
      PRINT_SIGNAL_ADDRESS(name,sig);                                   \
    } while (0)

#define INSTANCE0_SC_SIGNAL(component, sig)                             \
  do                                                                    \
    {                                                                   \
      TEST_SIGNAL(component->sig->name(),component->sig);               \
      TEST_SIGNAL(sig           ->name(),sig);                          \
      (*(component->sig)) (*(sig));                                     \
    } while (0)

#define _INSTANCE0_SC_SIGNAL(component, sig1,sig2)                      \
  do                                                                    \
    {                                                                   \
      TEST_SIGNAL(component->sig1->name(),component->sig1);             \
      TEST_SIGNAL(sig2           ->name(),sig2);                        \
      (*(component->sig1)) (*(sig2));                                   \
    } while (0)

#define DELETE0_SC_SIGNAL( sig)                                         \
  do                                                                    \
    {                                                                   \
      PRINT_SIGNAL_ADDRESS("",sig);                                     \
      delete sig;                                                       \
    } while (0)

// ----------------------------------------------------------------------
// -----[ ITERATION 1 ]--------------------------------------------------
// ----------------------------------------------------------------------

#define __ALLOC1_INTERFACE_BEGIN(name, x1)                              \
  INTERFACE_PRINT(name);                                                \
  const std::string interface_name = name;                              \
  const uint32_t iterator_1 = x1;

#define __ALLOC1_INTERFACE_END(x1)

#define __ALLOC1_SIGNAL_IN( sig, name, type)                            \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN(type) * [iterator_1];                             \
      std::string separator="_";                                        \
      for (uint32_t it1=0; it1<iterator_1; it1++)                       \
        {                                                               \
          std::string str = "in_"+interface_name+separator+toString(it1)+separator+name; \
          sig [it1] = new SC_IN(type) (str.c_str());                    \
        }                                                               \
    } while (0)


#define __ALLOC1_SIGNAL_OUT( sig, name, type)                           \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT(type) * [iterator_1];                            \
      std::string separator="_";                                        \
      for (uint32_t it1=0; it1<iterator_1; it1++)                       \
        {                                                               \
          std::string str = "out_"+interface_name+separator+toString(it1)+separator+name; \
          sig [it1] = new SC_OUT(type) (str.c_str());                   \
        }                                                               \
    } while (0)

#ifdef POSITION
#define ALLOC1_INTERFACE_BEGIN( name, direction, localisation, str, x1) \
  INTERFACE_PRINT(name);                                                \
  uint32_t iterator_1 = 0;                                              \
  morpheo::behavioural::Interface_fifo ** interface;                    \
  {                                                                     \
    std::string separator="_";                                          \
    iterator_1 = x1;                                                    \
    interface = new morpheo::behavioural::Interface_fifo * [iterator_1]; \
    for (uint32_t it1=0; it1<iterator_1; it1++)                         \
      {                                                                 \
        interface [it1] = _interfaces->set_interface( name+separator+toString(it1), direction, localisation, str); \
      }                                                                 \
  }
#else
#define ALLOC1_INTERFACE_BEGIN( name, direction, localisation, str, x1) \
  INTERFACE_PRINT(name);                                                \
  uint32_t iterator_1 = 0;                                              \
  morpheo::behavioural::Interface_fifo ** interface;                    \
  {                                                                     \
    std::string separator="_";                                          \
    iterator_1 = x1;                                                    \
    interface = new morpheo::behavioural::Interface_fifo * [iterator_1]; \
    for (uint32_t it1=0; it1<iterator_1; it1++)                         \
      {                                                                 \
        interface [it1] = _interfaces->set_interface( name+separator+toString(it1)); \
      }                                                                 \
  }
#endif

#define ALLOC1_INTERFACE_END(x1)                                        \
  do                                                                    \
    {                                                                   \
      delete [] interface;                                              \
    } while (0)

#define ALLOC1_VAL_ACK_IN( sig, name, type)                             \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (Tcontrol_t) * [iterator_1];                      \
      for (uint32_t it1=0; it1<iterator_1; it1++)                       \
        {                                                               \
          sig [it1] = interface[it1]->set_signal_valack_in (name, type); \
        }                                                               \
    } while (0)

#define ALLOC1_VAL_ACK_OUT(sig, name, type)                             \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT(Tcontrol_t) * [iterator_1];                      \
      for (uint32_t it1=0; it1<iterator_1; it1++)                       \
        {                                                               \
          sig [it1] = interface[it1]->set_signal_valack_out(name, type); \
        }                                                               \
    } while (0)

#define ALLOC1_VALACK_IN(    sig, type)                                 \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (Tcontrol_t) * [iterator_1];                      \
      for (uint32_t it1=0; it1<iterator_1; it1++)                       \
        {                                                               \
          sig [it1] = interface[it1]->set_signal_valack_in (type);      \
        }                                                               \
    } while (0)

#define ALLOC1_VALACK_OUT(   sig, type)                                 \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT(Tcontrol_t) * [iterator_1];                      \
      for (uint32_t it1=0; it1<iterator_1; it1++)                       \
        {                                                               \
          sig [it1] = interface[it1]->set_signal_valack_out(type);      \
        }                                                               \
    } while (0)

#define ALLOC1_SIGNAL_IN( sig, name, type, size)                        \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (type) * [iterator_1];                            \
      for (uint32_t it1=0; it1<iterator_1; it1++)                       \
        {                                                               \
          if (size > 0)                                                 \
            {                                                           \
              sig [it1] = interface[it1]->set_signal_in <type> (name, size); \
            }                                                           \
          else                                                          \
            {                                                           \
              PRINT_SIZE_NUL(_component,interface[it1],name);           \
            }                                                           \
        }                                                               \
    } while (0)

#define ALLOC1_SIGNAL_OUT(sig, name, type, size)                        \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT(type) * [iterator_1];                            \
      for (uint32_t it1=0; it1<iterator_1; it1++)                       \
        {                                                               \
          if (size > 0)                                                 \
            {                                                           \
              sig [it1] = interface[it1]->set_signal_out<type> (name, size); \
            }                                                           \
          else                                                          \
            {                                                           \
              PRINT_SIZE_NUL(_component,interface[it1],name);           \
            }                                                           \
        }                                                               \
    } while (0)

#define DELETE1_SIGNAL(sig, x1, size)                                   \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          if (size > 0)                                                 \
            {                                                           \
              delete sig[it1];                                          \
            }                                                           \
        }                                                               \
      delete [] sig;                                                    \
    } while (0)

#define ALLOC1_FOREIGN_SIGNAL_IN(sig, interface, name, type, size,x1)   \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (type) * [x1];                                    \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        if (size > 0)                                                   \
          {                                                             \
            std::string str = (toString("in")+"_"+((interface!="")?(toString(interface)+"_"):toString(""))+toString(it1)+"_"+toString(name)); \
            sig [it1] = new SC_IN (type) (str.c_str());                 \
          }                                                             \
    } while (0)

#define ALLOC1_FOREIGN_SIGNAL_OUT(sig, interface, name, type, size,x1)  \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT (type) * [x1];                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        if (size > 0)                                                   \
          {                                                             \
            std::string str = (toString("out")+"_"+((interface!="")?(toString(interface)+"_"):toString(""))+toString(it1)+"_"+toString(name)); \
            sig [it1] = new SC_OUT (type) (str.c_str());                \
          }                                                             \
    } while (0)

#define DELETE1_FOREIGN_SIGNAL( sig, size,x1)                           \
  do                                                                    \
    {                                                                   \
      DELETE1_SIGNAL(sig,x1,size);                                      \
    } while (0)

#define ALLOC1_SC_SIGNAL( sig, name, type, x1)                          \
  do                                                                    \
    {                                                                   \
      sig = new sc_signal<type> * [x1];                                 \
      {                                                                 \
        std::string separator="_";                                      \
        std::string str;                                                \
        for (uint32_t it1=0; it1<x1; it1++)                             \
          {                                                             \
            str = name+separator+toString(it1);                         \
            sig [it1] = new sc_signal<type> (str.c_str());              \
            PRINT_SIGNAL_ADDRESS(str.c_str(),sig[it1]);                 \
          }                                                             \
      }                                                                 \
    } while (0)

#define INSTANCE1_SC_SIGNAL(component, sig, x1)                         \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          TEST_SIGNAL(component->sig [it1]->name(),component->sig [it1]); \
          TEST_SIGNAL(sig            [it1]->name(),sig            [it1]); \
          (*(component->sig[it1])) (*(sig[it1]));                       \
        }                                                               \
    } while (0)

#define _INSTANCE1_SC_SIGNAL(component, sig1, sig2, x1)                 \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          TEST_SIGNAL(component->sig1 [it1]->name(),component->sig1 [it1]); \
          TEST_SIGNAL(sig2            [it1]->name(),sig2            [it1]); \
          (*(component->sig1[it1])) (*(sig2[it1]));                     \
        }                                                               \
    } while (0)

#define DELETE1_SC_SIGNAL(sig, x1)                                      \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          PRINT_SIGNAL_ADDRESS("",sig[it1]);                            \
          delete sig[it1];                                              \
        }                                                               \
      delete [] sig;                                                    \
    } while (0)

// ----------------------------------------------------------------------
// -----[ ITERATION 2 ]--------------------------------------------------
// ----------------------------------------------------------------------

#ifdef POSITION
#define ALLOC2_INTERFACE_BEGIN( name, direction, localisation, str, x1, x2) \
  INTERFACE_PRINT(name);                                                \
  uint32_t iterator_1 = 0;                                              \
  uint32_t iterator_2 = 0;                                              \
  morpheo::behavioural::Interface_fifo *** interface;                   \
  {                                                                     \
    std::string separator="_";                                          \
    iterator_1 = x1;                                                    \
    interface = new morpheo::behavioural::Interface_fifo ** [iterator_1]; \
    for (uint32_t it1=0; it1<iterator_1; it1++)                         \
      {                                                                 \
        iterator_2 = x2;                                                \
        interface [it1] = new morpheo::behavioural::Interface_fifo * [iterator_2]; \
        for (uint32_t it2=0; it2<iterator_2; it2++)                     \
          {                                                             \
            interface [it1][it2] = _interfaces->set_interface( name+separator+toString(it1)+separator+toString(it2), direction, localisation, str); \
          }                                                             \
      }                                                                 \
  }
#else
#define ALLOC2_INTERFACE_BEGIN( name, direction, localisation, str, x1, x2) \
  INTERFACE_PRINT(name);                                                \
  uint32_t iterator_1 = 0;                                              \
  uint32_t iterator_2 = 0;                                              \
  morpheo::behavioural::Interface_fifo *** interface;                   \
  {                                                                     \
    std::string separator="_";                                          \
    iterator_1 = x1;                                                    \
    interface = new morpheo::behavioural::Interface_fifo ** [iterator_1]; \
    for (uint32_t it1=0; it1<iterator_1; it1++)                         \
      {                                                                 \
        iterator_2 = x2;                                                \
        interface [it1] = new morpheo::behavioural::Interface_fifo * [iterator_2]; \
        for (uint32_t it2=0; it2<iterator_2; it2++)                     \
          {                                                             \
            interface [it1][it2] = _interfaces->set_interface( name+separator+toString(it1)+separator+toString(it2)); \
          }                                                             \
      }                                                                 \
  }
#endif

#define ALLOC2_INTERFACE_END(x1, x2)                                    \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        delete [] interface [it1];                                      \
      delete [] interface;                                              \
    } while (0)

#define _ALLOC2_VAL_ACK_IN( sig, name, type, x1, x2)                    \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (Tcontrol_t) ** [x1];                             \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_IN (Tcontrol_t) * [x2];                    \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = interface[it1][it2]->set_signal_valack_in (name, type); \
            }                                                           \
        }                                                               \
    } while (0)

#define _ALLOC2_VAL_ACK_OUT( sig, name, type, x1, x2)                   \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT (Tcontrol_t) ** [x1];                            \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_OUT (Tcontrol_t) * [x2];                   \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = interface[it1][it2]->set_signal_valack_out (name, type); \
            }                                                           \
        }                                                               \
    } while (0)

#define _ALLOC2_VALACK_IN(    sig,type, x1, x2)                         \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (Tcontrol_t) ** [x1];                             \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_IN (Tcontrol_t) * [x2];                    \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = interface[it1][it2]->set_signal_valack_in (type); \
            }                                                           \
        }                                                               \
    } while (0)

#define _ALLOC2_VALACK_OUT(    sig,type, x1, x2)                        \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT (Tcontrol_t) ** [x1];                            \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_OUT (Tcontrol_t) * [x2];                   \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = interface[it1][it2]->set_signal_valack_out (type); \
            }                                                           \
        }                                                               \
    } while (0)

#define _ALLOC2_SIGNAL_IN( sig, name, type, size, x1, x2)               \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (type) ** [x1];                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_IN (type) * [x2];                          \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              if (size > 0)                                             \
                {                                                       \
                  sig [it1][it2] = interface[it1][it2]->set_signal_in <type> (name, size); \
                }                                                       \
              else                                                      \
                {                                                       \
                  PRINT_SIZE_NUL(_component,interface[it1][it2],name);  \
                }                                                       \
            }                                                           \
        }                                                               \
    } while (0)

#define _ALLOC2_SIGNAL_OUT( sig, name, type, size, x1, x2)              \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT (type) ** [x1];                                  \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_OUT (type) * [x2];                         \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              if (size > 0)                                             \
                {                                                       \
                  sig [it1][it2] = interface[it1][it2]->set_signal_out <type> (name, size); \
                }                                                       \
              else                                                      \
                {                                                       \
                  PRINT_SIZE_NUL(_component,interface[it1][it2],name);  \
                }                                                       \
            }                                                           \
        }                                                               \
    } while (0)

#define ALLOC2_VAL_ACK_IN( sig, name, type      ) _ALLOC2_VAL_ACK_IN( sig, name, type      , iterator_1, iterator_2) 
#define ALLOC2_VAL_ACK_OUT(sig, name, type      ) _ALLOC2_VAL_ACK_OUT(sig, name, type      , iterator_1, iterator_2) 
#define ALLOC2_VALACK_IN(  sig,       type      ) _ALLOC2_VALACK_IN(  sig,       type      , iterator_1, iterator_2) 
#define ALLOC2_VALACK_OUT( sig,       type      ) _ALLOC2_VALACK_OUT( sig,       type      , iterator_1, iterator_2) 
#define ALLOC2_SIGNAL_IN(  sig, name, type, size) _ALLOC2_SIGNAL_IN(  sig, name, type, size, iterator_1, iterator_2) 
#define ALLOC2_SIGNAL_OUT( sig, name, type, size) _ALLOC2_SIGNAL_OUT( sig, name, type, size, iterator_1, iterator_2) 

#define DELETE2_SIGNAL(sig, x1,x2, size)                                \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              if (size > 0)                                             \
                {                                                       \
                  delete sig[it1][it2];                                 \
                }                                                       \
            }                                                           \
          delete [] sig[it1];                                           \
        }                                                               \
      delete [] sig;                                                    \
    } while (0)

#define ALLOC2_FOREIGN_SIGNAL_IN( sig, interface, name, type, size, x1, x2) \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (type) ** [x1];                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_IN (type) * [x2];                          \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            if (size > 0)                                               \
              {                                                         \
                std::string str = (toString("in")+"_"+((interface!="")?(toString(interface)+"_"):toString(""))+toString(it1)+"_"+toString(it2)+"_"+toString(name)); \
                sig [it1][it2] = new SC_IN    (type) (str.c_str());     \
              }                                                         \
        }                                                               \
    } while (0)

#define ALLOC2_FOREIGN_SIGNAL_OUT( sig, interface, name, type, size, x1, x2) \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT (type) ** [x1];                                  \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_OUT (type) * [x2];                         \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            if (size > 0)                                               \
              {                                                         \
                std::string str = (toString("out")+"_"+((interface!="")?(toString(interface)+"_"):toString(""))+toString(it1)+"_"+toString(it2)+"_"+toString(name)); \
                sig [it1][it2] = new SC_IN    (type) (str.c_str());     \
              }                                                         \
        }                                                               \
    } while (0)

#define DELETE2_FOREIGN_SIGNAL( sig, size,x1,x2)            \
  do                                                        \
    {                                                       \
      DELETE2_SIGNAL(sig,x1,x2,size);                       \
    } while (0)

#define ALLOC2_SC_SIGNAL( sig, name, type, x1, x2)                      \
  do                                                                    \
    {                                                                   \
      sig = new sc_signal<type> ** [x1];                                \
      {                                                                 \
        std::string separator="_";                                      \
        std::string str;                                                \
        for (uint32_t it1=0; it1<x1; it1++)                             \
          {                                                             \
            sig [it1] = new sc_signal<type> * [x2];                     \
            for (uint32_t it2=0; it2<x2; it2++)                         \
              {                                                         \
                str = name+separator+toString(it1)+separator+toString(it2); \
                sig [it1][it2] = new sc_signal<type> (str.c_str());     \
                PRINT_SIGNAL_ADDRESS(str.c_str(),sig[it1][it2]);        \
              }                                                         \
          }                                                             \
      }                                                                 \
    } while (0)

#define INSTANCE2_SC_SIGNAL(component, sig, x1, x2)                     \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        for (uint32_t it2=0; it2<x2; it2++)                             \
          {                                                             \
            TEST_SIGNAL(component->sig  [it1][it2]->name(),component->sig  [it1][it2]); \
            TEST_SIGNAL(sig             [it1][it2]->name(),sig             [it1][it2]); \
            (*(component->sig[it1][it2])) (*(sig[it1][it2]));           \
          }                                                             \
    } while (0)

#define _INSTANCE2_SC_SIGNAL(component, sig1, sig2, x1, x2)             \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        for (uint32_t it2=0; it2<x2; it2++)                             \
          {                                                             \
            TEST_SIGNAL(component->sig1 [it1][it2]->name(),component->sig1 [it1][it2]); \
            TEST_SIGNAL(sig2            [it1][it2]->name(),sig2            [it1][it2]); \
            (*(component->sig1[it1][it2])) (*(sig2[it1][it2]));         \
          }                                                             \
    } while (0)

#define DELETE2_SC_SIGNAL(sig,x1,x2)                                    \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              PRINT_SIGNAL_ADDRESS("",sig[it1][it2]);                   \
              delete sig[it1][it2];                                     \
            }                                                           \
          delete [] sig[it1];                                           \
        }                                                               \
      delete [] sig;                                                    \
    } while (0)

// ----------------------------------------------------------------------
// -----[ ITERATION 3 ]--------------------------------------------------
// ----------------------------------------------------------------------

#ifdef POSITION
#define ALLOC3_INTERFACE_BEGIN( name, direction, localisation, str, x1, x2, x3) \
  INTERFACE_PRINT(name);                                                \
  uint32_t iterator_1 = 0;                                              \
  uint32_t iterator_2 = 0;                                              \
  uint32_t iterator_3 = 0;                                              \
  morpheo::behavioural::Interface_fifo **** interface;                  \
  {                                                                     \
    std::string separator="_";                                          \
    iterator_1 = x1;                                                    \
    interface = new morpheo::behavioural::Interface_fifo *** [iterator_1]; \
    for (uint32_t it1=0; it1<iterator_1; it1++)                         \
      {                                                                 \
        iterator_2 = x2;                                                \
        interface [it1] = new morpheo::behavioural::Interface_fifo ** [iterator_2]; \
        for (uint32_t it2=0; it2<iterator_2; it2++)                     \
          {                                                             \
            iterator_3 = x3;                                            \
            interface [it1][it2] = new morpheo::behavioural::Interface_fifo * [iterator_3]; \
            for (uint32_t it3=0; it3<iterator_3; it3++)                 \
              {                                                         \
                interface [it1][it2][it3] = _interfaces->set_interface( name+separator+toString(it1)+separator+toString(it2)+separator+toString(it3), direction, localisation, str); \
              }                                                         \
          }                                                             \
      }                                                                 \
  }
#else
#define ALLOC3_INTERFACE_BEGIN( name, direction, localisation, str, x1, x2, x3) \
  INTERFACE_PRINT(name);                                                \
  uint32_t iterator_1 = 0;                                              \
  uint32_t iterator_2 = 0;                                              \
  uint32_t iterator_3 = 0;                                              \
  morpheo::behavioural::Interface_fifo **** interface;                  \
  {                                                                     \
    std::string separator="_";                                          \
    iterator_1 = x1;                                                    \
    interface = new morpheo::behavioural::Interface_fifo *** [iterator_1]; \
    for (uint32_t it1=0; it1<iterator_1; it1++)                         \
      {                                                                 \
        iterator_2 = x2;                                                \
        interface [it1] = new morpheo::behavioural::Interface_fifo ** [iterator_2]; \
        for (uint32_t it2=0; it2<iterator_2; it2++)                     \
          {                                                             \
            iterator_3 = x3;                                            \
            interface [it1][it2] = new morpheo::behavioural::Interface_fifo * [iterator_3]; \
            for (uint32_t it3=0; it3<iterator_3; it3++)                 \
              {                                                         \
                interface [it1][it2][it3] = _interfaces->set_interface( name+separator+toString(it1)+separator+toString(it2)+separator+toString(it3)); \
              }                                                         \
          }                                                             \
      }                                                                 \
  }
#endif

#define ALLOC3_INTERFACE_END(x1, x2, x3)                         \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            delete [] interface [it1][it2];                             \
          delete [] interface [it1];                                    \
        }                                                               \
      delete [] interface;                                              \
    } while (0)

// #define _ALLOC3_VAL_ACK_IN( sig, name, type, x1, x2, x3)
// #define _ALLOC3_VAL_ACK_OUT( sig, name, type, x1, x2, x3)

#define _ALLOC3_VALACK_IN(    sig,type, x1, x2, x3)                     \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (Tcontrol_t) *** [x1];                            \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_IN (Tcontrol_t) ** [x2];                   \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = new SC_IN (Tcontrol_t) * [x3];           \
              for (uint32_t it3=0; it3<x3; it3++)                       \
                {                                                       \
                  sig [it1][it2][it3] = interface[it1][it2][it3]->set_signal_valack_in (type); \
                }                                                       \
            }                                                           \
        }                                                               \
    } while (0)

#define _ALLOC3_VALACK_OUT(    sig,type, x1, x2, x3)                    \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT (Tcontrol_t) *** [x1];                           \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_OUT (Tcontrol_t) ** [x2];                  \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = new SC_OUT (Tcontrol_t) * [x3];          \
              for (uint32_t it3=0; it3<x3; it3++)                       \
                {                                                       \
                  sig [it1][it2][it3] = interface[it1][it2][it3]->set_signal_valack_out (type); \
                }                                                       \
            }                                                           \
        }                                                               \
    } while (0)


#define _ALLOC3_SIGNAL_IN( sig, name, type, size, x1, x2,x3)            \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (type) *** [x1];                                  \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_IN (type) ** [x2];                         \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = new SC_IN (type) * [x3];                 \
              for (uint32_t it3=0; it3<x3; it3++)                       \
                {                                                       \
                  if (size > 0)                                         \
                    {                                                   \
                      sig [it1][it2][it3] = interface[it1][it2][it3]->set_signal_in <type> (name, size); \
                    }                                                   \
                  else                                                  \
                    {                                                   \
                      PRINT_SIZE_NUL(_component,interface[it1][it2][it3],name); \
                    }                                                   \
                }                                                       \
            }                                                           \
        }                                                               \
    } while (0)

#define _ALLOC3_SIGNAL_OUT( sig, name, type, size, x1, x2,x3)           \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT (type) *** [x1];                                 \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_OUT (type) ** [x2];                        \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = new SC_OUT (type) * [x3];                \
              for (uint32_t it3=0; it3<x3; it3++)                       \
                {                                                       \
                  if (size > 0)                                         \
                    {                                                   \
                      sig [it1][it2][it3] = interface[it1][it2][it3]->set_signal_out <type> (name, size); \
                    }                                                   \
                  else                                                  \
                    {                                                   \
                      PRINT_SIZE_NUL(_component,interface[it1][it2][it3],name); \
                    }                                                   \
                }                                                       \
            }                                                           \
        }                                                               \
    } while (0)

// #define ALLOC3_VAL_ACK_IN( sig, name, type      ) _ALLOC3_VAL_ACK_IN( sig, name, type      , iterator_1, iterator_2, iterator_3) 
// #define ALLOC3_VAL_ACK_OUT(sig, name, type      ) _ALLOC3_VAL_ACK_OUT(sig, name, type      , iterator_1, iterator_2, iterator_3) 
#define ALLOC3_VALACK_IN(  sig,       type      ) _ALLOC3_VALACK_IN(  sig,       type      , iterator_1, iterator_2, iterator_3) 
#define ALLOC3_VALACK_OUT( sig,       type      ) _ALLOC3_VALACK_OUT( sig,       type      , iterator_1, iterator_2, iterator_3) 
#define ALLOC3_SIGNAL_IN(  sig, name, type, size) _ALLOC3_SIGNAL_IN(  sig, name, type, size, iterator_1, iterator_2, iterator_3) 
#define ALLOC3_SIGNAL_OUT( sig, name, type, size) _ALLOC3_SIGNAL_OUT( sig, name, type, size, iterator_1, iterator_2, iterator_3) 

#define DELETE3_SIGNAL(sig, x1, x2, x3, size)                           \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              for (uint32_t it3=0; it3<x3; it3++)                       \
                {                                                       \
                  if (size > 0)                                         \
                    {                                                   \
                      delete sig[it1][it2][it3];                        \
                    }                                                   \
                }                                                       \
              delete [] sig[it1][it2];                                  \
            }                                                           \
          delete [] sig[it1];                                           \
        }                                                               \
      delete [] sig;                                                    \
    } while (0)

#define ALLOC3_FOREIGN_SIGNAL_IN( sig, interface, name, type, size, x1, x2,x3)     \
  do                                                                    \
    {                                                                   \
      sig = new SC_IN (type) *** [x1];                                  \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_IN (type) ** [x2];                         \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = new SC_IN (type) * [x3];                 \
              for (uint32_t it3=0; it3<x3; it3++)                       \
                if (size > 0)                                           \
                  {                                                     \
                    std::string str = (toString("in")+"_"+((interface!="")?(toString(interface)+"_"):toString(""))+toString(it1)+"_"+toString(it2)+"_"+toString(it3)+"_"+toString(name)); \
                    sig [it1][it2][it3] = new SC_IN (type) (str.c_str()); \
                  }                                                     \
            }                                                           \
        }                                                               \
    } while (0)

#define ALLOC3_FOREIGN_SIGNAL_OUT( sig, interface, name, type, size, x1, x2,x3)    \
  do                                                                    \
    {                                                                   \
      sig = new SC_OUT (type) *** [x1];                                 \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          sig [it1] = new SC_OUT (type) ** [x2];                        \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              sig [it1][it2] = new SC_OUT (type) * [x3];                \
              for (uint32_t it3=0; it3<x3; it3++)                       \
                if (size > 0)                                           \
                  {                                                     \
                    std::string str = (toString("out")+"_"+((interface!="")?(toString(interface)+"_"):toString(""))+toString(it1)+"_"+toString(it2)+"_"+toString(it3)+"_"+toString(name)); \
                    sig [it1][it2][it3] = new SC_OUT(type) (str.c_str()); \
                  }                                                     \
            }                                                           \
        }                                                               \
    } while (0)

#define DELETE3_FOREIGN_SIGNAL( sig, size,x1,x2,x3)            \
  do                                                           \
    {                                                          \
      DELETE3_SIGNAL(sig,x1,x2,x3,size);                       \
    } while (0)

#define ALLOC3_SC_SIGNAL( sig, name, type, x1, x2, x3)                  \
  do                                                                    \
    {                                                                   \
      sig = new sc_signal<type> *** [x1];                               \
      {                                                                 \
        std::string separator="_";                                      \
        std::string str;                                                \
        for (uint32_t it1=0; it1<x1; it1++)                             \
          {                                                             \
            sig [it1] = new sc_signal<type> ** [x2];                    \
            for (uint32_t it2=0; it2<x2; it2++)                         \
              {                                                         \
                sig [it1][it2] = new sc_signal<type> * [x3];            \
                for (uint32_t it3=0; it3<x3; it3++)                     \
                  {                                                     \
                    str = name+separator+toString(it1)+separator+toString(it2)+separator+toString(it3); \
                    sig [it1][it2][it3] = new sc_signal<type> (str.c_str()); \
                    PRINT_SIGNAL_ADDRESS(str.c_str(),sig[it1][it2][it3]); \
                  }                                                     \
              }                                                         \
          }                                                             \
      }                                                                 \
    } while (0)

#define INSTANCE3_SC_SIGNAL(component, sig, x1, x2, x3)                 \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        for (uint32_t it2=0; it2<x2; it2++)                             \
          for (uint32_t it3=0; it3<x3; it3++)                           \
            {                                                           \
              TEST_SIGNAL(component->sig  [it1][it2][it3]->name(),component->sig  [it1][it2][it3]); \
              TEST_SIGNAL(sig             [it1][it2][it3]->name(),sig             [it1][it2][it3]); \
              (*(component->sig[it1][it2][it3])) (*(sig[it1][it2][it3])); \
            }                                                           \
    } while (0)

#define _INSTANCE3_SC_SIGNAL(component, sig1, sig2, x1, x2, x3)         \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        for (uint32_t it2=0; it2<x2; it2++)                             \
          for (uint32_t it3=0; it3<x3; it3++)                           \
            {                                                           \
              TEST_SIGNAL(component->sig1 [it1][it2][it3]->name(),component->sig1 [it1][it2][it3]); \
              TEST_SIGNAL(sig2            [it1][it2][it3]->name(),sig2            [it1][it2][it3]); \
              (*(component->sig1[it1][it2][it3])) (*(sig2[it1][it2][it3])); \
            }                                                           \
    } while (0)

#define DELETE3_SC_SIGNAL(sig,x1,x2,x3)                                 \
  do                                                                    \
    {                                                                   \
      for (uint32_t it1=0; it1<x1; it1++)                               \
        {                                                               \
          for (uint32_t it2=0; it2<x2; it2++)                           \
            {                                                           \
              for (uint32_t it3=0; it3<x3; it3++)                       \
                {                                                       \
                  PRINT_SIGNAL_ADDRESS("",sig[it1][it2][it3]);          \
                  delete sig[it1][it2][it3];                            \
                }                                                       \
              delete [] sig[it1][it2];                                  \
            }                                                           \
          delete [] sig[it1];                                           \
        }                                                               \
      delete [] sig;                                                    \
    } while (0)

#endif
