#ifdef VHDL
/*
 * $Id: Execute_queue_vhdl_body.cpp 96 2008-12-16 19:36:25Z moulu $
 *
 * [ Description ]
 * 
 */

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

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


#undef  FUNCTION
#define FUNCTION "Execute_queue::vhdl_body"
  void Execute_queue::vhdl_body (Vhdl * & vhdl)
  {
    log_printf(FUNC,Execute_queue,FUNCTION,"Begin");
    vhdl->set_body (0,"");
    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_CURRENT_STATE <= STATE_0;");
//     vhdl->set_body (2,"else");
    vhdl->set_body (3,"reg_CURRENT_STATE <= sig_NEXT_STATE;");
//     vhdl->set_body (2,"end if;");

    for (uint32_t i = 0; i <_param->_size_queue - 1; i++)
      {
	vhdl->set_body (2,"if sig_WEN_"+toString(i)+" = '1' then");
	vhdl->set_body (3,"if sig_SEL_"+toString(i)+" = '0' then");
	if (_param->_have_port_context_id)
	vhdl->set_body (4,"reg_CONTEXT_ID_"+toString(i)+"    <= in_EXECUTE_QUEUE_IN_CONTEXT_ID;");
	if (_param->_have_port_front_end_id)
	vhdl->set_body (4,"reg_FRONT_END_ID_"+toString(i)+"  <= in_EXECUTE_QUEUE_IN_FRONT_END_ID;");
	if (_param->_have_port_ooo_engine_id)
	vhdl->set_body (4,"reg_OOO_ENGINE_ID_"+toString(i)+" <= in_EXECUTE_QUEUE_IN_OOO_ENGINE_ID;");
	if (_param->_have_port_rob_ptr)
        vhdl->set_body (4,"reg_PACKET_ID_"+toString(i)+"     <= in_EXECUTE_QUEUE_IN_PACKET_ID;");
	vhdl->set_body (4, "reg_FLAGS_"+toString(i)+"        <= in_EXECUTE_QUEUE_IN_FLAGS;");
	vhdl->set_body (4, "reg_EXCEPTION_"+toString(i)+"    <= in_EXECUTE_QUEUE_IN_EXCEPTION;");
	vhdl->set_body (4, "reg_NO_SEQUENCE_"+toString(i)+"  <= in_EXECUTE_QUEUE_IN_NO_SEQUENCE;");
	vhdl->set_body (4, "reg_ADDRESS_"+toString(i)+"      <= in_EXECUTE_QUEUE_IN_ADDRESS;");
	vhdl->set_body (4, "reg_DATA_"+toString(i)+"         <= in_EXECUTE_QUEUE_IN_DATA;");

	vhdl->set_body (3, "else");
	if (_param->_have_port_context_id)
	vhdl->set_body (4,"reg_CONTEXT_ID_"+toString(i)+"    <= reg_CONTEXT_ID_"+toString(i+1)+";");
	if (_param->_have_port_front_end_id)
	vhdl->set_body (4,"reg_FRONT_END_ID_"+toString(i)+"  <= reg_FRONT_END_ID_"+toString(i+1)+";");
	if (_param->_have_port_ooo_engine_id)
	vhdl->set_body (4,"reg_OOO_ENGINE_ID_"+toString(i)+" <= reg_OOO_ENGINE_ID_"+toString(i+1)+";");
	if (_param->_have_port_rob_ptr)
        vhdl->set_body (4,"reg_PACKET_ID_"+toString(i)+"     <= reg_PACKET_ID_"+toString(i+1)+";");
	vhdl->set_body (4, "reg_FLAGS_"+toString(i)+"        <= reg_FLAGS_"+toString(i+1)+";");
	vhdl->set_body (4, "reg_EXCEPTION_"+toString(i)+"    <= reg_EXCEPTION_"+toString(i+1)+";");
	vhdl->set_body (4, "reg_NO_SEQUENCE_"+toString(i)+"  <= reg_NO_SEQUENCE_"+toString(i+1)+";");
	vhdl->set_body (4, "reg_ADDRESS_"+toString(i)+"      <= reg_ADDRESS_"+toString(i+1)+";");
	vhdl->set_body (4, "reg_DATA_"+toString(i)+"         <= reg_DATA_"+toString(i+1)+";");
	
	vhdl->set_body (3,"end if;");

	vhdl->set_body (2,"end if;");
      }

    vhdl->set_body (2,"if sig_WEN_"+toString(_param->_size_queue-1)+" = '1' then");
    if (_param->_have_port_context_id)
      vhdl->set_body (3,"reg_CONTEXT_ID_"+toString(_param->_size_queue-1)+"    <= in_EXECUTE_QUEUE_IN_CONTEXT_ID;");
    if (_param->_have_port_front_end_id)
      vhdl->set_body (3,"reg_FRONT_END_ID_"+toString(_param->_size_queue-1)+"  <= in_EXECUTE_QUEUE_IN_FRONT_END_ID;");
    if (_param->_have_port_ooo_engine_id)
      vhdl->set_body (3,"reg_OOO_ENGINE_ID_"+toString(_param->_size_queue-1)+" <= in_EXECUTE_QUEUE_IN_OOO_ENGINE_ID;");
    if (_param->_have_port_rob_ptr)
      vhdl->set_body (3,"reg_PACKET_ID_"+toString(_param->_size_queue-1)+"     <= in_EXECUTE_QUEUE_IN_PACKET_ID;");
    vhdl->set_body (3, "reg_FLAGS_"+toString(_param->_size_queue-1)+"        <= in_EXECUTE_QUEUE_IN_FLAGS;");
    vhdl->set_body (3, "reg_EXCEPTION_"+toString(_param->_size_queue-1)+"    <= in_EXECUTE_QUEUE_IN_EXCEPTION;");
    vhdl->set_body (3, "reg_NO_SEQUENCE_"+toString(_param->_size_queue-1)+"  <= in_EXECUTE_QUEUE_IN_NO_SEQUENCE;");
    vhdl->set_body (3, "reg_ADDRESS_"+toString(_param->_size_queue-1)+"      <= in_EXECUTE_QUEUE_IN_ADDRESS;");
    vhdl->set_body (3, "reg_DATA_"+toString(_param->_size_queue-1)+"         <= in_EXECUTE_QUEUE_IN_DATA;");
    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,"");
    vhdl->set_body (0,"");

    vhdl->set_body (0,"out_EXECUTE_QUEUE_OUT_VAL <= sig_OUT_VAL;");
    vhdl->set_body (0,"out_EXECUTE_QUEUE_IN_ACK <= sig_IN_ACK;");
    if (_param->_have_port_context_id)
    vhdl->set_body (0,"out_EXECUTE_QUEUE_OUT_CONTEXT_ID <= reg_CONTEXT_ID_0;");
    if (_param->_have_port_front_end_id)
    vhdl->set_body (0,"out_EXECUTE_QUEUE_OUT_FRONT_END_ID <= reg_FRONT_END_ID_0;");
    if (_param->_have_port_ooo_engine_id)
    vhdl->set_body (0,"out_EXECUTE_QUEUE_OUT_OOO_ENGINE_ID <= reg_OOO_ENGINE_ID_0;");
    if (_param->_have_port_rob_ptr)
    vhdl->set_body (0,"out_EXECUTE_QUEUE_OUT_PACKET_ID <= reg_PACKET_ID_0;");
    vhdl->set_body (0, "out_EXECUTE_QUEUE_OUT_FLAGS <= reg_FLAGS_0;");
    vhdl->set_body (0, "out_EXECUTE_QUEUE_OUT_EXCEPTION <= reg_EXCEPTION_0;");
    vhdl->set_body (0, "out_EXECUTE_QUEUE_OUT_NO_SEQUENCE <= reg_NO_SEQUENCE_0;");
    vhdl->set_body (0, "out_EXECUTE_QUEUE_OUT_ADDRESS <= reg_ADDRESS_0;");
    vhdl->set_body (0, "out_EXECUTE_QUEUE_OUT_DATA <= reg_DATA_0;");


    vhdl->set_body (0,"");

    vhdl->set_body (0,"process (reg_CURRENT_STATE, in_EXECUTE_QUEUE_OUT_ACK, in_EXECUTE_QUEUE_IN_VAL, in_NRESET)");
    vhdl->set_body (0,"begin");
    vhdl->set_body (1,"if in_NRESET = '0' then");
    vhdl->set_body (2,"sig_NEXT_STATE <= STATE_0;");
    vhdl->set_body (1,"else");
    vhdl->set_body (2,"case reg_CURRENT_STATE is");
    for (uint32_t i = 0; i <_param->_size_queue + 1; i++)
      {
	vhdl->set_body (3,"when STATE_"+toString(i)+" =>");
	if (i == 0)
	  {
	    vhdl->set_body (4,"if in_EXECUTE_QUEUE_IN_VAL = '1' then");
	    vhdl->set_body (5,"sig_NEXT_STATE <= reg_CURRENT_STATE ("+toString(_param->_size_queue-1)+" downto 0) & '0';");
	    vhdl->set_body (4,"else");
	    vhdl->set_body (5,"sig_NEXT_STATE <= reg_CURRENT_STATE;");
	    vhdl->set_body (4,"end if;");
	    continue;
	  }
	if (i == (_param->_size_queue))
	  {
	    vhdl->set_body (4,"if in_EXECUTE_QUEUE_OUT_ACK = '1' then");
	    vhdl->set_body (5,"sig_NEXT_STATE <= '0' & reg_CURRENT_STATE ("+toString(_param->_size_queue)+" downto 1);");
	    vhdl->set_body (4,"else");
	    vhdl->set_body (5,"sig_NEXT_STATE <= reg_CURRENT_STATE;");
	    vhdl->set_body (4,"end if;");
	    continue;
	  }
	vhdl->set_body (4,"if in_EXECUTE_QUEUE_IN_VAL = '1' and in_EXECUTE_QUEUE_OUT_ACK = '0' then");
	vhdl->set_body (5,"sig_NEXT_STATE <= reg_CURRENT_STATE ("+toString(_param->_size_queue-1)+" downto 0) & '0';");
	vhdl->set_body (4,"elsif in_EXECUTE_QUEUE_IN_VAL = '0' and in_EXECUTE_QUEUE_OUT_ACK = '1' then");
	vhdl->set_body (5,"sig_NEXT_STATE <= '0' & reg_CURRENT_STATE ("+toString(_param->_size_queue)+" downto 1);");
	vhdl->set_body (4,"else");
	vhdl->set_body (5,"sig_NEXT_STATE <= reg_CURRENT_STATE;");
	vhdl->set_body (4,"end if;");
      }
    vhdl->set_body (3,"when others => assert false report \"wrong state\" severity failure;");
    vhdl->set_body (2,"end case;");
    vhdl->set_body (1,"end if;");

    vhdl->set_body (2,"case reg_CURRENT_STATE is");
    for (uint32_t i = 0; i <_param->_size_queue + 1; i++)
      {
	vhdl->set_body (3,"when STATE_"+toString(i)+" =>");
	if (i == 0)
	  {
	    vhdl->set_body (4,"sig_OUT_VAL <= '0';");
	    vhdl->set_body (4,"sig_IN_ACK <= '1';");
	    for (uint32_t j = 0; j <_param->_size_queue; j++)
	      {
		if (i == j)
		  {
		    vhdl->set_body (4,"sig_SEL_"+toString(j)+" <= '0';");
		    vhdl->set_body (4,"sig_WEN_"+toString(j)+" <= in_EXECUTE_QUEUE_IN_VAL;");
		  }
		else
		  {
		    if (j < (_param->_size_queue - 1))
		      vhdl->set_body (4,"sig_SEL_"+toString(j)+" <= '0';");
		    vhdl->set_body (4,"sig_WEN_"+toString(j)+" <= '0';");
		  }
	      }
	    continue;
	  }
	if (i == (_param->_size_queue))
	  {
	    vhdl->set_body (4,"sig_OUT_VAL <= '1';");
	    vhdl->set_body (4,"sig_IN_ACK <= '0';");
	    for (uint32_t j = 0; j <_param->_size_queue; j++)
	      {
		if (j == (i - 1))
		  {
		    vhdl->set_body (4,"sig_WEN_"+toString(j)+" <= '0';");
		  }
		else
		  {
		    vhdl->set_body (4,"sig_SEL_"+toString(j)+" <= in_EXECUTE_QUEUE_OUT_ACK;");
		    vhdl->set_body (4,"sig_WEN_"+toString(j)+" <= in_EXECUTE_QUEUE_OUT_ACK;");
		  }
	      }
	    continue;
	  }
	vhdl->set_body (4,"sig_OUT_VAL <= '1';");
	vhdl->set_body (4,"sig_IN_ACK <= '1';");
	for (uint32_t j = 0; j <_param->_size_queue; j++)
	  {
	    if (j < (i - 1))
	      {
		vhdl->set_body (4,"sig_SEL_"+toString(j)+" <= in_EXECUTE_QUEUE_OUT_ACK;");
		vhdl->set_body (4,"sig_WEN_"+toString(j)+" <= in_EXECUTE_QUEUE_OUT_ACK;");
	      }
	    if (j == (i - 1))
	      {
		vhdl->set_body (4,"sig_SEL_"+toString(j)+" <= '0';");
		vhdl->set_body (4,"sig_WEN_"+toString(j)+" <= in_EXECUTE_QUEUE_OUT_ACK and in_EXECUTE_QUEUE_IN_VAL;");
	      }
	    if (j == i)
	      {
		if (j < (_param->_size_queue - 1))
		  vhdl->set_body (4,"sig_SEL_"+toString(j)+" <= '0';");
		vhdl->set_body (4,"sig_WEN_"+toString(j)+" <= in_EXECUTE_QUEUE_IN_VAL and not in_EXECUTE_QUEUE_OUT_ACK;");
	      }
	    if (j > i)
	      {
		if (j < (_param->_size_queue - 1))
		  vhdl->set_body (4,"sig_SEL_"+toString(j)+" <= '0';");
		vhdl->set_body (4,"sig_WEN_"+toString(j)+" <= '0';");
	      }
	  }
      }
    vhdl->set_body (3,"when others =>");
    vhdl->set_body (2,"end case;");

    vhdl->set_body (0,"end process;");

 

