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

#include "Behavioural/Generic/RegisterFile/RegisterFile_Monolithic/include/RegisterFile_Monolithic.h"

namespace morpheo                    {
namespace behavioural                {
namespace generic                    {
namespace registerfile               {
namespace registerfile_monolithic    {

  void RegisterFile_Monolithic::vhdl_body (Vhdl * & vhdl)
  {
    vhdl->set_body ("");
    vhdl->set_body ("-----------------------------------------------------------------------------");
    vhdl->set_body ("-- Ackitement");
    vhdl->set_body ("-----------------------------------------------------------------------------");
    vhdl->set_body ("");

    for (uint32_t i = 0; i < _param->_nb_port_read; i++)
      vhdl->set_body ("out_READ_"+toString(i)+"_ACK  <= '1';");
    for (uint32_t i = 0; i < _param->_nb_port_write; i++)
      vhdl->set_body ("out_WRITE_"+toString(i)+"_ACK <= '1';");
    for (uint32_t i = 0; i < _param->_nb_port_read_write; i++)
      vhdl->set_body ("out_READ_WRITE_"+toString(i)+"_ACK  <= '1';");

    vhdl->set_body ("");
    vhdl->set_body ("-----------------------------------------------------------------------------");
    vhdl->set_body ("-- Read RegisterFile");
    vhdl->set_body ("-----------------------------------------------------------------------------");
    vhdl->set_body ("");
    
    for (uint32_t i = 0; i < _param->_nb_port_read; i++)
      {
	string str_address;
	if (_param->_have_port_address)
	  str_address = "conv_integer(in_READ_"+toString(i)+"_ADDRESS)";
	else
	  str_address = "0";

	vhdl->set_body ("out_READ_"+toString(i)+"_DATA <= reg_DATA ("+str_address+") when in_READ_"+toString(i)+"_VAL = '1' else "+std_logic_others(_param->_size_word,0)+";");
      }
    for (uint32_t i = 0; i < _param->_nb_port_read_write; i++)
      {
	string str_address;
	if (_param->_have_port_address)
	  str_address = "conv_integer(in_READ_WRITE_"+toString(i)+"_ADDRESS)";
	else
	  str_address = "0";
	vhdl->set_body ("out_READ_WRITE_"+toString(i)+"_RDATA <= reg_DATA ("+str_address+") when in_READ_WRITE_"+toString(i)+"_VAL = '1' and in_READ_WRITE_"+toString(i)+"_RW = '"+toString(RW_READ)+"' else "+std_logic_others(_param->_size_word,0)+";");
      }

    vhdl->set_body ("");
    vhdl->set_body ("-----------------------------------------------------------------------------");
    vhdl->set_body ("-- Write RegisterFile");
    vhdl->set_body ("-----------------------------------------------------------------------------");
    vhdl->set_body ("");

    vhdl->set_body ("RegisterFile_write: process (in_CLOCK)");
    vhdl->set_body ("begin  -- process RegisterFile_write");
    vhdl->set_body ("\tif in_CLOCK'event and in_CLOCK = '1' then");
    
    for (uint32_t i = 0; i < _param->_nb_port_write; i++)
      {
	string str_address;
	if (_param->_have_port_address)
	  str_address = "conv_integer(in_WRITE_"+toString(i)+"_ADDRESS)";
	else
	  str_address = "0";

	vhdl->set_body ("\t\tif (in_WRITE_"+toString(i)+"_VAL = '1') then");
	vhdl->set_body ("\t\t\treg_DATA("+str_address+") <= in_WRITE_"+toString(i)+"_DATA;");
	vhdl->set_body ("\t\tend if;");
      }
    for (uint32_t i = 0; i < _param->_nb_port_read_write; i++)
      {
	string str_address;
	if (_param->_have_port_address)
	  str_address = "conv_integer(in_READ_WRITE_"+toString(i)+"_ADDRESS)";
	else
	  str_address = "0";
	
	vhdl->set_body ("\t\tif (in_READ_WRITE_"+toString(i)+"_VAL = '1' and in_READ_WRITE_"+toString(i)+"_RW = '"+toString(RW_WRITE)+"') then");
	vhdl->set_body ("\t\t\treg_DATA("+str_address+") <= in_READ_WRITE_"+toString(i)+"_WDATA;");
	vhdl->set_body ("\t\tend if;");
      }

    vhdl->set_body ("\tend if;");
    vhdl->set_body ("end process RegisterFile_write;");
  };

}; // end namespace registerfile_monolithic
}; // end namespace registerfile 
}; // end namespace generic
}; // end namespace behavioural          
}; // end namespace morpheo              
#endif
