#ifdef VHDL
/*
 * $Id: RegisterFile_Monolithic_vhdl_body.cpp 101 2009-01-15 17:19:08Z rosiere $
 *
 * [ 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   (0,"");
    vhdl->set_comment(0,"---------------------------------------------------------------------------");
    vhdl->set_comment(0," Ackitement");
    vhdl->set_comment(0,"---------------------------------------------------------------------------");
    vhdl->set_body   (0,"");

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

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

	vhdl->set_body   (0,"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++)
      {
	std::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   (0,"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   (0,"");
    vhdl->set_comment(0,"---------------------------------------------------------------------------");
    vhdl->set_comment(0," Write RegisterFile");
    vhdl->set_comment(0,"---------------------------------------------------------------------------");
    vhdl->set_body   (0,"");

    vhdl->set_body   (0,"RegisterFile_write: process (in_CLOCK)");
    vhdl->set_body   (0,"begin  -- process RegisterFile_write");
    vhdl->set_body   (1,"if in_CLOCK'event and in_CLOCK = '1' then");

    if (_param->_have_init_value)
      {
        vhdl->set_body   (2,"if in_NRESET = '0' then");
        
        std::string init_value = ((_param->_size_word>1)?"\"":"'")+_param->_init_value+((_param->_size_word>1)?"\"":"'");
        
        for (uint32_t i=0; i<_param->_nb_word; ++i)
          vhdl->set_body   (3,"reg_DATA("+toString(i)+") <= "+init_value+";");

        vhdl->set_body   (2,"else");
      }
    
    for (uint32_t i = 0; i < _param->_nb_port_write; i++)
      {
	std::string str_address;
	if (_param->_have_port_address)
	  str_address = "conv_integer(in_WRITE_"+toString(i)+"_ADDRESS)";
	else
	  str_address = "0";

	vhdl->set_body   (2,"if (in_WRITE_"+toString(i)+"_VAL = '1') then");
	vhdl->set_body   (3,"reg_DATA("+str_address+") <= in_WRITE_"+toString(i)+"_DATA;");
	vhdl->set_body   (2,"end if;");
      }
    for (uint32_t i = 0; i < _param->_nb_port_read_write; i++)
      {
	std::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   (2,"if (in_READ_WRITE_"+toString(i)+"_VAL = '1' and in_READ_WRITE_"+toString(i)+"_RW = '"+toString(RW_WRITE)+"') then");
	vhdl->set_body   (3,"reg_DATA("+str_address+") <= in_READ_WRITE_"+toString(i)+"_WDATA;");
	vhdl->set_body   (2,"end if;");
      }

    vhdl->set_body   (1,"end if;");

    if (_param->_have_init_value)
      vhdl->set_body   (1,"end if;");

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

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