//     vhdl->set_body (2,"end case;");
//     for (uint32_t i = 0; i <_param->_size_queue; i++)
//       {
// 	if (i == 0)
// 	  vhdl->set_body (4,"sig_WEN_"+toString(i)+" <= in_EXECUTE_QUEUE_IN_VAL;");
// 	else
// 	  vhdl->set_body (4,"sig_WEN_"+toString(i)+" <= '0';");
// 	if (i < _param->_size_queue - 1)
// 	  vhdl->set_body (4,"sig_SEL_"+toString(i)+" <= '0';");
//       }
//     vhdl->set_body (2,"end process;");
	
//     vhdl->set_body (0,"sig_TRANS_OUT <=");
//     vhdl->set_body (1,"'0' when reg_CURRENT_STATE = STATE_0 else");
//     vhdl->set_body (1,"'1';");

//     vhdl->set_body (0,"sig_TRANS_IN <=");
//     vhdl->set_body (1,"'0' when reg_CURRENT_STATE = STATE_"+toString(_param->_size_queue)+" else");
//     vhdl->set_body (1,"'1';");



//     vhdl->set_body (0,"sig_NEXT_STATE <=");
//     vhdl->set_body (1,"reg_CURRENT_STATE("+toString(_param->_size_queue-1)+" downto 0) & '0' when in_EXECUTE_QUEUE_IN_VAL = '1' and ((reg_CURRENT_STATE = STATE_0) xor (in_EXECUTE_QUEUE_OUT_ACK = '0')) and sig_TRANS_IN = '1' else");
//     vhdl->set_body (1,"'0' & reg_CURRENT_STATE("+toString(_param->_size_queue)+" downto 1) when in_EXECUTE_QUEUE_OUT_ACK = '1' and ((in_EXECUTE_QUEUE_IN_VAL = '0') xor (reg_CURRENT_STATE = STATE_"+toString(_param->_size_queue)+")) and sig_TRANS_OUT = '1' else");
//     vhdl->set_body (1,"reg_CURRENT_STATE;");

