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

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

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


  void RegisterFile::allocation (
#ifdef STATISTICS
				 morpheo::behavioural::Parameters_Statistics * param_statistics
#else
				 void
#endif
				 )
  {
    std::string rename;

    log_printf(FUNC,RegisterFile,"allocation","Begin");

    // ~~~~~[ Interface : "" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
      in_CLOCK              = new SC_CLOCK           ("in_CLOCK" );
      in_NRESET             = new SC_IN (Tcontrol_t) ("in_NRESET");
    }
    // ~~~~~[ 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++)
      { 
	rename =  "in_READ_"+toString(i)+"_VAL"    ;
	 in_READ_VAL     [i]  = new SC_IN (Tcontrol_t) (rename.c_str());   
	rename = "out_READ_"+toString(i)+"_ACK"    ;
	out_READ_ACK     [i]  = new SC_OUT(Tcontrol_t) (rename.c_str());
	if (_param->_have_port_address == true)
	  {
	rename =  "in_READ_"+toString(i)+"_ADDRESS";
	 in_READ_ADDRESS [i]  = new SC_IN (Taddress_t) (rename.c_str());
	  }
	rename = "out_READ_"+toString(i)+"_DATA"   ;
	out_READ_DATA    [i]  = new SC_OUT(Tdata_t   ) (rename.c_str());
      }

    // ~~~~~[ 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++)
      {
	rename =  "in_WRITE_"+toString(i)+"_VAL"    ;
	 in_WRITE_VAL     [i]  = new SC_IN (Tcontrol_t) (rename.c_str());
	rename = "out_WRITE_"+toString(i)+"_ACK"    ;
	out_WRITE_ACK     [i]  = new SC_OUT(Tcontrol_t) (rename.c_str());
	if (_param->_have_port_address == true)
	  {
	rename =  "in_WRITE_"+toString(i)+"_ADDRESS";
	 in_WRITE_ADDRESS [i]  = new SC_IN (Taddress_t) (rename.c_str());
	  }
	rename =  "in_WRITE_"+toString(i)+"_DATA"   ;
	 in_WRITE_DATA    [i]  = new SC_IN (Tdata_t   ) (rename.c_str());
      }

    // ~~~~~[ Component ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                                                
    if (_param->_instance == instance_RegisterFile_Monolithic)
    // =====[ component_RegisterFile_Monolithic ]=========================
      {
	component_RegisterFile_Monolithic  = new morpheo::behavioural::generic::registerfile::registerfile_monolithic  ::RegisterFile_Monolithic  ::RegisterFile_Monolithic   (_name.c_str()
#ifdef STATISTICS
																					       ,param_statistics
#endif
																					       ,_param->_param_registerfile_monolithic
																					       );
	
      }
    else
    // =====[ component_RegisterFile_Multi_Banked ]=======================
      {
	component_RegisterFile_Multi_Banked = new morpheo::behavioural::generic::registerfile::registerfile_multi_banked::RegisterFile_Multi_Banked::RegisterFile_Multi_Banked (_name.c_str()
#ifdef STATISTICS
																						,param_statistics
#endif
																						,_param->_param_registerfile_multi_banked
																						);
	
      }
    // ~~~~~[ Component - Instanciation ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    if (_param->_instance == instance_RegisterFile_Monolithic)
    // =====[ Component_RegisterFile_Monolithic - Instanciation ]=========
      {
	(*(component_RegisterFile_Monolithic  ->in_CLOCK )) (*(in_CLOCK ));
	(*(component_RegisterFile_Monolithic  ->in_NRESET)) (*(in_NRESET));
	
	for (uint32_t i=0; i<_param->_nb_port_read; i++)
	  { 
	    (*(component_RegisterFile_Monolithic  -> in_READ_VAL     [i])) (*( in_READ_VAL     [i]));   
	    (*(component_RegisterFile_Monolithic  ->out_READ_ACK     [i])) (*(out_READ_ACK     [i]));
	    if (_param->_have_port_address == true)
	    (*(component_RegisterFile_Monolithic  -> in_READ_ADDRESS [i])) (*( in_READ_ADDRESS [i]));
	    (*(component_RegisterFile_Monolithic  ->out_READ_DATA    [i])) (*(out_READ_DATA    [i]));
	  }
	
	for (uint32_t i=0; i<_param->_nb_port_write; i++)
	  {
	    (*(component_RegisterFile_Monolithic  -> in_WRITE_VAL     [i])) (*( in_WRITE_VAL     [i]));
	    (*(component_RegisterFile_Monolithic  ->out_WRITE_ACK     [i])) (*(out_WRITE_ACK     [i]));
	    if (_param->_have_port_address == true)
	    (*(component_RegisterFile_Monolithic  -> in_WRITE_ADDRESS [i])) (*( in_WRITE_ADDRESS [i]));
	    (*(component_RegisterFile_Monolithic  -> in_WRITE_DATA    [i])) (*( in_WRITE_DATA    [i]));
	  }
      }
    else
    // =====[ Component_RegisterFile_Multi_Banked - Instanciation ]=======
      {
	(*(component_RegisterFile_Multi_Banked->in_CLOCK )) (*(in_CLOCK ));
	(*(component_RegisterFile_Multi_Banked->in_NRESET)) (*(in_NRESET));
	
	for (uint32_t i=0; i<_param->_nb_port_read; i++)
	  { 
	    (*(component_RegisterFile_Multi_Banked-> in_READ_VAL     [i])) (*( in_READ_VAL     [i]));   
	    (*(component_RegisterFile_Multi_Banked->out_READ_ACK     [i])) (*(out_READ_ACK     [i]));
	    if (_param->_have_port_address == true)
	    (*(component_RegisterFile_Multi_Banked-> in_READ_ADDRESS [i])) (*( in_READ_ADDRESS [i]));
	    (*(component_RegisterFile_Multi_Banked->out_READ_DATA    [i])) (*(out_READ_DATA    [i]));
	  }
	
	for (uint32_t i=0; i<_param->_nb_port_write; i++)
	  {
	    (*(component_RegisterFile_Multi_Banked-> in_WRITE_VAL     [i])) (*( in_WRITE_VAL     [i]));
	    (*(component_RegisterFile_Multi_Banked->out_WRITE_ACK     [i])) (*(out_WRITE_ACK     [i]));
	    if (_param->_have_port_address == true)
	    (*(component_RegisterFile_Multi_Banked-> in_WRITE_ADDRESS [i])) (*( in_WRITE_ADDRESS [i]));
	    (*(component_RegisterFile_Multi_Banked-> in_WRITE_DATA    [i])) (*( in_WRITE_DATA    [i]));
	  }
      }

    if (_param->_instance == instance_RegisterFile_Monolithic)
      _component = component_RegisterFile_Monolithic  ->_component;
    else
      _component = component_RegisterFile_Multi_Banked->_component;

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

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

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