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

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Register_unit/include/Register_unit.h"
#include "Behavioural/include/Allocation.h"

namespace morpheo {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace register_unit {

#undef  FUNCTION
#define FUNCTION "Register_unit::allocation"
  void Register_unit::allocation (
#ifdef STATISTICS
				  morpheo::behavioural::Parameters_Statistics * param_statistics
#else
				  void
#endif
				  )
  {
    log_printf(FUNC,Register_unit,FUNCTION,"Begin");

    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name       
					      ,"Register_unit"
#ifdef POSITION
					      ,COMBINATORY 
#endif
					      );

    _interfaces = entity->set_interfaces();

    // ~~~~~[ Interface : "" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Interface * interface = _interfaces->set_interface(""
#ifdef POSITION
						       ,IN
						       ,SOUTH,
						       "Generalist interface"
#endif
						       );

    in_CLOCK        = interface->set_signal_clk              ("clock" ,1, CLOCK_VHDL_YES);
    in_NRESET       = interface->set_signal_in  <Tcontrol_t> ("nreset",1, RESET_VHDL_YES);

    // ~~~~~[ Interface "gpr_read" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("gpr_read",IN,NORTH,_("Interface to read the register file"),_param->_nb_gpr_read);
      
      ALLOC1_VALACK_IN ( in_GPR_READ_VAL          ,VAL);
      ALLOC1_VALACK_OUT(out_GPR_READ_ACK          ,ACK);
      ALLOC1_SIGNAL_IN ( in_GPR_READ_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id);
      ALLOC1_SIGNAL_IN ( in_GPR_READ_NUM_REG      ,"num_reg"      ,Tgeneral_address_t,_param->_size_gpr_address);
      ALLOC1_SIGNAL_OUT(out_GPR_READ_DATA         ,"data"         ,Tgeneral_data_t   ,_param->_size_general_data);
      ALLOC1_SIGNAL_OUT(out_GPR_READ_DATA_VAL     ,"data_val"     ,Tcontrol_t        ,1);

      ALLOC1_INTERFACE_END(_param->_nb_gpr_read);
    }

    // ~~~~~[ Interface "gpr_write" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("gpr_write",IN,NORTH,_("Interface to write the register file"),_param->_nb_gpr_write);

      ALLOC1_VALACK_IN ( in_GPR_WRITE_VAL          ,VAL);
      ALLOC1_VALACK_OUT(out_GPR_WRITE_ACK          ,ACK);
      ALLOC1_SIGNAL_IN ( in_GPR_WRITE_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id);
      ALLOC1_SIGNAL_IN ( in_GPR_WRITE_NUM_REG      ,"num_reg"      ,Tgeneral_address_t,_param->_size_gpr_address);
      ALLOC1_SIGNAL_IN ( in_GPR_WRITE_DATA         ,"data"         ,Tgeneral_data_t   ,_param->_size_general_data);

      ALLOC1_INTERFACE_END(_param->_nb_gpr_write);
    }

    // ~~~~~[ Interface "spr_read" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("spr_read",IN,NORTH,_("Interface to read the register file"),_param->_nb_spr_read);
      
      ALLOC1_VALACK_IN ( in_SPR_READ_VAL          ,VAL);
      ALLOC1_VALACK_OUT(out_SPR_READ_ACK          ,ACK);
      ALLOC1_SIGNAL_IN ( in_SPR_READ_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id);
      ALLOC1_SIGNAL_IN ( in_SPR_READ_NUM_REG      ,"num_reg"      ,Tspecial_address_t,_param->_size_spr_address);
      ALLOC1_SIGNAL_OUT(out_SPR_READ_DATA         ,"data"         ,Tspecial_data_t   ,_param->_size_special_data);
      ALLOC1_SIGNAL_OUT(out_SPR_READ_DATA_VAL     ,"data_val"     ,Tcontrol_t        ,1);

      ALLOC1_INTERFACE_END(_param->_nb_spr_read);
    }

    // ~~~~~[ Interface "spr_write" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC1_INTERFACE_BEGIN("spr_write",IN,NORTH,_("Interface to write the register file"),_param->_nb_spr_write);

      ALLOC1_VALACK_IN ( in_SPR_WRITE_VAL          ,VAL);
      ALLOC1_VALACK_OUT(out_SPR_WRITE_ACK          ,ACK);
      ALLOC1_SIGNAL_IN ( in_SPR_WRITE_OOO_ENGINE_ID,"ooo_engine_id",Tcontext_t        ,_param->_size_ooo_engine_id);
      ALLOC1_SIGNAL_IN ( in_SPR_WRITE_NUM_REG      ,"num_reg"      ,Tspecial_address_t,_param->_size_spr_address);
      ALLOC1_SIGNAL_IN ( in_SPR_WRITE_DATA         ,"data"         ,Tspecial_data_t   ,_param->_size_special_data);

      ALLOC1_INTERFACE_END(_param->_nb_spr_write);
    }

    // ~~~~~[ Interface "insert_rob" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      ALLOC2_INTERFACE_BEGIN("insert_rob",IN,WEST,_("Interface to update status (insert)"),_param->_nb_ooo_engine,_param->_nb_inst_insert_rob [it1]);
      
      _ALLOC2_VALACK_IN ( in_INSERT_ROB_VAL       ,VAL                                                      ,_param->_nb_ooo_engine,_param->_nb_inst_insert_rob [it1]);
      _ALLOC2_VALACK_OUT(out_INSERT_ROB_ACK       ,ACK                                                      ,_param->_nb_ooo_engine,_param->_nb_inst_insert_rob [it1]);
      _ALLOC2_SIGNAL_IN ( in_INSERT_ROB_RD_USE    ,"rd_use"    ,Tcontrol_t        ,1                        ,_param->_nb_ooo_engine,_param->_nb_inst_insert_rob [it1]);
      _ALLOC2_SIGNAL_IN ( in_INSERT_ROB_RD_NUM_REG,"rd_num_reg",Tgeneral_address_t,_param->_size_gpr_address,_param->_nb_ooo_engine,_param->_nb_inst_insert_rob [it1]);
      _ALLOC2_SIGNAL_IN ( in_INSERT_ROB_RE_USE    ,"re_use"    ,Tcontrol_t        ,1                        ,_param->_nb_ooo_engine,_param->_nb_inst_insert_rob [it1]);
      _ALLOC2_SIGNAL_IN ( in_INSERT_ROB_RE_NUM_REG,"re_num_reg",Tspecial_address_t,_param->_size_spr_address,_param->_nb_ooo_engine,_param->_nb_inst_insert_rob [it1]);
      
      ALLOC2_INTERFACE_END(_param->_nb_ooo_engine,_param->_nb_inst_insert_rob [it1]);
    }

