/*
 * $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         (_size_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_in_to_out          = new uint32_t [_nb_port_read ];
	_link_port_read_in_to_select       = new uint32_t [_nb_port_read ];
	_link_port_write_in_to_out         = new uint32_t [_nb_port_write];
	_link_port_write_in_to_select      = new uint32_t [_nb_port_write];
	uint32_t _nb_port_select_by_bank_read_port  [_nb_port_read_by_bank ];
	uint32_t _nb_port_select_by_bank_write_port [_nb_port_write_by_bank];
	
	// init
	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++)
	  {
	    uint32_t x = i%_nb_port_read_by_bank;
	    _link_port_read_in_to_out          [i] = x;
	    _link_port_read_in_to_select       [i] = _nb_port_select_by_bank_read_port [x];
	    _nb_port_select_by_bank_read_port  [x] ++;
	  }

	// init
	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++)
	  {
	    uint32_t x = i%_nb_port_write_by_bank;
	    _link_port_write_in_to_out         [i] = x;
	    _link_port_write_in_to_select      [i] = _nb_port_select_by_bank_write_port [x];
	    _nb_port_select_by_bank_write_port [x] ++;
	  }
      }
    // else : don't allocate

    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");
    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              