//     vhdl->set_body (0,"sig_WEN_0 <=");
//     vhdl->set_body (1,"in_EXECUTE_QUEUE_IN_VAL when reg_CURRENT_STATE = STATE_0 else");
//     vhdl->set_body (1,"in_EXECUTE_QUEUE_OUT_ACK and in_EXECUTE_QUEUE_IN_VAL when reg_CURRENT_STATE = STATE_1 else");
//     vhdl->set_body (1,"in_EXECUTE_QUEUE_OUT_ACK;");
//      for (uint32_t i = 1; i <_param->_size_queue-1; i++)
//       {
// 	vhdl->set_body (0,"sig_WEN_"+toString(i)+" <=");
// 	vhdl->set_body (1,"in_EXECUTE_QUEUE_IN_VAL and not in_EXECUTE_QUEUE_OUT_ACK when reg_CURRENT_STATE = STATE_"+toString(i)+" else");
// 	vhdl->set_body (1,"in_EXECUTE_QUEUE_IN_VAL and in_EXECUTE_QUEUE_OUT_ACK when reg_CURRENT_STATE = STATE_"+toString(i+1)+" else");
// 	vhdl->set_body (1,"in_EXECUTE_QUEUE_OUT_ACK;");
//       }
//     vhdl->set_body (0,"sig_WEN_"+toString(_param->_size_queue-1)+" <=");
//     vhdl->set_body (1,"in_EXECUTE_QUEUE_IN_VAL and not in_EXECUTE_QUEUE_OUT_ACK when reg_CURRENT_STATE = STATE_"+toString(_param->_size_queue-1)+" else");
//     vhdl->set_body (1,"in_EXECUTE_QUEUE_OUT_ACK;");

