#ifdef VHDL
/*
 * $Id: Functionnal_unit_vhdl_body.cpp 116 2009-04-30 13:51:41Z moulu $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Functionnal_unit/include/Functionnal_unit.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace multi_execute_unit {
namespace execute_unit {
namespace functionnal_unit {


#undef  FUNCTION
#define FUNCTION "Functionnal_unit::vhdl_body"
  void Functionnal_unit::vhdl_body (Vhdl * & vhdl)
  {
    log_printf(FUNC,Functionnal_unit,FUNCTION,"Begin");
    vhdl->set_body ("");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"-- Registers                       ");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"");
    vhdl->set_body ("");
    vhdl->set_body (0,"process (in_CLOCK)");
    vhdl->set_body (0,"begin");
    vhdl->set_body (1,"if in_CLOCK'event and in_CLOCK = '1' then");

    vhdl->set_body (2,"if (in_NRESET = '0') then");
    vhdl->set_body (3,"reg_BUSY_IN <= '0';");
    vhdl->set_body (3,"reg_BUSY_OUT <= '0';");
    vhdl->set_body (2,"else");

    vhdl->set_comment (3,"Input Buffer");
    vhdl->set_body (3,"if (sig_EXECUTE_IN_ACK = '1') then");
    vhdl->set_body (4,"reg_BUSY_IN <= in_EXECUTE_IN_VAL;");
    if(_param->_have_port_context_id)
      vhdl->set_body (4,"reg_EXECUTE_IN_CONTEXT_ID <= in_EXECUTE_IN_CONTEXT_ID;");
    if(_param->_have_port_front_end_id)
      vhdl->set_body (4,"reg_EXECUTE_IN_FRONT_END_ID <= in_EXECUTE_IN_FRONT_END_ID;");
    if(_param->_have_port_ooo_engine_id)
      vhdl->set_body (4,"reg_EXECUTE_IN_OOO_ENGINE_ID <= in_EXECUTE_IN_OOO_ENGINE_ID;");
    if(_param->_have_port_rob_ptr)
      vhdl->set_body (4,"reg_EXECUTE_IN_PACKET_ID <= in_EXECUTE_IN_PACKET_ID;");
    vhdl->set_body (4,"reg_EXECUTE_IN_OPERATION <= in_EXECUTE_IN_OPERATION;");
    vhdl->set_body (4,"reg_EXECUTE_IN_TYPE <= in_EXECUTE_IN_TYPE;");
    vhdl->set_body (4,"reg_EXECUTE_IN_DATA_RA <= in_EXECUTE_IN_DATA_RA;");
    vhdl->set_body (4,"reg_EXECUTE_IN_DATA_RB <= in_EXECUTE_IN_DATA_RB;");
    vhdl->set_body (4,"reg_EXECUTE_IN_DATA_RC <= in_EXECUTE_IN_DATA_RC;");
    vhdl->set_body (4,"reg_EXECUTE_IN_HAS_IMMEDIAT <= in_EXECUTE_IN_HAS_IMMEDIAT;");    
    vhdl->set_body (4,"reg_EXECUTE_IN_IMMEDIAT <= in_EXECUTE_IN_IMMEDIAT;");
    vhdl->set_body (4,"reg_EXECUTE_IN_WRITE_RD <= in_EXECUTE_IN_WRITE_RD;");
    vhdl->set_body (4,"reg_EXECUTE_IN_NUM_REG_RD <= in_EXECUTE_IN_NUM_REG_RD;");
    vhdl->set_body (4,"reg_EXECUTE_IN_WRITE_RE <= in_EXECUTE_IN_WRITE_RE;");
    vhdl->set_body (4,"reg_EXECUTE_IN_NUM_REG_RE <= in_EXECUTE_IN_NUM_REG_RE;");
    vhdl->set_body (3,"end if;");

    vhdl->set_comment (3,"Output Buffer");
    vhdl->set_body (3,"if (sig_EXECUTE_OUT_UPDATE = '1') then");
    vhdl->set_body (4,"reg_BUSY_OUT <= reg_BUSY_IN;");
    if(_param->_have_port_context_id)
      vhdl->set_body (4,"reg_EXECUTE_OUT_CONTEXT_ID <= sig_EXECUTE_OUT_CONTEXT_ID;");
    if(_param->_have_port_front_end_id)
      vhdl->set_body (4,"reg_EXECUTE_OUT_FRONT_END_ID <= sig_EXECUTE_OUT_FRONT_END_ID;");
    if(_param->_have_port_ooo_engine_id)
      vhdl->set_body (4,"reg_EXECUTE_OUT_OOO_ENGINE_ID <= sig_EXECUTE_OUT_OOO_ENGINE_ID;");
    if(_param->_have_port_rob_ptr)
      vhdl->set_body (4,"reg_EXECUTE_OUT_PACKET_ID <= sig_EXECUTE_OUT_PACKET_ID;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_WRITE_RD <= sig_EXECUTE_OUT_WRITE_RD;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_NUM_REG_RD <= sig_EXECUTE_OUT_NUM_REG_RD;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_DATA_RD <= sig_EXECUTE_OUT_DATA_RD;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_WRITE_RE <= sig_EXECUTE_OUT_WRITE_RE;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_NUM_REG_RE <= sig_EXECUTE_OUT_NUM_REG_RE;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_DATA_RE <= sig_EXECUTE_OUT_DATA_RE;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_EXCEPTION <= sig_EXECUTE_OUT_EXCEPTION;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_NO_SEQUENCE <= sig_EXECUTE_OUT_NO_SEQUENCE;");
    vhdl->set_body (4,"reg_EXECUTE_OUT_ADDRESS <= sig_EXECUTE_OUT_ADDRESS;");
    vhdl->set_body (3,"end if;");
    vhdl->set_body (2,"end if;");
    vhdl->set_body (1,"end if;");
    vhdl->set_body (0,"end process;");

    vhdl->set_body ("");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"-- Insides                         ");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"");

    vhdl->set_body (0,"");
    vhdl->set_body (0,"sig_B_OPERAND <= reg_EXECUTE_IN_IMMEDIAT when (reg_EXECUTE_IN_HAS_IMMEDIAT = '1') else");
    vhdl->set_body (1,"reg_EXECUTE_IN_DATA_RB;");

    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"ALU");
    vhdl->set_comment(0,"");

    vhdl->set_body (0,"sig_IS_ARITH <= reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_ADD))+") or reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_ADDC))+") or reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_SUB))+");");

    vhdl->set_body (0,"sig_IS_LOGIC <= reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_AND))+") or reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_OR))+") or reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_XOR))+");");

    vhdl->set_body (0,"sig_CIN_ARITH <= reg_EXECUTE_IN_DATA_RC("+toString(FLAG_POSITION_CY)+") and reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_ADDC))+");");
//    vhdl->set_body (0,"sig_CIN_ARITH <= (reg_EXECUTE_IN_DATA_RC("+toString(FLAG_POSITION_CY)+") and reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_ADDC))+")) or reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_SUB))+");");

//    vhdl->set_body (0,"sig_ARITH_B_OPERAND <= not (sig_B_OPERAND) when (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_SUB))+") = '1') else");
    vhdl->set_body (0,"sig_ARITH_B_OPERAND <= ((not sig_B_OPERAND) + 1) when (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_SUB))+") = '1') else");
    vhdl->set_body (1,"sig_B_OPERAND;");

    vhdl->set_body (0,"sig_RES_ARITH <= ('0' & reg_EXECUTE_IN_DATA_RA) + ('0' & sig_ARITH_B_OPERAND) + ("+std_logic_cst(_param->_size_general_data-2,0)+" & sig_CIN_ARITH);");

    vhdl->set_body (0,"");
    vhdl->set_body (0,"sig_A_AND_B <= reg_EXECUTE_IN_DATA_RA and sig_B_OPERAND;");
    vhdl->set_body (0,"sig_A_OR_B <= reg_EXECUTE_IN_DATA_RA or sig_B_OPERAND;");
    vhdl->set_body (0,"sig_A_XOR_B <= reg_EXECUTE_IN_DATA_RA xor sig_B_OPERAND;");

    vhdl->set_body (0,"");
    vhdl->set_body (0,"with reg_EXECUTE_IN_OPERATION select");
    vhdl->set_body (0,"sig_RES_LOGIC <=");
    vhdl->set_body (1,"sig_A_AND_B when "+std_logic_cst(_param->_size_operation,OPERATION_ALU_L_AND)+",");
    vhdl->set_body (1,"sig_A_OR_B  when "+std_logic_cst(_param->_size_operation,OPERATION_ALU_L_OR)+",");
    vhdl->set_body (1,"sig_A_XOR_B when "+std_logic_cst(_param->_size_operation,OPERATION_ALU_L_XOR)+",");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data,0)+" when others;");

    vhdl->set_body (0,"sig_RES_ALU <=");
    vhdl->set_body (1,"sig_RES_ARITH ("+toString(_param->_size_general_data-1)+" downto 0) when (sig_IS_ARITH = '1') else");
    vhdl->set_body (1,"sig_RES_LOGIC when (sig_IS_LOGIC = '1') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data,0)+";");

    vhdl->set_body (0,"");
    vhdl->set_comment(0,"In ISA l.sub doesn't change carry flag.");
    vhdl->set_body (0,"sig_COUT_ALU <= (sig_RES_ARITH("+toString(_param->_size_general_data)+") and (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_ADD))+") or reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_ADDC))+"))) or (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_ALU_L_SUB))+") and reg_EXECUTE_IN_DATA_RC("+toString(FLAG_POSITION_CY)+"));");
    vhdl->set_body (0,"sig_OVR_ALU <= ((sig_ARITH_B_OPERAND("+toString(_param->_size_general_data-1)+") and reg_EXECUTE_IN_DATA_RA("+toString(_param->_size_general_data-1)+") and not sig_RES_ARITH("+toString(_param->_size_general_data-1)+")) or (not sig_ARITH_B_OPERAND("+toString(_param->_size_general_data-1)+") and not reg_EXECUTE_IN_DATA_RA("+toString(_param->_size_general_data-1)+") and sig_RES_ARITH("+toString(_param->_size_general_data-1)+"))) and sig_IS_ARITH;");

    vhdl->set_body (0,"");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"MOVE");
    vhdl->set_comment(0,"");
    vhdl->set_body (0,"sig_MOVHI <= reg_EXECUTE_IN_IMMEDIAT("+toString(_param->_size_general_data-17)+" downto 0) & "+std_logic_cst(16,0)+";");
    
    vhdl->set_body (0,"sig_CMOV <=");
    vhdl->set_body (1,"reg_EXECUTE_IN_DATA_RA when (reg_EXECUTE_IN_DATA_RC("+toString(FLAG_POSITION_F)+") = '1') else");
    vhdl->set_body (1,"reg_EXECUTE_IN_DATA_RB;");
    
    vhdl->set_body (0,"sig_RES_MOVE <=");
    vhdl->set_body (1,"sig_MOVHI when (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_MOVE_L_MOVHI))+") = '1') else");
    vhdl->set_body (1,"sig_CMOV when (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_MOVE_L_CMOV))+") = '1') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data,0)+";");

    vhdl->set_body (0,"");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"BRANCH");
    vhdl->set_comment(0,"");
    vhdl->set_body (0,"sig_NOSQ_BRANCH <= (reg_EXECUTE_IN_DATA_RC("+toString(FLAG_POSITION_F)+") and reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_BRANCH_L_TEST_F))+")) or (not reg_EXECUTE_IN_DATA_RC("+toString(FLAG_POSITION_F)+") and reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_BRANCH_L_TEST_NF))+")) or reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_BRANCH_L_JALR))+");");

#ifdef SYSTEMC_VHDL_COMPATIBILITY
    vhdl->set_body (0,"sig_RES_BRANCH <=");
    vhdl->set_body (1,"reg_EXECUTE_IN_IMMEDIAT("+toString(_param->_size_general_data-3)+" downto 0) & "+std_logic_cst(2,0)+"when (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_BRANCH_L_JALR))+") = '1') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data,0)+";");
#else
    vhdl->set_body (0,"sig_RES_BRANCH <= reg_EXECUTE_IN_IMMEDIAT("+toString(_param->_size_general_data-3)+" downto 0) & "+std_logic_cst(2,0)+";");
#endif

    vhdl->set_body (0,"sig_ADDR_BRANCH <=");
    vhdl->set_body (1,"reg_EXECUTE_IN_DATA_RB("+toString(_param->_size_instruction_address+1)+" downto 2) when (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_BRANCH_L_JALR))+") = '1') else");
    vhdl->set_body (1,"reg_EXECUTE_IN_IMMEDIAT("+toString(_param->_size_instruction_address-1)+" downto 0);");
 
    vhdl->set_body ("");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"SHIFTER");
    vhdl->set_comment(0,"");

    vhdl->set_comment(0,"Instance shifter");
    vhdl->set_body   (0,"instance_"+_name+"_shifter : "+_name+"_shifter");
    vhdl->set_body   (0,"port map (");
    vhdl->set_body   (1,"  in_SHIFTER_0_DATA      \t=>\treg_EXECUTE_IN_DATA_RA");
    vhdl->set_body   (1,", in_SHIFTER_0_SHIFT     \t=>\tsig_B_OPERAND("+toString((log2(_param->_size_general_data))-1)+" downto 0)");
    vhdl->set_body   (1,", in_SHIFTER_0_DIRECTION \t=>\treg_EXECUTE_IN_OPERATION(0)");
    vhdl->set_body   (1,", in_SHIFTER_0_TYPE      \t=>\treg_EXECUTE_IN_OPERATION(1)");
    vhdl->set_body   (1,", in_SHIFTER_0_CARRY     \t=>\treg_EXECUTE_IN_OPERATION(2)");
    vhdl->set_body   (1,",out_SHIFTER_0_DATA      \t=>\tsig_RES_SHIFTER");
    vhdl->set_body   (0,");");
    vhdl->set_body   (0,"");

    vhdl->set_body ("");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"EXTEND");
    vhdl->set_comment(0,"");

    vhdl->set_body (0,"sig_EXT_BYTE_S <=");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-8,(1<<_param->_size_general_data-8)-1)+" & reg_EXECUTE_IN_DATA_RA (7 downto 0) when (reg_EXECUTE_IN_DATA_RA (7) = '1') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-8,0)+" & reg_EXECUTE_IN_DATA_RA (7 downto 0);");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_EXT_BYTE_Z <=");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-8,0)+" & reg_EXECUTE_IN_DATA_RA (7 downto 0);");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_EXT_HALF_WORD_S <=");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-16,(1<<_param->_size_general_data-16)-1)+" & reg_EXECUTE_IN_DATA_RA (15 downto 0) when (reg_EXECUTE_IN_DATA_RA (15) = '1') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-16,0)+" & reg_EXECUTE_IN_DATA_RA (15 downto 0);");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_EXT_HALF_WORD_Z <=");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-16,0)+" & reg_EXECUTE_IN_DATA_RA (15 downto 0);");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_EXT_WORD_S <=");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-32,(1<<_param->_size_general_data-32)-1)+" & reg_EXECUTE_IN_DATA_RA (31 downto 0) when (reg_EXECUTE_IN_DATA_RA (31) = '1') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-32,0)+" & reg_EXECUTE_IN_DATA_RA (31 downto 0);");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_EXT_WORD_Z <=");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-32,0)+" & reg_EXECUTE_IN_DATA_RA (31 downto 0);");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_EXT_S <=");
    vhdl->set_body (1,"sig_EXT_BYTE_S      when (reg_EXECUTE_IN_IMMEDIAT = 8)  else");
    vhdl->set_body (1,"sig_EXT_HALF_WORD_S when (reg_EXECUTE_IN_IMMEDIAT = 16) else");
    vhdl->set_body (1,"sig_EXT_WORD_S;");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_EXT_Z <=");
    vhdl->set_body (1,"sig_EXT_BYTE_Z      when (reg_EXECUTE_IN_IMMEDIAT = 8)  else");
    vhdl->set_body (1,"sig_EXT_HALF_WORD_Z when (reg_EXECUTE_IN_IMMEDIAT = 16) else");
    vhdl->set_body (1,"sig_EXT_WORD_Z;");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_RES_EXTEND <=");
    vhdl->set_body (1,"sig_EXT_Z      when (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_EXTEND_L_EXTEND_Z))+") = '1')  else");
    vhdl->set_body (1,"sig_EXT_S;");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"FIND");
    vhdl->set_comment(0,"");

    vhdl->set_body (0,"sig_FF1 <=");
    for (uint32_t i=0; i<_param->_size_general_data; i++)
      vhdl->set_body (1,std_logic_cst(log2(_param->_size_general_data)+1,i+1)+" \twhen (reg_EXECUTE_IN_DATA_RA ("+toString(i)+") = '1') \telse");
    vhdl->set_body (1,std_logic_cst(log2(_param->_size_general_data)+1,0)+";");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_FL1 <=");
    for (uint32_t i=_param->_size_general_data; i>0; i--)
      vhdl->set_body (1,std_logic_cst(log2(_param->_size_general_data)+1,i)+" \twhen (reg_EXECUTE_IN_DATA_RA ("+toString(i-1)+") = '1') \telse");
    vhdl->set_body (1,std_logic_cst(log2(_param->_size_general_data)+1,0)+";");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_RES_FIND <=");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-log2(_param->_size_general_data)-1,0)+"&"+"sig_FF1      when (reg_EXECUTE_IN_OPERATION("+toString(log2(OPERATION_FIND_L_FF1))+") = '1')  else");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data-log2(_param->_size_general_data)-1,0)+"&"+"sig_FL1;");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"SPECIAL");
    vhdl->set_comment(0,"");

    vhdl->set_body (0,"sig_SPR_IS_HERE <=");
    //    vhdl->set_body (1,"'1' when (sig_A_OR_B("+toString(_param->_size_special_address_group+_param->_size_special_address_register-1)+" downto "+toString(_param->_size_special_address_register)+") = "+std_logic_cst(_param->_size_special_address_group,GROUP_MAC)+") else");
    vhdl->set_body (1,"'1' when (sig_A_OR_B(15 downto 0) = "+std_logic_cst(_param->_size_special_address_group,GROUP_MAC)+") else");
    vhdl->set_body (1,"'0';");

    vhdl->set_comment(0,"MFSPR");
    vhdl->set_body (0,"sig_MFSPR <=");
    vhdl->set_body (1,"reg_MACLO"+toString((_param->_have_port_context_id == 1) ? "(reg_EXECUTE_IN_CONTEXT_ID)" : "(0)")+" when (sig_SPR_IS_HERE = '1' and sig_A_OR_B("+toString(_param->_size_special_address_register-1)+" downto 0) = "+std_logic_cst(_param->_size_special_address_register,SPR_MACLO)+") else");
    vhdl->set_body (1,"reg_MACHI"+toString((_param->_have_port_context_id == 1) ? "(reg_EXECUTE_IN_CONTEXT_ID)" : "(0)")+" when (sig_SPR_IS_HERE = '1' and sig_A_OR_B("+toString(_param->_size_special_address_register-1)+" downto 0) = "+std_logic_cst(_param->_size_special_address_register,SPR_MACHI)+") else");
    vhdl->set_body (1,std_logic_cst(_param->_size_spr,0)+";");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"");

    vhdl->set_comment(0,"MTSPR");
    vhdl->set_body (0,"process (in_CLOCK)");
    vhdl->set_body (0,"begin");
    vhdl->set_body (1,"if in_CLOCK'event and in_CLOCK = '1' then");
    vhdl->set_body (2,"if (sig_SPR_IS_HERE = '1') then");
    vhdl->set_body (3,"if (sig_A_OR_B("+toString(_param->_size_special_address_register-1)+" downto 0) = "+std_logic_cst(_param->_size_special_address_register,SPR_MACLO)+") then");
    vhdl->set_body (4,"reg_MACLO"+toString((_param->_have_port_context_id == 1) ? "(reg_EXECUTE_IN_CONTEXT_ID)" : "(0)")+" <= reg_EXECUTE_IN_DATA_RB;");
    vhdl->set_body (3,"end if;");
    vhdl->set_body (3,"if (sig_A_OR_B("+toString(_param->_size_special_address_register-1)+" downto 0) = "+std_logic_cst(_param->_size_special_address_register,SPR_MACHI)+") then");
    vhdl->set_body (4,"reg_MACHI"+toString((_param->_have_port_context_id == 1) ? "(reg_EXECUTE_IN_CONTEXT_ID)" : "(0)")+" <= reg_EXECUTE_IN_DATA_RB;");
    vhdl->set_body (3,"end if;");
    vhdl->set_body (2,"end if;");
    vhdl->set_body (1,"end if;");
    vhdl->set_body (0,"end process;");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"sig_RES_SPECIAL <=");
    vhdl->set_body (1,"sig_MFSPR when (reg_EXECUTE_IN_OPERATION = "+std_logic_cst(_param->_size_operation,OPERATION_SPECIAL_L_MFSPR)+")  else");
    vhdl->set_body (1,"reg_EXECUTE_IN_DATA_RB when (reg_EXECUTE_IN_OPERATION = "+std_logic_cst(_param->_size_operation,OPERATION_SPECIAL_L_MTSPR)+")  else");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data,0)+";");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"TRANSACTION");
    vhdl->set_comment(0,"");
//     vhdl->set_body (0,"sig_EXECUTE_OUT_VAL <= reg_BUSY_IN;");
//     vhdl->set_body (0,"sig_EXECUTE_IN_ACK <= not reg_BUSY_IN or (reg_BUSY_IN and in_EXECUTE_OUT_ACK);");
    
    vhdl->set_body (0,"sig_EXECUTE_OUT_VAL <= reg_BUSY_OUT;");
    vhdl->set_body (0,"sig_EXECUTE_OUT_UPDATE <= not reg_BUSY_OUT or (reg_BUSY_OUT and in_EXECUTE_OUT_ACK);");
    vhdl->set_body (0,"sig_EXECUTE_IN_ACK <= not reg_BUSY_IN or (reg_BUSY_IN and sig_EXECUTE_OUT_UPDATE);");
    
    vhdl->set_body ("");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"--                                  ");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"");
    vhdl->set_body ("");
    if(_param->_have_port_context_id)
      vhdl->set_body (0,"sig_EXECUTE_OUT_CONTEXT_ID <= reg_EXECUTE_IN_CONTEXT_ID;");

    if(_param->_have_port_front_end_id)
      vhdl->set_body (0,"sig_EXECUTE_OUT_FRONT_END_ID <= reg_EXECUTE_IN_FRONT_END_ID;");

    if(_param->_have_port_ooo_engine_id)
      vhdl->set_body (0,"sig_EXECUTE_OUT_OOO_ENGINE_ID <= reg_EXECUTE_IN_OOO_ENGINE_ID;");

    if(_param->_have_port_rob_ptr)
      vhdl->set_body (0,"sig_EXECUTE_OUT_PACKET_ID <= reg_EXECUTE_IN_PACKET_ID;");

    vhdl->set_body (0,"sig_EXECUTE_OUT_WRITE_RD <=  reg_EXECUTE_IN_WRITE_RD;");

    vhdl->set_body (0,"sig_EXECUTE_OUT_NUM_REG_RD <= reg_EXECUTE_IN_NUM_REG_RD;");

    vhdl->set_body (0,"with reg_EXECUTE_IN_TYPE select");
    vhdl->set_body (0,"sig_EXECUTE_OUT_DATA_RD <=");
    vhdl->set_body (1,"sig_RES_ALU when "+std_logic_cst(_param->_size_type,TYPE_ALU)+",");
    vhdl->set_body (1,"sig_RES_MOVE when "+std_logic_cst(_param->_size_type,TYPE_MOVE)+",");
    vhdl->set_body (1,"sig_RES_BRANCH when "+std_logic_cst(_param->_size_type,TYPE_BRANCH)+",");
    vhdl->set_body (1,"sig_RES_SHIFTER when "+std_logic_cst(_param->_size_type,TYPE_SHIFT)+",");
    vhdl->set_body (1,"sig_RES_EXTEND when "+std_logic_cst(_param->_size_type,TYPE_EXTEND)+",");
    vhdl->set_body (1,"sig_RES_FIND when "+std_logic_cst(_param->_size_type,TYPE_FIND)+",");
    vhdl->set_body (1,"sig_RES_SPECIAL when "+std_logic_cst(_param->_size_type,TYPE_SPECIAL)+",");
    vhdl->set_body (1,std_logic_cst(_param->_size_general_data,0)+" when others;");

    vhdl->set_body (0,"sig_EXECUTE_OUT_WRITE_RE <= reg_EXECUTE_IN_WRITE_RE;");

    vhdl->set_body (0,"sig_EXECUTE_OUT_NUM_REG_RE <= reg_EXECUTE_IN_NUM_REG_RE;");

    vhdl->set_body (0,"with reg_EXECUTE_IN_TYPE select");
    vhdl->set_body (0,"sig_EXECUTE_OUT_DATA_RE <=");
    if(FLAG_POSITION_CY > FLAG_POSITION_OV)
    vhdl->set_body (1,"sig_COUT_ALU & sig_OVR_ALU when "+std_logic_cst(_param->_size_type,TYPE_ALU)+",");
    else
    vhdl->set_body (1,"sig_OVR_ALU & sig_COUT_ALU when "+std_logic_cst(_param->_size_type,TYPE_ALU)+",");
    vhdl->set_body (1,std_logic_cst(_param->_size_special_data,0)+" when others;");

    vhdl->set_body (0,"sig_EXECUTE_OUT_EXCEPTION <=");
    vhdl->set_body (1,std_logic_cst(_param->_size_exception,EXCEPTION_ALU_RANGE)+" when (reg_EXECUTE_IN_TYPE = "+std_logic_cst(_param->_size_type,TYPE_ALU)+" and sig_OVR_ALU = '1') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_exception,EXCEPTION_ALU_SPR_ACCESS_MUST_READ)+" when (reg_EXECUTE_IN_TYPE = "+std_logic_cst(_param->_size_type,TYPE_SPECIAL)+" and reg_EXECUTE_IN_OPERATION = "+std_logic_cst(_param->_size_operation,OPERATION_SPECIAL_L_MFSPR)+" and sig_SPR_IS_HERE = '0') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_exception,EXCEPTION_ALU_SPR_ACCESS_MUST_WRITE)+" when (reg_EXECUTE_IN_TYPE = "+std_logic_cst(_param->_size_type,TYPE_SPECIAL)+" and reg_EXECUTE_IN_OPERATION = "+std_logic_cst(_param->_size_operation,OPERATION_SPECIAL_L_MTSPR)+" and sig_SPR_IS_HERE = '0') else");
    vhdl->set_body (1,std_logic_cst(_param->_size_exception,EXCEPTION_NONE)+";");

    vhdl->set_body (0,"with reg_EXECUTE_IN_TYPE select");
    vhdl->set_body (0,"sig_EXECUTE_OUT_NO_SEQUENCE <=");
    vhdl->set_body (1,"sig_NOSQ_BRANCH when "+std_logic_cst(_param->_size_type,TYPE_BRANCH)+",");
    vhdl->set_body (1,std_logic_cst(1,0)+"when others;");

#ifdef SYSTEMC_VHDL_COMPATIBILITY
    vhdl->set_body (0,"with reg_EXECUTE_IN_TYPE select");
    vhdl->set_body (0,"sig_EXECUTE_OUT_ADDRESS <=");
    vhdl->set_body (1,"sig_ADDR_BRANCH when "+std_logic_cst(_param->_size_type,TYPE_BRANCH)+",");
    vhdl->set_body (1,"sig_A_OR_B("+toString(_param->_size_instruction_address-1)+" downto 0) when "+std_logic_cst(_param->_size_type,TYPE_SPECIAL)+",");
    vhdl->set_body (1,std_logic_cst(_param->_size_instruction_address,0)+" when others;");
#else
    vhdl->set_body (0,"with reg_EXECUTE_IN_TYPE select");
    vhdl->set_body (0,"sig_EXECUTE_OUT_ADDRESS <=");
    vhdl->set_body (1,"sig_ADDR_BRANCH when "+std_logic_cst(_param->_size_type,TYPE_BRANCH)+",");
    vhdl->set_body (1,"sig_A_OR_B when others;");
//    vhdl->set_body (0,"sig_EXECUTE_OUT_ADDRESS <= sig_ADDR_BRANCH;");
#endif

    vhdl->set_body ("");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"-- Outputs                          ");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"");
    vhdl->set_body ("");
//     if(_param->_have_port_context_id)
//       vhdl->set_body (0,"out_EXECUTE_OUT_CONTEXT_ID <= sig_EXECUTE_OUT_CONTEXT_ID;");
//     if(_param->_have_port_front_end_id)
//       vhdl->set_body (0,"out_EXECUTE_OUT_FRONT_END_ID <= sig_EXECUTE_OUT_FRONT_END_ID;");
//     if(_param->_have_port_ooo_engine_id)
//       vhdl->set_body (0,"out_EXECUTE_OUT_OOO_ENGINE_ID <= sig_EXECUTE_OUT_OOO_ENGINE_ID;");
//     if(_param->_have_port_rob_ptr)
//       vhdl->set_body (0,"out_EXECUTE_OUT_PACKET_ID <= sig_EXECUTE_OUT_PACKET_ID;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_WRITE_RD <=  sig_EXECUTE_OUT_WRITE_RD;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_NUM_REG_RD <= sig_EXECUTE_OUT_NUM_REG_RD;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_DATA_RD <= sig_EXECUTE_OUT_DATA_RD;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_WRITE_RE <= sig_EXECUTE_OUT_WRITE_RE;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_NUM_REG_RE <= sig_EXECUTE_OUT_NUM_REG_RE;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_DATA_RE <= sig_EXECUTE_OUT_DATA_RE;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_EXCEPTION <= sig_EXECUTE_OUT_EXCEPTION;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_NO_SEQUENCE <= sig_EXECUTE_OUT_NO_SEQUENCE;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_ADDRESS <= sig_EXECUTE_OUT_ADDRESS;");
//     vhdl->set_body (0,"out_EXECUTE_OUT_VAL <= sig_EXECUTE_OUT_VAL;");
//     vhdl->set_body (0,"out_EXECUTE_IN_ACK <= sig_EXECUTE_IN_ACK;");

    if(_param->_have_port_context_id)
      vhdl->set_body (0,"out_EXECUTE_OUT_CONTEXT_ID <= reg_EXECUTE_OUT_CONTEXT_ID;");
    if(_param->_have_port_front_end_id)
      vhdl->set_body (0,"out_EXECUTE_OUT_FRONT_END_ID <= reg_EXECUTE_OUT_FRONT_END_ID;");
    if(_param->_have_port_ooo_engine_id)
      vhdl->set_body (0,"out_EXECUTE_OUT_OOO_ENGINE_ID <= reg_EXECUTE_OUT_OOO_ENGINE_ID;");
    if(_param->_have_port_rob_ptr)
      vhdl->set_body (0,"out_EXECUTE_OUT_PACKET_ID <= reg_EXECUTE_OUT_PACKET_ID;");
    vhdl->set_body (0,"out_EXECUTE_OUT_WRITE_RD <=  reg_EXECUTE_OUT_WRITE_RD;");
    vhdl->set_body (0,"out_EXECUTE_OUT_NUM_REG_RD <= reg_EXECUTE_OUT_NUM_REG_RD;");
    vhdl->set_body (0,"out_EXECUTE_OUT_DATA_RD <= reg_EXECUTE_OUT_DATA_RD;");
    vhdl->set_body (0,"out_EXECUTE_OUT_WRITE_RE <= reg_EXECUTE_OUT_WRITE_RE;");
    vhdl->set_body (0,"out_EXECUTE_OUT_NUM_REG_RE <= reg_EXECUTE_OUT_NUM_REG_RE;");
    vhdl->set_body (0,"out_EXECUTE_OUT_DATA_RE <= reg_EXECUTE_OUT_DATA_RE;");
    vhdl->set_body (0,"out_EXECUTE_OUT_EXCEPTION <= reg_EXECUTE_OUT_EXCEPTION;");
    vhdl->set_body (0,"out_EXECUTE_OUT_NO_SEQUENCE <= reg_EXECUTE_OUT_NO_SEQUENCE;");
    vhdl->set_body (0,"out_EXECUTE_OUT_ADDRESS <= reg_EXECUTE_OUT_ADDRESS;");
    vhdl->set_body (0,"out_EXECUTE_OUT_VAL <= sig_EXECUTE_OUT_VAL;");
    vhdl->set_body (0,"out_EXECUTE_IN_ACK <= sig_EXECUTE_IN_ACK;");

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

}; // end namespace functionnal_unit
}; // end namespace execute_unit
}; // end namespace multi_execute_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

}; // end namespace behavioural
}; // end namespace morpheo              
#endif
