/*
 * $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::allocation (void)
  {
    _component   = new Component (_usage);

    Entity * entity = _component->set_entity (_name                   
					     ,"RegisterFile_Monolithic"
#ifdef POSITION
					     ,REGISTER                 
#endif
					      );
    
    _interfaces = entity->set_interfaces();

    // ~~~~~[ Interface : "" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      Interface * interface = _interfaces->set_interface(""
#ifdef POSITION
							 , IN
							 ,SOUTH
							 , "Generalist interface"
#endif
							 );
      
      in_CLOCK              = interface->set_signal_clk              ("clock" ,1);
      in_NRESET             = interface->set_signal_in  <Tcontrol_t> ("nreset",1, RESET_VHDL_YES);
    }
    // ~~~~~[ Interface : "read" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     in_READ_VAL         = new SC_IN (Tcontrol_t) * [_param->_nb_port_read];
    out_READ_ACK         = new SC_OUT(Tcontrol_t) * [_param->_nb_port_read];
    if (_param->_have_port_address)
     in_READ_ADDRESS     = new SC_IN (Taddress_t) * [_param->_nb_port_read];
    out_READ_DATA        = new SC_OUT(Tdata_t   ) * [_param->_nb_port_read];

    for (uint32_t i=0; i<_param->_nb_port_read; i++)
      { 
	Interface_fifo * interface = _interfaces->set_interface("read_"+toString(i)
#ifdef POSITION
								, IN  
								,WEST
								, "Interface Read"
#endif
								);

	 in_READ_VAL     [i]  = interface->set_signal_valack_in        ("val"    , VAL);
	out_READ_ACK     [i]  = interface->set_signal_valack_out       ("ack"    , ACK);
	if (_param->_have_port_address)
	 in_READ_ADDRESS [i]  = interface->set_signal_in  <Taddress_t> ("address", _param->_size_address);
	out_READ_DATA    [i]  = interface->set_signal_out <Tdata_t   > ("data"   , _param->_size_word);
      }

    // ~~~~~[ Interface : "write" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     in_WRITE_VAL        = new SC_IN (Tcontrol_t) * [_param->_nb_port_write];
    out_WRITE_ACK        = new SC_OUT(Tcontrol_t) * [_param->_nb_port_write];
    if (_param->_have_port_address)
     in_WRITE_ADDRESS    = new SC_IN (Taddress_t) * [_param->_nb_port_write];
     in_WRITE_DATA       = new SC_IN (Tdata_t   ) * [_param->_nb_port_write];
    
    for (uint32_t i=0; i<_param->_nb_port_write; i++)
      {
	Interface_fifo * interface = _interfaces->set_interface("write_"+toString(i)
#ifdef POSITION
								, IN  
								,EAST
								, "Interface Write"
#endif
								);

	 in_WRITE_VAL     [i]  = interface->set_signal_valack_in        ("val"    , VAL);
	out_WRITE_ACK     [i]  = interface->set_signal_valack_out       ("ack"    , ACK);
	if (_param->_have_port_address)
	 in_WRITE_ADDRESS [i]  = interface->set_signal_in  <Taddress_t> ("address", _param->_size_address);
	 in_WRITE_DATA    [i]  = interface->set_signal_in  <Tdata_t   > ("data"   , _param->_size_word);
      }

    // ~~~~~[ Interface : "read_write" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     in_READ_WRITE_VAL         = new SC_IN (Tcontrol_t) * [_param->_nb_port_read_write];
    out_READ_WRITE_ACK         = new SC_OUT(Tcontrol_t) * [_param->_nb_port_read_write];
     in_READ_WRITE_RW          = new SC_IN (Tcontrol_t) * [_param->_nb_port_read_write];
    if (_param->_have_port_address)
     in_READ_WRITE_ADDRESS     = new SC_IN (Taddress_t) * [_param->_nb_port_read_write];
     in_READ_WRITE_WDATA       = new SC_IN (Tdata_t   ) * [_param->_nb_port_read_write];
    out_READ_WRITE_RDATA       = new SC_OUT(Tdata_t   ) * [_param->_nb_port_read_write];

    for (uint32_t i=0; i<_param->_nb_port_read_write; i++)
      { 
	Interface_fifo * interface = _interfaces->set_interface("read_write_"+toString(i)
#ifdef POSITION
								, IN  
								,WEST
								, "Interface Read_Write"
#endif
								);

	 in_READ_WRITE_VAL     [i]  = interface->set_signal_valack_in        ("val"    , VAL);
	out_READ_WRITE_ACK     [i]  = interface->set_signal_valack_out       ("ack"    , ACK);
	 in_READ_WRITE_RW      [i]  = interface->set_signal_valack_in        ("rw"     , VAL);
	if (_param->_have_port_address)
	 in_READ_WRITE_ADDRESS [i]  = interface->set_signal_in  <Taddress_t> ("address", _param->_size_address);
	 in_READ_WRITE_WDATA   [i]  = interface->set_signal_in  <Tdata_t   > ("wdata"  , _param->_size_word);
	out_READ_WRITE_RDATA   [i]  = interface->set_signal_out <Tdata_t   > ("rdata"  , _param->_size_word);
      }

    // ----- Register
    reg_DATA = new SC_REGISTER (Tdata_t) * [_param->_nb_word];
    
    for (uint32_t i=0; i<_param->_nb_word; i++)
      {
	string rename = "reg_DATA["  + toString(i) + "]";
	reg_DATA [i]  = new SC_REGISTER (Tdata_t) (rename.c_str());
      }

#ifdef POSITION
    _component->generate_file();
#endif
  };

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