//     vhdl->set_body (0,"");
//     for (uint32_t i = 0; i <_param->_size_queue-1; i++)
//       {
// 	vhdl->set_body (0,"sig_SEL_"+toString(i)+" <=");
// 	vhdl->set_body (1,"'0' when reg_CURRENT_STATE = STATE_"+toString(i+1)+" or reg_CURRENT_STATE = STATE_"+toString(i)+" else");
// 	vhdl->set_body (1,"in_EXECUTE_QUEUE_OUT_ACK;");
//       }

//   process (reg_CURRENT_STATE, in_PUSH_0_VAL, in_POP_0_ACK)
//   begin
//     case reg_CURRENT_STATE is
    
// with reg_CURRENT_STATE select
//   sig_WEN0 <=
//   0 when 1,
//   4 when 6;
//       when "00001" => out_POP_0_VAL <= '0';
//                      out_PUSH_0_ACK <= '1';
//                      sig_SEL0 <= '0';
//                      sig_WEN0 <= in_PUSH_0_VAL;
//                      sig_SEL1 <= '0';
//                      sig_WEN1 <= '0';
//                      sig_SEL2 <= '0';
//                      sig_WEN2 <= '0';
//                      sig_WEN3 <= '0';
//                      if in_PUSH_0_VAL = '1' then
//                        sig_NEXT_STATE <= reg_CURRENT_STATE(3 downto 0) & '0';
//                      else
//                        sig_NEXT_STATE <= reg_CURRENT_STATE;
//                      end if;

