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

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

namespace morpheo                    {
namespace behavioural {
namespace generic {
namespace registerfile {
namespace registerfile_multi_banked {


  void RegisterFile_Multi_Banked::allocation (void)
  {
    log_printf(FUNC,RegisterFile_Multi_Banked,"allocation","Begin");

    _component   = new Component ();

    Entity * entity = _component->set_entity (_name       
					      ,"RegisterFile_Multi_Banked"
#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, CLOCK_VHDL_YES);
     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 == true)
     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 == true)
	 in_READ_ADDRESS [i]  = interface->set_signal_in  <Taddress_t> ("address", static_cast<uint32_t>(log2(_param->_nb_word)));
	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 == true)
     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 == true)
	 in_WRITE_ADDRESS [i]  = interface->set_signal_in  <Taddress_t> ("address", static_cast<uint32_t>(log2(_param->_nb_word)));
	 in_WRITE_DATA    [i]  = interface->set_signal_in  <Tdata_t   > ("data"   , _param->_size_word);
      }

    // ~~~~~[ Registers ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    reg_DATA = new SC_REGISTER (Tdata_t) ** [_param->_nb_bank];

    for (uint32_t i=0; i<_param->_nb_bank; i++)
      {
	reg_DATA [i] = new SC_REGISTER (Tdata_t) * [_param->_nb_word];
	
	for (uint32_t j=0; j<_param->_nb_word; j++)
	  {
	    std::string rename = "reg_DATA_"  + toString(i) + "_"  + toString(j);
	    reg_DATA [i][j]  = new SC_REGISTER (Tdata_t) (rename.c_str());
	  }
      }

    // ~~~~~[ Internal ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    internal_WRITE_VAL     = new bool       [_param->_nb_port_write];
    internal_WRITE_BANK    = new Taddress_t [_param->_nb_port_write];
    internal_WRITE_NUM_REG = new Taddress_t [_param->_nb_port_write];

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

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

    log_printf(FUNC,RegisterFile_Multi_Banked,"allocation","End");
  };

}; // end namespace registerfile_multi_banked
}; // end namespace registerfile
}; // end namespace generic

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