//     // ~~~~~[ Interface "retire_rob" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//     in_RETIRE_ROB_VAL            = new SC_IN (Tcontrol_t        )  ** [_param->_nb_ooo_engine];
//     out_RETIRE_ROB_ACK            = new SC_OUT(Tcontrol_t        )  ** [_param->_nb_ooo_engine];
//     in_RETIRE_ROB_RD_OLD_USE     = new SC_IN (Tcontrol_t        )  ** [_param->_nb_ooo_engine];
//     in_RETIRE_ROB_RD_OLD_NUM_REG = new SC_IN (Tgeneral_address_t)  ** [_param->_nb_ooo_engine];
//     in_RETIRE_ROB_RE_OLD_USE     = new SC_IN (Tcontrol_t        )  ** [_param->_nb_ooo_engine];
//     in_RETIRE_ROB_RE_OLD_NUM_REG = new SC_IN (Tspecial_address_t)  ** [_param->_nb_ooo_engine];
//     in_RETIRE_ROB_RD_NEW_USE     = new SC_IN (Tcontrol_t        )  ** [_param->_nb_ooo_engine];
//     in_RETIRE_ROB_RD_NEW_NUM_REG = new SC_IN (Tgeneral_address_t)  ** [_param->_nb_ooo_engine];
//     in_RETIRE_ROB_RE_NEW_USE     = new SC_IN (Tcontrol_t        )  ** [_param->_nb_ooo_engine];
//     in_RETIRE_ROB_RE_NEW_NUM_REG = new SC_IN (Tspecial_address_t)  ** [_param->_nb_ooo_engine];

//     for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
//       {
// 	uint32_t x=_param->_nb_inst_retire_rob [i];

