#ifdef VHDL
/*
 * $Id: Write_queue_vhdl_body.cpp 103 2009-01-16 16:55:32Z moulu $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Write_unit/Write_unit/Write_queue/include/Write_queue.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_execute_loop {
namespace execute_loop {
namespace multi_write_unit {
namespace write_unit {
namespace write_queue {


#undef  FUNCTION
#define FUNCTION "Write_queue::vhdl_body"
  void Write_queue::vhdl_body (Vhdl * & vhdl)
  {
    log_printf(FUNC,Write_queue,FUNCTION,"Begin");
    vhdl->set_body ("");
    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"-- Instance queue                  ");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"");

    vhdl->set_body   (0,"instance_"+_name+"_queue : "+_name+"_queue");
    vhdl->set_body   (0,"port map (");
    vhdl->set_body   (1,"  in_CLOCK       \t=>\t      in_CLOCK ");
    vhdl->set_body   (1,", in_NRESET      \t=>\t      in_NRESET");
    vhdl->set_body   (1,", in_INSERT_VAL  \t=>\tsig_QUEUE_INSERT_VAL");
    vhdl->set_body   (1,",out_INSERT_ACK  \t=>\tsig_QUEUE_INSERT_ACK");
    vhdl->set_body   (1,", in_INSERT_DATA \t=>\tsig_QUEUE_INSERT_DATA");
    vhdl->set_body   (1,",out_RETIRE_VAL  \t=>\tsig_QUEUE_RETIRE_VAL");
    vhdl->set_body   (1,", in_RETIRE_ACK  \t=>\tsig_QUEUE_RETIRE_ACK");
    vhdl->set_body   (1,",out_RETIRE_DATA \t=>\tsig_QUEUE_RETIRE_DATA");
    for (uint32_t i=0; i<_param->_nb_bypass_write; i++)
      {
        vhdl->set_body (1,",out_SLOT_"+toString(i)+"_VAL    \t=>\tsig_QUEUE_SLOT_"+toString(i)+"_VAL");
        vhdl->set_body (1,",out_SLOT_"+toString(i)+"_DATA   \t=>\tsig_QUEUE_SLOT_"+toString(i)+"_DATA");
      }
    vhdl->set_body   (0,");");

    vhdl->set_body   (0,"");


    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,"write_rd_re_bis: process (in_CLOCK)");
    vhdl->set_body   (0,"begin  -- process write rd/re bis");
    vhdl->set_body   (1,"if in_CLOCK'event and in_CLOCK = '1' then");
// #ifdef SYSTEMC_VHDL_COMPATIBILITY
//     vhdl->set_body   (2,"if (in_NRESET = '0') then");    
//     vhdl->set_body   (2,"reg_GPR_WRITE <= '0';");
//     vhdl->set_body   (2,"reg_SPR_WRITE <= '0';");
//     vhdl->set_body   (2,"else");
// #endif
      vhdl->set_body   (2,"reg_UPDATE <= (in_WRITE_QUEUE_OUT_ACK and sig_WRITE_QUEUE_OUT_VAL) or (not sig_QUEUE_RETIRE_VAL);");

    vhdl->set_body   (2,"if (sig_GPR_WRITE_0_VAL = '1' and in_GPR_WRITE_0_ACK = '1') then");    
    vhdl->set_body   (3,"reg_GPR_WRITE <= '0';");
    vhdl->set_body   (2,"else");
    vhdl->set_body   (3,"reg_GPR_WRITE <= sig_GPR_WRITE;");
    vhdl->set_body   (2,"end if;");

    vhdl->set_body   (2,"if (sig_SPR_WRITE_0_VAL = '1' and in_SPR_WRITE_0_ACK = '1') then");    
    vhdl->set_body   (3,"reg_SPR_WRITE <= '0';");
    vhdl->set_body   (2,"else");
    vhdl->set_body   (3,"reg_SPR_WRITE <= sig_SPR_WRITE;");
    vhdl->set_body   (2,"end if;");

// #ifdef SYSTEMC_VHDL_COMPATIBILITY
//     vhdl->set_body   (2,"end if;");
// #endif
    vhdl->set_body   (1,"end if;");
    vhdl->set_body   (0,"end process write_rd_re_bis;");

    vhdl->set_body   (0,"sig_GPR_WRITE <= sig_WRITE_RD when (reg_UPDATE = '1') else reg_GPR_WRITE;");
    vhdl->set_body   (0,"sig_SPR_WRITE <= sig_WRITE_RE when (reg_UPDATE = '1') else reg_SPR_WRITE;");
    vhdl->set_body   (0,"sig_GPR_WRITE_0_VAL <= sig_QUEUE_RETIRE_VAL and sig_GPR_WRITE;");
    vhdl->set_body   (0,"sig_SPR_WRITE_0_VAL <= sig_QUEUE_RETIRE_VAL and sig_SPR_WRITE;");
    vhdl->set_body   (0,"sig_DELETE_QUEUE_FRONT <= sig_QUEUE_RETIRE_VAL and not sig_GPR_WRITE and not sig_SPR_WRITE when (sig_WRITE_QUEUE_OUT_EXCEPTION = "+toString(EXCEPTION_MEMORY_LOAD_SPECULATIVE)+") else '0';");
    vhdl->set_body   (0,"sig_WRITE_QUEUE_OUT_VAL <= sig_QUEUE_RETIRE_VAL and not sig_DELETE_QUEUE_FRONT and not sig_GPR_WRITE and not sig_SPR_WRITE;");
    vhdl->set_body   (0,"sig_QUEUE_RETIRE_ACK <= sig_DELETE_QUEUE_FRONT or (in_WRITE_QUEUE_OUT_ACK and sig_WRITE_QUEUE_OUT_VAL);");

    if (_param->_nb_bypass_write > 0)
      {
        vhdl->set_body (0,"sig_BYPASS_WRITE_0_GPR_VAL <= sig_GPR_WRITE_0_VAL;");
        vhdl->set_body (0,"sig_BYPASS_WRITE_0_SPR_VAL <= sig_SPR_WRITE_0_VAL;");
      }

    for (uint32_t i=1; i<_param->_nb_bypass_write; i++)
      {
        vhdl->set_body (0,"sig_BYPASS_WRITE_"+toString(i)+"_GPR_VAL <= sig_QUEUE_SLOT_"+toString(i)+"_VAL and sig_BYPASS_WRITE_"+toString(i)+"_WRITE_RD;");
        vhdl->set_body (0,"sig_BYPASS_WRITE_"+toString(i)+"_SPR_VAL <= sig_QUEUE_SLOT_"+toString(i)+"_VAL and sig_BYPASS_WRITE_"+toString(i)+"_WRITE_RE;");
      }

    vhdl->set_body   (0,"");


    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"-- Input  Buffer                   ");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"");

    {
    uint32_t min = 0;
    uint32_t max, size;

    if(_param->_have_port_context_id   )
      {
    size = _param->_size_context_id;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_CONTEXT_ID;");
    min = max+1;
      }
    if(_param->_have_port_front_end_id   )
      {
    size = _param->_size_front_end_id;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_FRONT_END_ID;");
    min = max+1;
      }
    if(_param->_have_port_ooo_engine_id   )
      {
    size = _param->_size_ooo_engine_id;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_OOO_ENGINE_ID;");
    min = max+1;
      }
    if(_param->_have_port_rob_ptr)
      {
    size = _param->_size_rob_ptr;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_PACKET_ID;");
    min = max+1;
      }

    size = 1;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_WRITE_RD;");
    min = max+1;

    size = _param->_size_general_register;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_NUM_REG_RD;");
    min = max+1;

    size = _param->_size_general_data;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_DATA_RD;");
    min = max+1;

    size = 1;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_WRITE_RE;");
    min = max+1;

    size = _param->_size_special_register;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_NUM_REG_RE;");
    min = max+1;

    size = _param->_size_special_data;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_DATA_RE;");
    min = max+1;

    size = _param->_size_exception;    
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_EXCEPTION;");
    min = max+1;

    size = 1;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_NO_SEQUENCE;");
    min = max+1;

    size = _param->_size_instruction_address;
    max = min-1+size;
    vhdl->set_body   (0,"sig_QUEUE_INSERT_DATA "+std_logic_range(_param->_size_internal_queue,max,min)+" <= in_WRITE_QUEUE_IN_ADDRESS;");
    min = max+1;
    }

    vhdl->set_body   (0,"");


    vhdl->set_comment(0,"");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"-- Output Buffer                   ");
    vhdl->set_comment(0,"-----------------------------------");
    vhdl->set_comment(0,"");
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_VAL    <= sig_WRITE_QUEUE_OUT_VAL;");
    if(_param->_have_port_context_id)
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_CONTEXT_ID    <= sig_WRITE_QUEUE_OUT_CONTEXT_ID   ;");
    if(_param->_have_port_front_end_id)
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_FRONT_END_ID  <= sig_WRITE_QUEUE_OUT_FRONT_END_ID ;");
    if(_param->_have_port_ooo_engine_id)
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_OOO_ENGINE_ID <= sig_WRITE_QUEUE_OUT_OOO_ENGINE_ID;");
    if(_param->_have_port_rob_ptr)
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_PACKET_ID     <= sig_WRITE_QUEUE_OUT_PACKET_ID    ;");
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_FLAGS         <= sig_WRITE_QUEUE_OUT_FLAGS        ;");
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_EXCEPTION     <= sig_WRITE_QUEUE_OUT_EXCEPTION    ;");
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_NO_SEQUENCE   <= sig_WRITE_QUEUE_OUT_NO_SEQUENCE  ;");
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_ADDRESS       <= sig_WRITE_QUEUE_OUT_ADDRESS      ;");
    vhdl->set_body   (0,"out_WRITE_QUEUE_OUT_DATA          <= sig_WRITE_QUEUE_OUT_DATA         ;");
    vhdl->set_body ("");

    vhdl->set_body (0,"out_GPR_WRITE_0_VAL                 <= sig_GPR_WRITE_0_VAL;");
    if(_param->_have_port_ooo_engine_id)
    vhdl->set_body (0,"out_GPR_WRITE_0_OOO_ENGINE_ID       <= sig_GPR_WRITE_0_OOO_ENGINE_ID;");
    vhdl->set_body (0,"out_GPR_WRITE_0_NUM_REG             <= sig_GPR_WRITE_0_NUM_REG;");
    vhdl->set_body (0,"out_GPR_WRITE_0_DATA                <= sig_GPR_WRITE_0_DATA;");

    for (uint32_t i=1; i<_param->_nb_gpr_write; i++)
      vhdl->set_body (0,"out_GPR_WRITE_"+toString(i)+"_VAL                 <= '0';");

    vhdl->set_body (0,"out_SPR_WRITE_0_VAL                 <= sig_SPR_WRITE_0_VAL;");
    if(_param->_have_port_ooo_engine_id)
    vhdl->set_body (0,"out_SPR_WRITE_0_OOO_ENGINE_ID       <= sig_SPR_WRITE_0_OOO_ENGINE_ID;");
    vhdl->set_body (0,"out_SPR_WRITE_0_NUM_REG             <= sig_SPR_WRITE_0_NUM_REG;");
    vhdl->set_body (0,"out_SPR_WRITE_0_DATA                <= sig_SPR_WRITE_0_DATA;");

    for (uint32_t i=1; i<_param->_nb_spr_write; i++)
      vhdl->set_body (0,"out_SPR_WRITE_"+toString(i)+"_VAL                 <= '0';");

    vhdl->set_body ("");

    for (uint32_t i=0; i<_param->_nb_bypass_write; i++)
      {
        vhdl->set_body (0,"out_BYPASS_WRITE_"+toString(i)+"_GPR_VAL          <= sig_BYPASS_WRITE_"+toString(i)+"_GPR_VAL;");
        vhdl->set_body (0,"out_BYPASS_WRITE_"+toString(i)+"_GPR_NUM_REG      <= sig_BYPASS_WRITE_"+toString(i)+"_GPR_NUM_REG;");
        vhdl->set_body (0,"out_BYPASS_WRITE_"+toString(i)+"_GPR_DATA         <= sig_BYPASS_WRITE_"+toString(i)+"_GPR_DATA;");

        vhdl->set_body (0,"out_BYPASS_WRITE_"+toString(i)+"_SPR_VAL          <= sig_BYPASS_WRITE_"+toString(i)+"_SPR_VAL;");
        vhdl->set_body (0,"out_BYPASS_WRITE_"+toString(i)+"_SPR_NUM_REG      <= sig_BYPASS_WRITE_"+toString(i)+"_SPR_NUM_REG;");
        vhdl->set_body (0,"out_BYPASS_WRITE_"+toString(i)+"_SPR_DATA         <= sig_BYPASS_WRITE_"+toString(i)+"_SPR_DATA;");

        if(_param->_have_port_ooo_engine_id)
        vhdl->set_body (0,"out_BYPASS_WRITE_"+toString(i)+"_OOO_ENGINE_ID    <= sig_BYPASS_WRITE_"+toString(i)+"_OOO_ENGINE_ID;");
      }

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

}; // end namespace write_queue
}; // end namespace write_unit
}; // end namespace multi_write_unit
}; // end namespace execute_loop
}; // end namespace multi_execute_loop
}; // end namespace core

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