/*
 * $Id$
 *
 * [ Description ]
 * 
 */

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

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

  Parameters::Parameters (uint32_t    nb_port_read         ,
			  uint32_t    nb_port_write        ,
			  uint32_t    size_address         ,
			  uint32_t    size_word            ,
			  uint32_t    nb_bank              ,
			  uint32_t    nb_port_read_by_bank ,
			  uint32_t    nb_port_write_by_bank,
			  Tcrossbar_t crossbar             ):
    _nb_port_read          (nb_port_read         ),
    _nb_port_write         (nb_port_write        ),
    _size_address          (size_address         ),
    _size_word             (size_word            ),
    _nb_bank               (nb_bank              ),
    _nb_port_read_by_bank  (nb_port_read_by_bank ),
    _nb_port_write_by_bank (nb_port_write_by_bank),
    _crossbar              (crossbar             ),
    _shift_address         (static_cast<uint32_t>(ceil(log2(_nb_bank))))
  {
    log_printf(FUNC,RegisterFile_Multi_Banked_Glue,"Parameters","Begin");

    if (_crossbar == PARTIAL_CROSSBAR)
      {
	// All port_src is connected with one port_dest on each bank
	
	_link_port_read  = new uint32_t [_nb_port_read ];
	for (uint32_t i=0; i<_nb_port_read ; i++)
	  _link_port_read  [i] = i%_nb_port_read_by_bank;

	_link_port_write = new uint32_t [_nb_port_write];
	for (uint32_t i=0; i<_nb_port_write; i++)
	  _link_port_write [i] = i%_nb_port_write_by_bank;
      }
    // else : don't allocate

    _nb_port_select_by_bank_read_port  = new uint32_t [_nb_port_read_by_bank ];
    
    if (_crossbar == FULL_CROSSBAR)
      // All port_src is connected with all port_dest on each bank
      for (uint32_t i=0; i<_nb_port_read_by_bank ;i++)
	_nb_port_select_by_bank_read_port [i] = _nb_port_read;
    else
      // All port_src is connected with one port_dest on each bank
      {
	for (uint32_t i=0; i<_nb_port_read_by_bank ;i++)
	  _nb_port_select_by_bank_read_port [i] = 0;

	for (uint32_t i=0; i<_nb_port_read         ;i++)
	  _nb_port_select_by_bank_read_port [_link_port_read [i]] ++;
      }
    
    _nb_port_select_by_bank_write_port = new uint32_t [_nb_port_write_by_bank];

    if (_crossbar == FULL_CROSSBAR)
      // All port_src is connected with all port_dest on each bank
      for (uint32_t i=0; i<_nb_port_write_by_bank ;i++)
	_nb_port_select_by_bank_write_port [i] = _nb_port_write;
    else
      // All port_src is connected with one port_dest on each bank
      {
	for (uint32_t i=0; i<_nb_port_write_by_bank ;i++)
	  _nb_port_select_by_bank_write_port [i] = 0;

	for (uint32_t i=0; i<_nb_port_write         ;i++)
	  _nb_port_select_by_bank_write_port [_link_port_write[i]] ++;
      }
    
    test();
    log_printf(FUNC,RegisterFile_Multi_Banked_Glue,"Parameters","End");
  };
  
  Parameters::Parameters (Parameters & param):
    _nb_port_read          (param._nb_port_read         ),
    _nb_port_write         (param._nb_port_write        ),
    _size_address          (param._size_address         ),
    _size_word             (param._size_word            ),
    _nb_bank               (param._nb_bank              ),
    _nb_port_read_by_bank  (param._nb_port_read_by_bank ),
    _nb_port_write_by_bank (param._nb_port_write_by_bank),
    _crossbar              (param._crossbar             ),
    _shift_address         (param._shift_address        )
   {
    log_printf(FUNC,RegisterFile_Multi_Banked_Glue,"Parameters (copy)","Begin");

    _nb_port_select_by_bank_read_port  = new uint32_t [_nb_port_read_by_bank ];
    for (uint32_t i=0; i<_nb_port_read_by_bank; i++)
      _nb_port_select_by_bank_read_port [i] = param._nb_port_select_by_bank_read_port [i];
    
    _nb_port_select_by_bank_write_port = new uint32_t [_nb_port_write_by_bank ];
    for (uint32_t i=0; i<_nb_port_write_by_bank; i++)
      _nb_port_select_by_bank_write_port[i] = param._nb_port_select_by_bank_write_port [i];
    
    test();
    log_printf(FUNC,RegisterFile_Multi_Banked_Glue,"Parameters (copy)","End");
  };

  Parameters::~Parameters () 
  {
    log_printf(FUNC,RegisterFile_Multi_Banked_Glue,"~Parameters","Begin");
    log_printf(FUNC,RegisterFile_Multi_Banked_Glue,"~Parameters","End");
  };

}; // end namespace registerfile_multi_banked_glue
}; // end namespace registerfile_multi_banked
}; // end namespace registerfile
}; // end namespace generic
}; // end namespace behavioural
}; // end namespace morpheo              