//       when "00010" => out_POP_0_VAL <= '1';
//                      out_PUSH_0_ACK <= '1';
//                      sig_SEL0 <= '0';
//                      sig_WEN0 <= in_POP_0_ACK and in_PUSH_0_VAL;
//                      sig_SEL1 <= '0';
//                      sig_WEN1 <= in_PUSH_0_VAL and not in_POP_0_ACK;
//                      sig_SEL2 <= '0';
//                      sig_WEN2 <= '0';
//                      sig_WEN3 <= '0';
//                      if (in_PUSH_0_VAL = '1') and (in_POP_0_ACK = '0') then
//                        sig_NEXT_STATE <= reg_CURRENT_STATE(3 downto 0) & '0';
//                      elsif (in_PUSH_0_VAL = '0') and (in_POP_0_ACK = '1') then
//                        sig_NEXT_STATE <= '0' & reg_CURRENT_STATE(4 downto 1);
//                      else
//                        sig_NEXT_STATE <= reg_CURRENT_STATE;
//                      end if;

//       when "00100" => out_POP_0_VAL <= '1';
//                      out_PUSH_0_ACK <= '1';
//                      sig_SEL0 <= in_POP_0_ACK;
//                      sig_WEN0 <= in_POP_0_ACK;
//                      sig_SEL1 <= '0';
//                      sig_WEN1 <= in_POP_0_ACK and in_PUSH_0_VAL;
//                      sig_SEL2 <= '0';
//                      sig_WEN2 <= in_PUSH_0_VAL and not in_POP_0_ACK;
//                      sig_WEN3 <= '0';
//                      if (in_PUSH_0_VAL = '1') and (in_POP_0_ACK = '0') then
//                        sig_NEXT_STATE <= reg_CURRENT_STATE(3 downto 0) & '0';
//                      elsif (in_PUSH_0_VAL = '0') and (in_POP_0_ACK = '1') then
//                        sig_NEXT_STATE <= '0' & reg_CURRENT_STATE(4 downto 1);
//                      else
//                        sig_NEXT_STATE <= reg_CURRENT_STATE;
//                      end if;