// 	in_RETIRE_ROB_VAL            [i] = new SC_IN (Tcontrol_t        )  * [x];
// 	out_RETIRE_ROB_ACK            [i] = new SC_OUT(Tcontrol_t        )  * [x];
// 	in_RETIRE_ROB_RD_OLD_USE     [i] = new SC_IN (Tcontrol_t        )  * [x];
// 	in_RETIRE_ROB_RD_OLD_NUM_REG [i] = new SC_IN (Tgeneral_address_t)  * [x];
// 	in_RETIRE_ROB_RE_OLD_USE     [i] = new SC_IN (Tcontrol_t        )  * [x];
// 	in_RETIRE_ROB_RE_OLD_NUM_REG [i] = new SC_IN (Tspecial_address_t)  * [x];
// 	in_RETIRE_ROB_RD_NEW_USE     [i] = new SC_IN (Tcontrol_t        )  * [x];
// 	in_RETIRE_ROB_RD_NEW_NUM_REG [i] = new SC_IN (Tgeneral_address_t)  * [x];
// 	in_RETIRE_ROB_RE_NEW_USE     [i] = new SC_IN (Tcontrol_t        )  * [x];
// 	in_RETIRE_ROB_RE_NEW_NUM_REG [i] = new SC_IN (Tspecial_address_t)  * [x];

// 	for (uint32_t j=0; j<x; j++)
// 	  {
// 	    Interface_fifo * interface = _interfaces->set_interface("retire_rob_"+toString(i)+"_"+toString(j)
// #ifdef POSITION
// 								    ,IN
// 								    ,WEST
// 								    ,"Interface to update status (retire)"
// #endif
// 								    );


