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

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

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


#undef  FUNCTION
#define FUNCTION "Register_unit_Glue::vhdl_body"
  void Register_unit_Glue::vhdl_body (Vhdl * & vhdl)
  {
    log_printf(FUNC,Register_unit_Glue,FUNCTION,"Begin");

    vhdl->set_body("out_CONST_0 <= '0';");
    vhdl->set_body("out_CONST_1 <= '1';");

    //-----------------------------------
    // GPR_READ
    //-----------------------------------

    vhdl->set_body ("");
    for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
      {
	vhdl->set_body ("out_GPR_READ_"+toString(j)+"_ACK <=");
	for (uint32_t i=_param->_nb_ooo_engine-1; i>=1; i--)
	  {
	    vhdl->set_body ("\tin_GPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK and in_GPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_ACK when in_GPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else");
	  }
	vhdl->set_body ("\tin_GPR_READ_REGISTERFILE_0_"+toString(j)+"_ACK and in_GPR_READ_STATUS_0_"+toString(j)+"_ACK;");
      }

    vhdl->set_body ("");
    for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
      {
	vhdl->set_body ("out_GPR_READ_"+toString(j)+"_DATA <=");
	for (uint32_t i=_param->_nb_ooo_engine-1; i>=1; i--)
	  {
	    vhdl->set_body ("\tin_GPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_DATA when in_GPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else");
	  }
	vhdl->set_body ("\tin_GPR_READ_REGISTERFILE_0_"+toString(j)+"_DATA;");
      }

    vhdl->set_body ("");
    for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
      {
	vhdl->set_body ("out_GPR_READ_"+toString(j)+"_DATA_VAL <=");
	for (uint32_t i=_param->_nb_ooo_engine-1; i>=1; i--)
	  {
	    vhdl->set_body ("\tin_GPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_DATA_VAL when in_GPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else");
	  }
	vhdl->set_body ("\tin_GPR_READ_STATUS_0_"+toString(j)+"_DATA_VAL;");
      }

    if (_param->_have_port_ooo_engine_id == true)
      {
	vhdl->set_body ("");
	for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	  {
	    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	      {
		vhdl->set_body ("out_GPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_VAL <= in_GPR_READ_"+toString(j)+"_VAL and in_GPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_ACK when in_GPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else '0';");
	      }
	  }
	
	vhdl->set_body ("");
	for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	  {
	    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	      {
		vhdl->set_body ("out_GPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_VAL <= in_GPR_READ_"+toString(j)+"_VAL and in_GPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK when in_GPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else '0';");
	      }
	  }
      }
    else
      {
	for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	  vhdl->set_body ("out_GPR_READ_REGISTERFILE_0_"+toString(j)+"_VAL <= in_GPR_READ_"+toString(j)+"_VAL and in_GPR_READ_STATUS_0_"+toString(j)+"_ACK;");
	for (uint32_t j=0; j<_param->_nb_gpr_read; j++)
	  vhdl->set_body ("out_GPR_READ_STATUS_0_"+toString(j)+"_VAL <= in_GPR_READ_"+toString(j)+"_VAL and in_GPR_READ_REGISTERFILE_0_"+toString(j)+"_ACK;");
      }

    //-----------------------------------
    // GPR_WRITE
    //-----------------------------------

    vhdl->set_body ("");
    for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
      {
	vhdl->set_body ("out_GPR_WRITE_"+toString(j)+"_ACK <=");
	for (uint32_t i=_param->_nb_ooo_engine-1; i>=1; i--)
	  {
	    vhdl->set_body ("\tin_GPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK and in_GPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_ACK when in_GPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else");
	  }
	vhdl->set_body ("\tin_GPR_WRITE_REGISTERFILE_0_"+toString(j)+"_ACK and in_GPR_WRITE_STATUS_0_"+toString(j)+"_ACK;");
      }

    if (_param->_have_port_ooo_engine_id == true)
      {
	vhdl->set_body ("");
	for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	  {
	    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	      {
		vhdl->set_body ("out_GPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_VAL <= in_GPR_WRITE_"+toString(j)+"_VAL and in_GPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_ACK when in_GPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else '0';");
	      }
	  }
	
	vhdl->set_body ("");
	for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	  {
	    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	      {
		vhdl->set_body ("out_GPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_VAL <= in_GPR_WRITE_"+toString(j)+"_VAL and in_GPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK when in_GPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else '0';");
	      }
	  }
      }
    else
      {
	for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	  vhdl->set_body ("out_GPR_WRITE_REGISTERFILE_0_"+toString(j)+"_VAL <= in_GPR_WRITE_"+toString(j)+"_VAL and in_GPR_WRITE_STATUS_0_"+toString(j)+"_ACK;");
	for (uint32_t j=0; j<_param->_nb_gpr_write; j++)
	  vhdl->set_body ("out_GPR_WRITE_STATUS_0_"+toString(j)+"_VAL <= in_GPR_WRITE_"+toString(j)+"_VAL and in_GPR_WRITE_REGISTERFILE_0_"+toString(j)+"_ACK;");
      }

    //-----------------------------------
    // SPR_READ
    //-----------------------------------

    vhdl->set_body ("");
    for (uint32_t j=0; j<_param->_nb_spr_read; j++)
      {
	vhdl->set_body ("out_SPR_READ_"+toString(j)+"_ACK <=");
	for (uint32_t i=_param->_nb_ooo_engine-1; i>=1; i--)
	  {
	    vhdl->set_body ("\tin_SPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK and in_SPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_ACK when in_SPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else");
	  }
	vhdl->set_body ("\tin_SPR_READ_REGISTERFILE_0_"+toString(j)+"_ACK and in_SPR_READ_STATUS_0_"+toString(j)+"_ACK;");
      }

    vhdl->set_body ("");
    for (uint32_t j=0; j<_param->_nb_spr_read; j++)
      {
	vhdl->set_body ("out_SPR_READ_"+toString(j)+"_DATA <=");
	for (uint32_t i=_param->_nb_ooo_engine-1; i>=1; i--)
	  {
	    vhdl->set_body ("\tin_SPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_DATA when in_SPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else");
	  }
	vhdl->set_body ("\tin_SPR_READ_REGISTERFILE_0_"+toString(j)+"_DATA;");
      }

    vhdl->set_body ("");
    for (uint32_t j=0; j<_param->_nb_spr_read; j++)
      {
	vhdl->set_body ("out_SPR_READ_"+toString(j)+"_DATA_VAL <=");
	for (uint32_t i=_param->_nb_ooo_engine-1; i>=1; i--)
	  {
	    vhdl->set_body ("\tin_SPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_DATA_VAL when in_SPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else");
	  }
	vhdl->set_body ("\tin_SPR_READ_STATUS_0_"+toString(j)+"_DATA_VAL;");
      }

    if (_param->_have_port_ooo_engine_id == true)
      {
	vhdl->set_body ("");
	for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	  {
	    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	      {
		vhdl->set_body ("out_SPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_VAL <= in_SPR_READ_"+toString(j)+"_VAL and in_SPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_ACK when in_SPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else '0';");
	      }
	  }
	
	vhdl->set_body ("");
	for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	  {
	    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	      {
		vhdl->set_body ("out_SPR_READ_STATUS_"+toString(i)+"_"+toString(j)+"_VAL <= in_SPR_READ_"+toString(j)+"_VAL and in_SPR_READ_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK when in_SPR_READ_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else '0';");
	      }
	  }
      }
    else
      {
	for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	  vhdl->set_body ("out_SPR_READ_REGISTERFILE_0_"+toString(j)+"_VAL <= in_SPR_READ_"+toString(j)+"_VAL and in_SPR_READ_STATUS_0_"+toString(j)+"_ACK;");
	for (uint32_t j=0; j<_param->_nb_spr_read; j++)
	  vhdl->set_body ("out_SPR_READ_STATUS_0_"+toString(j)+"_VAL <= in_SPR_READ_"+toString(j)+"_VAL and in_SPR_READ_REGISTERFILE_0_"+toString(j)+"_ACK;");
      }

    //-----------------------------------
    // SPR_WRITE
    //-----------------------------------

    vhdl->set_body ("");
    for (uint32_t j=0; j<_param->_nb_spr_write; j++)
      {
	vhdl->set_body ("out_SPR_WRITE_"+toString(j)+"_ACK <=");
	for (uint32_t i=_param->_nb_ooo_engine-1; i>=1; i--)
	  {
	    vhdl->set_body ("\tin_SPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK and in_SPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_ACK when in_SPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else");
	  }
	vhdl->set_body ("\tin_SPR_WRITE_REGISTERFILE_0_"+toString(j)+"_ACK and in_SPR_WRITE_STATUS_0_"+toString(j)+"_ACK;");
      }

    if (_param->_have_port_ooo_engine_id == true)
      {
	vhdl->set_body ("");
	for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	  {
	    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	      {
		vhdl->set_body ("out_SPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_VAL <= in_SPR_WRITE_"+toString(j)+"_VAL and in_SPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_ACK when in_SPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else '0';");
	      }
	  }
	
	vhdl->set_body ("");
	for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	  {
	    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
	      {
		vhdl->set_body ("out_SPR_WRITE_STATUS_"+toString(i)+"_"+toString(j)+"_VAL <= in_SPR_WRITE_"+toString(j)+"_VAL and in_SPR_WRITE_REGISTERFILE_"+toString(i)+"_"+toString(j)+"_ACK when in_SPR_WRITE_"+toString(j)+"_OOO_ENGINE_ID = "+std_logic_conv(log2(_param->_nb_ooo_engine),i)+" else '0';");
	      }
	  }
      }
    else
      {
	for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	  vhdl->set_body ("out_SPR_WRITE_REGISTERFILE_0_"+toString(j)+"_VAL <= in_SPR_WRITE_"+toString(j)+"_VAL and in_SPR_WRITE_STATUS_0_"+toString(j)+"_ACK;");
	for (uint32_t j=0; j<_param->_nb_spr_write; j++)
	  vhdl->set_body ("out_SPR_WRITE_STATUS_0_"+toString(j)+"_VAL <= in_SPR_WRITE_"+toString(j)+"_VAL and in_SPR_WRITE_REGISTERFILE_0_"+toString(j)+"_ACK;");
      }


    //-----------------------------------
    // INSERT_ROB
    //-----------------------------------

    vhdl->set_body ("");
    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++)
	  {
	    vhdl->set_body ("out_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_ACK <=");
	    vhdl->set_body ("\tin_INSERT_ROB_GPR_STATUS_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_INSERT_ROB_SPR_STATUS_"+toString(i)+"_"+toString(j)+"_ACK;");

	    vhdl->set_body ("out_INSERT_ROB_GPR_STATUS_"+toString(i)+"_"+toString(j)+"_VAL <=");
	    vhdl->set_body ("\tin_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_VAL            and");
	    vhdl->set_body ("\tin_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_RD_USE         and");
	    vhdl->set_body ("\tin_INSERT_ROB_SPR_STATUS_"+toString(i)+"_"+toString(j)+"_ACK;");

	    vhdl->set_body ("out_INSERT_ROB_SPR_STATUS_"+toString(i)+"_"+toString(j)+"_VAL <=");
	    vhdl->set_body ("\tin_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_VAL            and");
	    vhdl->set_body ("\tin_INSERT_ROB_"+toString(i)+"_"+toString(j)+"_RE_USE         and");
	    vhdl->set_body ("\tin_INSERT_ROB_GPR_STATUS_"+toString(i)+"_"+toString(j)+"_ACK;");
	  }
      }

    //-----------------------------------
    // RETIRE_ROB
    //-----------------------------------
    vhdl->set_body ("");
    for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
      {
	uint32_t x=_param->_nb_inst_retire_rob [i];
	for (uint32_t j=0; j<x; j++)
	  {
	    vhdl->set_body ("out_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_ACK <=");
	    vhdl->set_body ("\tin_RETIRE_ROB_GPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_GPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_SPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_SPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_ACK;");

	    vhdl->set_body ("out_RETIRE_ROB_GPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_VAL <=");
	    vhdl->set_body ("\tin_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_VAL                and");
	    vhdl->set_body ("\tin_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_RD_OLD_USE         and");
	    vhdl->set_body ("\tin_RETIRE_ROB_GPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_SPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_SPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_ACK;");

	    vhdl->set_body ("out_RETIRE_ROB_GPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_VAL <=");
	    vhdl->set_body ("\tin_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_VAL                and");
	    vhdl->set_body ("\tin_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_RD_NEW_USE         and");
	    vhdl->set_body ("\tin_RETIRE_ROB_GPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_SPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_SPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_ACK;");

	    vhdl->set_body ("out_RETIRE_ROB_SPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_VAL <=");
	    vhdl->set_body ("\tin_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_VAL                and");
	    vhdl->set_body ("\tin_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_RE_OLD_USE         and");
	    vhdl->set_body ("\tin_RETIRE_ROB_GPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_GPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_SPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_ACK;");

	    vhdl->set_body ("out_RETIRE_ROB_SPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_VAL <=");
	    vhdl->set_body ("\tin_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_VAL                and");
	    vhdl->set_body ("\tin_RETIRE_ROB_"+toString(i)+"_"+toString(j)+"_RE_NEW_USE         and");
	    vhdl->set_body ("\tin_RETIRE_ROB_GPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_GPR_STATUS_NEW_"+toString(i)+"_"+toString(j)+"_ACK and");
	    vhdl->set_body ("\tin_RETIRE_ROB_SPR_STATUS_OLD_"+toString(i)+"_"+toString(j)+"_ACK;");
	  }
      }

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

}; // end namespace register_unit_glue
}; // end namespace register_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core
}; // end namespace behavioural
}; // end namespace morpheo              
#endif