//       when "01000" => out_POP_0_VAL <= '1';
//                      out_PUSH_0_ACK <= '1';
//                      sig_SEL0 <= in_POP_0_ACK;
//                      sig_WEN0 <= in_POP_0_ACK;
//                      sig_SEL1 <= in_POP_0_ACK;
//                      sig_WEN1 <= in_POP_0_ACK;
//                      sig_SEL2 <= '0';
//                      sig_WEN2 <= in_POP_0_ACK and in_PUSH_0_VAL;
//                      sig_WEN3 <= in_PUSH_0_VAL and not in_POP_0_ACK;
//                      if (in_PUSH_0_VAL = '1') and (in_POP_0_ACK = '0') then
//                        sig_NEXT_STATE <= reg_CURRENT_STATE(3 downto 0) & '0';
//                      elsif (in_PUSH_0_VAL = '0') and (in_POP_0_ACK = '1') then
//                        sig_NEXT_STATE <= '0' & reg_CURRENT_STATE(4 downto 1);
//                      else
//                        sig_NEXT_STATE <= reg_CURRENT_STATE;
//                      end if;

//       when "10000" => out_POP_0_VAL <= '1';
//                      out_PUSH_0_ACK <= '0';
//                      sig_SEL0 <= in_POP_0_ACK;
//                      sig_WEN0 <= in_POP_0_ACK;
//                      sig_SEL1 <= in_POP_0_ACK;
//                      sig_WEN1 <= in_POP_0_ACK;
//                      sig_SEL2 <= in_POP_0_ACK;
//                      sig_WEN2 <= in_POP_0_ACK;
//                      sig_WEN3 <= '0';
//                      if (in_PUSH_0_VAL = '0') and (in_POP_0_ACK = '1') then
//                        sig_NEXT_STATE <= '0' & reg_CURRENT_STATE(4 downto 1);
//                      else
//                        sig_NEXT_STATE <= reg_CURRENT_STATE;
//                      end if;

// 	    when others =>
// 			sig_next_state <= "00001";

// 	end case;
//   end process;

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

}; // end namespace execute_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