// 	    in_RETIRE_ROB_VAL            [i][j] = interface->set_signal_valack_in  (VAL);
// 	   out_RETIRE_ROB_ACK            [i][j] = interface->set_signal_valack_out (ACK);
// 	    in_RETIRE_ROB_RD_OLD_USE     [i][j] = interface->set_signal_in <Tcontrol_t        > ("rd_old_use"    , 1);
// 	    in_RETIRE_ROB_RD_OLD_NUM_REG [i][j] = interface->set_signal_in <Tgeneral_address_t> ("rd_old_num_reg", _param->_size_gpr_address);
// 	    in_RETIRE_ROB_RE_OLD_USE     [i][j] = interface->set_signal_in <Tcontrol_t        > ("re_old_use"    , 1);
// 	    in_RETIRE_ROB_RE_OLD_NUM_REG [i][j] = interface->set_signal_in <Tspecial_address_t> ("re_old_num_reg", _param->_size_spr_address);
// 	    in_RETIRE_ROB_RD_NEW_USE     [i][j] = interface->set_signal_in <Tcontrol_t        > ("rd_new_use"    , 1);
// 	    in_RETIRE_ROB_RD_NEW_NUM_REG [i][j] = interface->set_signal_in <Tgeneral_address_t> ("rd_new_num_reg", _param->_size_gpr_address);
// 	    in_RETIRE_ROB_RE_NEW_USE     [i][j] = interface->set_signal_in <Tcontrol_t        > ("re_new_use"    , 1);
// 	    in_RETIRE_ROB_RE_NEW_NUM_REG [i][j] = interface->set_signal_in <Tspecial_address_t> ("re_new_num_reg", _param->_size_spr_address);
// 	  }
//       }

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

    std::string name;
     
    component_gpr        = new morpheo::behavioural::generic::registerfile::RegisterFile::RegisterFile * [_param->_nb_ooo_engine];
    component_gpr_status = new morpheo::behavioural::generic::registerfile::RegisterFile::RegisterFile * [_param->_nb_ooo_engine];
    component_spr        = new morpheo::behavioural::generic::registerfile::RegisterFile::RegisterFile * [_param->_nb_ooo_engine];
    component_spr_status = new morpheo::behavioural::generic::registerfile::RegisterFile::RegisterFile * [_param->_nb_ooo_engine];
     
    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
      {
	name = _name+"_gpr_"+toString(i);
        log_printf(INFO,Register_unit,FUNCTION,_("Create   : %s"),name.c_str());

	component_gpr        [i] = new morpheo::behavioural::generic::registerfile::RegisterFile::RegisterFile 
	  (name.c_str()
#ifdef STATISTICS
	   ,param_statistics
#endif
	   ,_param->_param_gpr [i]
	   ,_usage
	   );
	 
	_component->set_component (component_gpr[i]->_component
#ifdef POSITION
				   , 50
				   , 50
				   , 10
				   , 10
#endif
				   );


	name = _name+"_gpr_status_"+toString(i);
        log_printf(INFO,Register_unit,FUNCTION,_("Create   : %s"),name.c_str());

	component_gpr_status [i] = new morpheo::behavioural::generic::registerfile::RegisterFile::RegisterFile
	  (name.c_str()
#ifdef STATISTICS
	   ,param_statistics
#endif
	   ,_param->_param_gpr_status [i]
	   ,_usage
	   );

	_component->set_component (component_gpr_status[i]->_component
#ifdef POSITION
				   , 50
				   , 50
				   , 10
				   , 10
#endif
				   );


	name = _name+"_spr_"+toString(i);
        log_printf(INFO,Register_unit,FUNCTION,_("Create   : %s"),name.c_str());
	 
	component_spr        [i] = new morpheo::behavioural::generic::registerfile::RegisterFile::RegisterFile 
	  (name.c_str()
#ifdef STATISTICS
	   ,param_statistics
#endif
	   ,_param->_param_spr [i]
	   ,_usage
	   );

	_component->set_component (component_spr[i]->_component
#ifdef POSITION
				   , 50
				   , 50
				   , 10
				   , 10
#endif
				   );

	name = _name+"_spr_status_"+toString(i);
        log_printf(INFO,Register_unit,FUNCTION,_("Create   : %s"),name.c_str());

	component_spr_status [i] = new morpheo::behavioural::generic::registerfile::RegisterFile::RegisterFile
	  (name.c_str()
#ifdef STATISTICS
	   ,param_statistics
#endif
	   ,_param->_param_spr_status [i]
	   ,_usage
	   );

	_component->set_component (component_spr_status[i]->_component
#ifdef POSITION
				   , 50
				   , 50
				   , 10
				   , 10
#endif
				   );
      }


    name = _name+"_glue";
    log_printf(INFO,Register_unit,FUNCTION,_("Create   : %s"),name.c_str());
     
    component_glue       = new morpheo::behavioural::core::multi_execute_loop::execute_loop::register_unit::register_unit_glue::Register_unit_Glue::Register_unit_Glue     
      (name.c_str()
#ifdef STATISTICS
       ,param_statistics
#endif
       ,_param->_param_glue
       ,_usage
       );

    _component->set_component (component_glue->_component
#ifdef POSITION
			       , 50
			       , 50
			       , 10
			       , 10
#endif
			       );
     
    // ~~~~~[ Instanciation ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
    std::string src,dest;
    
    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
      {
	src = _name+"_gpr_"+toString(i);
	
        log_printf(INFO,Register_unit,FUNCTION,_("Instance : %s"),src.c_str());
	
        {
          dest = _name;
#ifdef POSITION
          _component->interface_map (src ,"",
                                     dest,"");
#endif
          PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
          PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");
        }

	for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	  {
            dest = _name+"_glue";
            
#ifdef POSITION
            _component->interface_map (src ,    "read_"+toString(j),
                                       dest,"gpr_read_registerfile_"+toString(i)+"_"+toString(j));
#endif

	    COMPONENT_MAP(_component,src , "in_READ_"                                 +toString(j)+"_VAL",
                                     dest,"out_GPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_VAL");
	    COMPONENT_MAP(_component,src ,"out_READ_"                                 +toString(j)+"_ACK",
                                     dest, "in_GPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK");
	    COMPONENT_MAP(_component,src ,"out_READ_"                                 +toString(j)+"_DATA",
                                     dest, "in_GPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_DATA");

            dest = _name;

	    PORT_MAP     (_component,src , "in_READ_"    +toString(j)+"_ADDRESS",
                                     dest, "in_GPR_READ_"+toString(j)+"_NUM_REG");
	  }

	for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	  {
            dest = _name+"_glue";
            
#ifdef POSITION
            _component->interface_map (src ,    "write_"+toString(j),
                                       dest,"gpr_write_registerfile_"+toString(i)+"_"+toString(j));
#endif

	    COMPONENT_MAP(_component,src , "in_WRITE_"                                 +toString(j)+"_VAL",
                                     dest,"out_GPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_VAL");
	    COMPONENT_MAP(_component,src ,"out_WRITE_"                                 +toString(j)+"_ACK",
                                     dest, "in_GPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK");

            dest = _name;

	    PORT_MAP     (_component,src , "in_WRITE_"    +toString(j)+"_ADDRESS",
                                     dest, "in_GPR_WRITE_"+toString(j)+"_NUM_REG");
	    PORT_MAP     (_component,src , "in_WRITE_"    +toString(j)+"_DATA",
                                     dest, "in_GPR_WRITE_"+toString(j)+"_DATA");
	  }

      }// gpr
    
    {
      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	{
	  src = _name+"_gpr_status_"+toString(i);
	  
	  log_printf(INFO,Register_unit,FUNCTION,_("Instance : %s"),src.c_str());

          {
            dest = _name;
#ifdef POSITION
            _component->interface_map (src ,"",
                                       dest,"");
#endif
            PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
            PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");
          }
          
	  for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	    {
              dest = _name+"_glue";
              
#ifdef POSITION
              _component->interface_map (src ,    "read_"+toString(j),
                                         dest,"gpr_read_status_"+toString(i)+"_"+toString(j));
#endif

	      COMPONENT_MAP(_component,src , "in_READ_"                           +toString(j)+"_VAL",
                                       dest,"out_GPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_VAL");
	      COMPONENT_MAP(_component,src ,"out_READ_"                           +toString(j)+"_ACK",
                                       dest, "in_GPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_ACK");
	      COMPONENT_MAP(_component,src ,"out_READ_"                           +toString(j)+"_DATA",
                                       dest, "in_GPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_DATA_VAL");

              dest = _name;
              
              PORT_MAP     (_component,src , "in_READ_"    +toString(j)+"_ADDRESS",
                                       dest, "in_GPR_READ_"+toString(j)+"_NUM_REG");
	    }

	  uint32_t x=0;
	  for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	    {
              dest = _name+"_glue";
              
#ifdef POSITION
              _component->interface_map (src ,    "write_"+toString(j),
                                         dest,"gpr_write_status_"+toString(i)+"_"+toString(j));
#endif

              COMPONENT_MAP(_component,src , "in_WRITE_"                           +toString(x)+"_VAL",
                                       dest,"out_GPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_VAL");
              COMPONENT_MAP(_component,src ,"out_WRITE_"                           +toString(x)+"_ACK",
                                       dest, "in_GPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_ACK");
              COMPONENT_MAP(_component,src , "in_WRITE_"                           +toString(x)+"_DATA",
                                       dest,"out_GPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_DATA");
//                                     dest,"out_CONST_1");
              
              dest = _name;
              
              PORT_MAP     (_component,src , "in_WRITE_"    +toString(x)+"_ADDRESS",
                                       dest, "in_GPR_WRITE_"+toString(j)+"_NUM_REG");

              x++;
	    }
	  
	  for (uint32_t j=0; j<_param->_nb_inst_insert_rob [i]; j++)
	    {
              dest = _name+"_glue";
              
#ifdef POSITION
              _component->interface_map (src ,    "write_"+toString(j),
                                         dest,"insert_rob_gpr_status_"+toString(i)+"_"+toString(j));
#endif

              COMPONENT_MAP(_component,src , "in_WRITE_"                                +toString(x)+"_VAL",
                                       dest,"out_INSERT_ROB_GPR_STATUS_"+toString(i)+"_"+toString(j)+"_VAL");
              COMPONENT_MAP(_component,src ,"out_WRITE_"                                +toString(x)+"_ACK",
                                       dest, "in_INSERT_ROB_GPR_STATUS_"+toString(i)+"_"+toString(j)+"_ACK");
              COMPONENT_MAP(_component,src , "in_WRITE_"                                +toString(x)+"_DATA",
                                       dest,"out_INSERT_ROB_GPR_STATUS_"+toString(i)+"_"+toString(j)+"_DATA");
//                                     dest,"out_CONST_0");
              
              dest = _name;
              
              PORT_MAP     (_component,src , "in_WRITE_"                     +toString(x)+"_ADDRESS",
                                       dest, "in_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_RD_NUM_REG");

              x++;
	    }

	}
    }// gpr_status

    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
      {
	src = _name+"_spr_"+toString(i);
	
	log_printf(INFO,Register_unit,FUNCTION,_("Instance : %s"),src.c_str());
	
        {
          dest = _name;
#ifdef POSITION
          _component->interface_map (src ,"",
                                     dest,"");
#endif
          PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
          PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");
        }

	for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	  {
            dest = _name+"_glue";
            
#ifdef POSITION
            _component->interface_map (src ,    "read_"+toString(j),
                                       dest,"spr_read_registerfile_"+toString(i)+"_"+toString(j));
#endif

	    COMPONENT_MAP(_component,src , "in_READ_"                                 +toString(j)+"_VAL",
                                     dest,"out_SPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_VAL");
	    COMPONENT_MAP(_component,src ,"out_READ_"                                 +toString(j)+"_ACK",
                                     dest, "in_SPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK");
	    COMPONENT_MAP(_component,src ,"out_READ_"                                 +toString(j)+"_DATA",
                                     dest, "in_SPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_DATA");

            dest = _name;

	    PORT_MAP     (_component,src , "in_READ_"    +toString(j)+"_ADDRESS",
                                     dest, "in_SPR_READ_"+toString(j)+"_NUM_REG");
	  }

	for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	  {
            dest = _name+"_glue";
            
#ifdef POSITION
            _component->interface_map (src ,    "write_"+toString(j),
                                       dest,"spr_write_registerfile_"+toString(i)+"_"+toString(j));
#endif

	    COMPONENT_MAP(_component,src , "in_WRITE_"                                 +toString(j)+"_VAL",
                                     dest,"out_SPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_VAL");
	    COMPONENT_MAP(_component,src ,"out_WRITE_"                                 +toString(j)+"_ACK",
                                     dest, "in_SPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK");

            dest = _name;

	    PORT_MAP     (_component,src , "in_WRITE_"    +toString(j)+"_ADDRESS",
                                     dest, "in_SPR_WRITE_"+toString(j)+"_NUM_REG");
	    PORT_MAP     (_component,src , "in_WRITE_"    +toString(j)+"_DATA",
                                     dest, "in_SPR_WRITE_"+toString(j)+"_DATA");
	  }

      }// spr
    
    {
      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	{
	  src = _name+"_spr_status_"+toString(i);
	  
	  log_printf(INFO,Register_unit,FUNCTION,_("Instance : %s"),src.c_str());	
  
          {
            dest = _name;
#ifdef POSITION
            _component->interface_map (src ,"",
                                       dest,"");
#endif
            PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
            PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");
          }

	  for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	    {
              dest = _name+"_glue";
              
#ifdef POSITION
              _component->interface_map (src ,    "read_"+toString(j),
                                         dest,"spr_read_status_"+toString(i)+"_"+toString(j));
#endif

	      COMPONENT_MAP(_component,src , "in_READ_"                           +toString(j)+"_VAL",
                                       dest,"out_SPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_VAL");
	      COMPONENT_MAP(_component,src ,"out_READ_"                           +toString(j)+"_ACK",
                                       dest, "in_SPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_ACK");
	      COMPONENT_MAP(_component,src ,"out_READ_"                           +toString(j)+"_DATA",
                                       dest, "in_SPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_DATA_VAL");

              dest = _name;
              
              PORT_MAP     (_component,src , "in_READ_"    +toString(j)+"_ADDRESS",
                                       dest, "in_SPR_READ_"+toString(j)+"_NUM_REG");
	    }

	  uint32_t x=0;
	  for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	    {
              dest = _name+"_glue";
              
#ifdef POSITION
              _component->interface_map (src ,    "write_"+toString(j),
                                         dest,"spr_write_status_"+toString(i)+"_"+toString(j));
#endif

              COMPONENT_MAP(_component,src , "in_WRITE_"                           +toString(x)+"_VAL",
                                       dest,"out_SPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_VAL");
              COMPONENT_MAP(_component,src ,"out_WRITE_"                           +toString(x)+"_ACK",
                                       dest, "in_SPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_ACK");
              COMPONENT_MAP(_component,src , "in_WRITE_"                           +toString(x)+"_DATA",
                                       dest,"out_SPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_DATA");
//                                     dest,"out_CONST_1");
              
              dest = _name;
              
              PORT_MAP     (_component,src , "in_WRITE_"    +toString(x)+"_ADDRESS",
                                       dest, "in_SPR_WRITE_"+toString(j)+"_NUM_REG");

              x++;
	    }
	  
	  for (uint32_t j=0; j<_param->_nb_inst_insert_rob [i]; j++)
	    {
              dest = _name+"_glue";
              
#ifdef POSITION
              _component->interface_map (src ,    "write_"+toString(j),
                                         dest,"insert_rob_spr_status_"+toString(i)+"_"+toString(j));
#endif

              COMPONENT_MAP(_component,src , "in_WRITE_"                                +toString(x)+"_VAL",
                                       dest,"out_INSERT_ROB_SPR_STATUS_"+toString(i)+"_"+toString(j)+"_VAL");
              COMPONENT_MAP(_component,src ,"out_WRITE_"                                +toString(x)+"_ACK",
                                       dest, "in_INSERT_ROB_SPR_STATUS_"+toString(i)+"_"+toString(j)+"_ACK");
              COMPONENT_MAP(_component,src , "in_WRITE_"                                +toString(x)+"_DATA",
                                       dest,"out_INSERT_ROB_SPR_STATUS_"+toString(i)+"_"+toString(j)+"_DATA");
//                                     dest,"out_CONST_0");
              
              dest = _name;
              
              PORT_MAP     (_component,src , "in_WRITE_"                     +toString(x)+"_ADDRESS",
                                       dest, "in_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_RE_NUM_REG");

              x++;
	    }


	}
    }// spr_status

    {
      src = _name+"_glue";
     
      log_printf(INFO,Register_unit,FUNCTION,_("Instance : %s"),src.c_str());  
   
        {
          dest = _name;
#ifdef POSITION
          _component->interface_map (src ,"",
                                     dest,"");
#endif
          PORT_MAP(_component,src , "in_CLOCK" ,dest, "in_CLOCK");
          PORT_MAP(_component,src , "in_NRESET",dest, "in_NRESET");
        }

      for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	{
          dest = _name;
              
#ifdef POSITION
          _component->interface_map (src ,"gpr_read_"+toString(j),
                                     dest,"gpr_read_"+toString(j));
#endif

          PORT_MAP(_component,src , "in_GPR_READ_"+toString(j)+"_VAL",
                              dest, "in_GPR_READ_"+toString(j)+"_VAL");
          PORT_MAP(_component,src ,"out_GPR_READ_"+toString(j)+"_ACK",
                              dest,"out_GPR_READ_"+toString(j)+"_ACK");
	  if (_param->_have_port_ooo_engine_id == true)
          PORT_MAP(_component,src , "in_GPR_READ_"+toString(j)+"_OOO_ENGINE_ID",
                              dest, "in_GPR_READ_"+toString(j)+"_OOO_ENGINE_ID");
          PORT_MAP(_component,src ,"out_GPR_READ_"+toString(j)+"_DATA",
                              dest,"out_GPR_READ_"+toString(j)+"_DATA");
          PORT_MAP(_component,src ,"out_GPR_READ_"+toString(j)+"_DATA_VAL",
                              dest,"out_GPR_READ_"+toString(j)+"_DATA_VAL");

          // out_GPR_READ_REGISTERFILE_VAL   - gpr. in_READ_VAL
          //  in_GPR_READ_REGISTERFILE_ACK   - gpr.out_READ_ACK
          //  in_GPR_READ_REGISTERFILE_DATA  - gpr.out_READ_DATA
          
          // out_GPR_READ_STATUS_VAL         - gpr. in_READ_VAL
          //  in_GPR_READ_STATUS_ACK         - gpr.out_READ_ACK
          //  in_GPR_READ_STATUS_DATA_VAL    - gpr.out_READ_DATA
	}

      for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	{
          dest = _name;

#ifdef POSITION
          _component->interface_map (src ,"gpr_write_"+toString(j),
                                     dest,"gpr_write_"+toString(j));
#endif

          PORT_MAP(_component,src , "in_GPR_WRITE_"+toString(j)+"_VAL",
                              dest, "in_GPR_WRITE_"+toString(j)+"_VAL");
          PORT_MAP(_component,src ,"out_GPR_WRITE_"+toString(j)+"_ACK",
                              dest,"out_GPR_WRITE_"+toString(j)+"_ACK");
	  if (_param->_have_port_ooo_engine_id == true)
          PORT_MAP(_component,src , "in_GPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID",
                              dest, "in_GPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID");

          // out_GPR_WRITE_REGISTERFILE_VAL - gpr. in_WRITE_VAL
          //  in_GPR_WRITE_REGISTERFILE_ACK - gpr.out_WRITE_ACK
          // out_GPR_WRITE_STATUS_VAL       - gpr. in_WRITE_VAL
          //  in_GPR_WRITE_STATUS_ACK       - gpr.out_WRITE_ACK
          // out_GPR_WRITE_STATUS_DATA      - gpr. in_WRITE_DATA
	}

      for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	{
          dest = _name;
              
#ifdef POSITION
          _component->interface_map (src ,"spr_read_"+toString(j),
                                     dest,"spr_read_"+toString(j));
#endif

          PORT_MAP(_component,src , "in_SPR_READ_"+toString(j)+"_VAL",
                              dest, "in_SPR_READ_"+toString(j)+"_VAL");
          PORT_MAP(_component,src ,"out_SPR_READ_"+toString(j)+"_ACK",
                              dest,"out_SPR_READ_"+toString(j)+"_ACK");
	  if (_param->_have_port_ooo_engine_id == true)
          PORT_MAP(_component,src , "in_SPR_READ_"+toString(j)+"_OOO_ENGINE_ID",
                              dest, "in_SPR_READ_"+toString(j)+"_OOO_ENGINE_ID");
          PORT_MAP(_component,src ,"out_SPR_READ_"+toString(j)+"_DATA",
                              dest,"out_SPR_READ_"+toString(j)+"_DATA");
          PORT_MAP(_component,src ,"out_SPR_READ_"+toString(j)+"_DATA_VAL",
                              dest,"out_SPR_READ_"+toString(j)+"_DATA_VAL");

          // out_SPR_READ_REGISTERFILE_VAL   - spr. in_READ_VAL
          //  in_SPR_READ_REGISTERFILE_ACK   - spr.out_READ_ACK
          //  in_SPR_READ_REGISTERFILE_DATA  - spr.out_READ_DATA
          
          // out_SPR_READ_STATUS_VAL         - spr. in_READ_VAL
          //  in_SPR_READ_STATUS_ACK         - spr.out_READ_ACK
          //  in_SPR_READ_STATUS_DATA_VAL    - spr.out_READ_DATA
	}

      for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	{
          dest = _name;

#ifdef POSITION
          _component->interface_map (src ,"spr_write_"+toString(j),
                                     dest,"spr_write_"+toString(j));
#endif

          PORT_MAP(_component,src , "in_SPR_WRITE_"+toString(j)+"_VAL",
                              dest, "in_SPR_WRITE_"+toString(j)+"_VAL");
          PORT_MAP(_component,src ,"out_SPR_WRITE_"+toString(j)+"_ACK",
                              dest,"out_SPR_WRITE_"+toString(j)+"_ACK");
	  if (_param->_have_port_ooo_engine_id == true)
          PORT_MAP(_component,src , "in_SPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID",
                              dest, "in_SPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID");

          // out_SPR_WRITE_REGISTERFILE_VAL - spr. in_WRITE_VAL
          //  in_SPR_WRITE_REGISTERFILE_ACK - spr.out_WRITE_ACK
          // out_SPR_WRITE_STATUS_VAL       - spr. in_WRITE_VAL
          //  in_SPR_WRITE_STATUS_ACK       - spr.out_WRITE_ACK
          // out_SPR_WRITE_STATUS_DATA      - spr. in_WRITE_DATA
	}

      for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	{
	  uint32_t x     =_param->_nb_inst_insert_rob [i];

	  for (uint32_t j=0; j<x; j++)
	    {
              dest = _name;

#ifdef POSITION
              _component->interface_map (src ,"insert_rob_"+toString(i)+"_"+toString(j),
                                         dest,"insert_rob_"+toString(i)+"_"+toString(j));
#endif

	      PORT_MAP(_component,src , "in_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_VAL",
                                  dest, "in_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_VAL");
	      PORT_MAP(_component,src ,"out_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_ACK",
                                  dest,"out_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_ACK");
	      PORT_MAP(_component,src , "in_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_RD_USE",
                                  dest, "in_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_RD_USE");
	      PORT_MAP(_component,src , "in_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_RE_USE",
                                  dest, "in_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_RE_USE");
              
              // out_INSERT_ROB_GPR_STATUS_VAL - gpr_status.  in_WRITE_VAL
              //  in_INSERT_ROB_GPR_STATUS_ACK - gpr_status. out_WRITE_ACK
              // out_INSERT_ROB_GPR_STATUS_DATA- gpr_status.  in_WRITE_DATA
              // out_INSERT_ROB_SPR_STATUS_VAL - spr_status.  in_WRITE_VAL
              //  in_INSERT_ROB_SPR_STATUS_ACK - spr_status. out_WRITE_ACK
              //  in_INSERT_ROB_SPR_STATUS_DATA- spr_status. out_WRITE_DATA
	    }
	}
      
    }// glue

#if DEBUG_Register_unit == true
    _component->test_map ();
#endif

#ifdef POSITION
    if (usage_is_set(_usage,USE_POSITION))
      _component->generate_file();
#endif

//     std::cout << *_component << std::endl;

    log_printf(FUNC,Register_unit,FUNCTION,"End");
  };

}; // end namespace register_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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