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

#define NB_ITERATION 16

#define LABEL(str) do {cout << "{"+toString(static_cast<uint32_t>(sc_simulation_time()))+"} " << str << endl; _RegisterFile_Multi_Banked_Glue->vhdl_testbench_label(str);} while (0)

#include "Behavioural/Generic/RegisterFile/RegisterFile_Multi_Banked/RegisterFile_Multi_Banked_Glue/SelfTest/include/test.h"
#include "Include/Test.h"
#include "Include/BitManipulation.h"

void test (string name,
	   morpheo::behavioural::generic::registerfile::registerfile_multi_banked::registerfile_multi_banked_glue::Parameters _param)
{
  cout << "<" << name << "> : Simulation SystemC" << endl;

  RegisterFile_Multi_Banked_Glue * _RegisterFile_Multi_Banked_Glue = new RegisterFile_Multi_Banked_Glue (name.c_str(),
#ifdef STATISTICS
													 morpheo::behavioural::Parameters_Statistics(5,50),
#endif
													 _param);
  
#ifdef SYSTEMC
  /*********************************************************************
   * Déclarations des signaux
   *********************************************************************/
  sc_clock                               * CLOCK;

  sc_signal<Tcontrol_t>                 ** READ_IN_VAL       ;
  sc_signal<Tcontrol_t>                 ** READ_IN_ACK       ;
  sc_signal<Taddress_t>                 ** READ_IN_ADDRESS   ;
  sc_signal<Tdata_t   >                 ** READ_IN_DATA      ;
  sc_signal<Tcontrol_t>               **** READ_SELECT_VAL   ;
  sc_signal<Tcontrol_t>               **** READ_SELECT_ACK   ;
  sc_signal<Tcontrol_t>                *** READ_OUT_VAL      ;
  sc_signal<Tcontrol_t>                *** READ_OUT_ACK      ;
  sc_signal<Taddress_t>                *** READ_OUT_ADDRESS  ;
  sc_signal<Tdata_t   >                *** READ_OUT_DATA     ;
  sc_signal<Tcontrol_t>                 ** WRITE_IN_VAL      ;
  sc_signal<Tcontrol_t>                 ** WRITE_IN_ACK      ;
  sc_signal<Taddress_t>                 ** WRITE_IN_ADDRESS  ;
  sc_signal<Tdata_t   >                 ** WRITE_IN_DATA     ;
  sc_signal<Tcontrol_t>               **** WRITE_SELECT_VAL  ;
  sc_signal<Tcontrol_t>               **** WRITE_SELECT_ACK  ;
  sc_signal<Tcontrol_t>                *** WRITE_OUT_VAL     ;
  sc_signal<Tcontrol_t>                *** WRITE_OUT_ACK     ;
  sc_signal<Taddress_t>                *** WRITE_OUT_ADDRESS ;
  sc_signal<Tdata_t   >                *** WRITE_OUT_DATA    ;

  string rename;

  CLOCK                                  = new sc_clock ("clock", 1.0, 0.5);

  READ_IN_VAL       = new sc_signal<Tcontrol_t>           * [_param._nb_port_read];
  READ_IN_ACK       = new sc_signal<Tcontrol_t>           * [_param._nb_port_read];
  READ_IN_ADDRESS   = new sc_signal<Taddress_t>           * [_param._nb_port_read];
  READ_IN_DATA      = new sc_signal<Tdata_t   >           * [_param._nb_port_read];

  for (uint32_t i=0; i<_param._nb_port_read; i++)
    {
      rename = "READ_IN_VAL_"+toString(i)+"      ";
      READ_IN_VAL       [i] = new sc_signal<Tcontrol_t> (rename.c_str());
      rename = "READ_IN_ACK_"+toString(i)+"      ";
      READ_IN_ACK       [i] = new sc_signal<Tcontrol_t> (rename.c_str());
      rename = "READ_IN_ADDRESS_"+toString(i)+"  ";
      READ_IN_ADDRESS   [i] = new sc_signal<Taddress_t> (rename.c_str());
      rename = "READ_IN_DATA_"+toString(i)+"     ";
      READ_IN_DATA      [i] = new sc_signal<Tdata_t   > (rename.c_str());
    }

   READ_SELECT_VAL  = new sc_signal<Tcontrol_t> *** [_param._nb_bank];
   READ_SELECT_ACK  = new sc_signal<Tcontrol_t> *** [_param._nb_bank];

    for (uint32_t i=0; i<_param._nb_bank; i++)
      {
	READ_SELECT_VAL [i] = new sc_signal<Tcontrol_t>  ** [_param._nb_port_read_by_bank];
	READ_SELECT_ACK [i] = new sc_signal<Tcontrol_t>  ** [_param._nb_port_read_by_bank];

	 for (uint32_t j=0; j<_param._nb_port_read_by_bank; j++)
	   {
	     READ_SELECT_VAL [i][j] = new sc_signal<Tcontrol_t>   * [_param._nb_port_select_by_bank_read_port [j]];
	     READ_SELECT_ACK [i][j] = new sc_signal<Tcontrol_t>   * [_param._nb_port_select_by_bank_read_port [j]];
	     
	     for (uint32_t k=0; k<_param._nb_port_select_by_bank_read_port [j]; k++)
	       {
		 rename="READ_SELECT_VAL_"+toString(i)+"_"+toString(j)+"_"+toString(k)+" ";
		 READ_SELECT_VAL [i][j][k] = new sc_signal<Tcontrol_t> (rename.c_str());
		 
		 rename="READ_SELECT_ACK_"+toString(i)+"_"+toString(j)+"_"+toString(k)+" ";
		 READ_SELECT_ACK [i][j][k] = new sc_signal<Tcontrol_t> (rename.c_str());
	       }
	   }
      }
   						      
   READ_OUT_VAL      = new sc_signal<Tcontrol_t>          ** [_param._nb_bank];
   READ_OUT_ACK      = new sc_signal<Tcontrol_t>          ** [_param._nb_bank];
   READ_OUT_ADDRESS  = new sc_signal<Taddress_t>          ** [_param._nb_bank];
   READ_OUT_DATA     = new sc_signal<Tdata_t   >          ** [_param._nb_bank];

   for (uint32_t i=0; i<_param._nb_bank; i++)
     {
       READ_OUT_VAL      [i] = new sc_signal<Tcontrol_t>          * [_param._nb_port_read_by_bank];
       READ_OUT_ACK      [i] = new sc_signal<Tcontrol_t>          * [_param._nb_port_read_by_bank];
       READ_OUT_ADDRESS  [i] = new sc_signal<Taddress_t>          * [_param._nb_port_read_by_bank];
       READ_OUT_DATA     [i] = new sc_signal<Tdata_t   >          * [_param._nb_port_read_by_bank];
       
       for (uint32_t j=0; j<_param._nb_port_read_by_bank; j++)
	 {
	   rename="READ_OUT_VAL_"+toString(i)+"_"+toString(j)+"      ";
	   READ_OUT_VAL      [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	   rename="READ_OUT_ACK_"+toString(i)+"_"+toString(j)+"      ";
	   READ_OUT_ACK      [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	   rename="READ_OUT_ADDRESS_"+toString(i)+"_"+toString(j)+"  ";
	   READ_OUT_ADDRESS  [i][j] = new sc_signal<Taddress_t> (rename.c_str());
	   rename="READ_OUT_DATA_"+toString(i)+"_"+toString(j)+"     ";
	   READ_OUT_DATA     [i][j] = new sc_signal<Tdata_t   > (rename.c_str());
	 }
     }
   
   WRITE_IN_VAL      = new sc_signal<Tcontrol_t>           * [_param._nb_port_write];
   WRITE_IN_ACK      = new sc_signal<Tcontrol_t>           * [_param._nb_port_write];
   WRITE_IN_ADDRESS  = new sc_signal<Taddress_t>           * [_param._nb_port_write];
   WRITE_IN_DATA     = new sc_signal<Tdata_t   >           * [_param._nb_port_write];
   for (uint32_t i=0; i<_param._nb_port_write; i++)
     {
       rename = "WRITE_IN_VAL_"+toString(i)+"     ";
       WRITE_IN_VAL      [i] = new sc_signal<Tcontrol_t> (rename.c_str());
       rename = "WRITE_IN_ACK_"+toString(i)+"     ";
       WRITE_IN_ACK      [i] = new sc_signal<Tcontrol_t> (rename.c_str());
       rename = "WRITE_IN_ADDRESS_"+toString(i)+" ";
       WRITE_IN_ADDRESS  [i] = new sc_signal<Taddress_t> (rename.c_str());
       rename = "WRITE_IN_DATA_"+toString(i)+"    ";
       WRITE_IN_DATA     [i] = new sc_signal<Tdata_t   > (rename.c_str());
     }

   WRITE_SELECT_VAL  = new sc_signal<Tcontrol_t> *** [_param._nb_bank];
   WRITE_SELECT_ACK  = new sc_signal<Tcontrol_t> *** [_param._nb_bank];

    for (uint32_t i=0; i<_param._nb_bank; i++)
      {
	WRITE_SELECT_VAL [i] = new sc_signal<Tcontrol_t>  ** [_param._nb_port_write_by_bank];
	WRITE_SELECT_ACK [i] = new sc_signal<Tcontrol_t>  ** [_param._nb_port_write_by_bank];

	 for (uint32_t j=0; j<_param._nb_port_write_by_bank; j++)
	   {
	     WRITE_SELECT_VAL [i][j] = new sc_signal<Tcontrol_t>   * [_param._nb_port_select_by_bank_write_port [j]];
	     WRITE_SELECT_ACK [i][j] = new sc_signal<Tcontrol_t>   * [_param._nb_port_select_by_bank_write_port [j]];
	     
	     for (uint32_t k=0; k<_param._nb_port_select_by_bank_write_port [j]; k++)
	       {
		 rename="WRITE_SELECT_VAL_"+toString(i)+"_"+toString(j)+"_"+toString(k)+" ";
		 WRITE_SELECT_VAL [i][j][k] = new sc_signal<Tcontrol_t> (rename.c_str());
		 
		 rename="WRITE_SELECT_ACK_"+toString(i)+"_"+toString(j)+"_"+toString(k)+" ";
		 WRITE_SELECT_ACK [i][j][k] = new sc_signal<Tcontrol_t> (rename.c_str());
	       }
	   }
      }
      
   WRITE_OUT_VAL     = new sc_signal<Tcontrol_t>          ** [_param._nb_bank];
   WRITE_OUT_ACK     = new sc_signal<Tcontrol_t>          ** [_param._nb_bank];
   WRITE_OUT_ADDRESS = new sc_signal<Taddress_t>          ** [_param._nb_bank];
   WRITE_OUT_DATA    = new sc_signal<Tdata_t   >          ** [_param._nb_bank];
   
   for (uint32_t i=0; i<_param._nb_bank; i++)
     {
       WRITE_OUT_VAL     [i] = new sc_signal<Tcontrol_t>          * [_param._nb_port_write_by_bank];
       WRITE_OUT_ACK     [i] = new sc_signal<Tcontrol_t>          * [_param._nb_port_write_by_bank];
       WRITE_OUT_ADDRESS [i] = new sc_signal<Taddress_t>          * [_param._nb_port_write_by_bank];
       WRITE_OUT_DATA    [i] = new sc_signal<Tdata_t   >          * [_param._nb_port_write_by_bank];
       
       for (uint32_t j=0; j<_param._nb_port_write_by_bank; j++)
	 {
	   rename = "WRITE_OUT_VAL_"+toString(i)+"_"+toString(j)+"     ";
	   WRITE_OUT_VAL     [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	   rename = "WRITE_OUT_ACK_"+toString(i)+"_"+toString(j)+"     ";
	   WRITE_OUT_ACK     [i][j] = new sc_signal<Tcontrol_t> (rename.c_str());
	   rename = "WRITE_OUT_ADDRESS_"+toString(i)+"_"+toString(j)+" ";
	   WRITE_OUT_ADDRESS [i][j] = new sc_signal<Taddress_t> (rename.c_str());
	   rename = "WRITE_OUT_DATA_"+toString(i)+"_"+toString(j)+"    ";
	   WRITE_OUT_DATA    [i][j] = new sc_signal<Tdata_t   > (rename.c_str());
	 }
     }
  
  /********************************************************
   * Instanciation
   ********************************************************/
  
  cout << "<" << name << "> Instanciation of _RegisterFile_Multi_Banked_Glue" << endl;
  
  (*(_RegisterFile_Multi_Banked_Glue->in_CLOCK))        (*(CLOCK));

   for (uint32_t i=0; i<_param._nb_port_read; i++)
     {
       (*(_RegisterFile_Multi_Banked_Glue-> in_READ_IN_VAL       [i]))       (*(READ_IN_VAL       [i]));
       (*(_RegisterFile_Multi_Banked_Glue->out_READ_IN_ACK       [i]))       (*(READ_IN_ACK       [i]));
       (*(_RegisterFile_Multi_Banked_Glue-> in_READ_IN_ADDRESS   [i]))       (*(READ_IN_ADDRESS   [i]));
       (*(_RegisterFile_Multi_Banked_Glue->out_READ_IN_DATA      [i]))       (*(READ_IN_DATA      [i]));
     }

   for (uint32_t i=0; i<_param._nb_bank; i++)
     for (uint32_t j=0; j<_param._nb_port_read_by_bank; j++)
       for (uint32_t k=0; k<_param._nb_port_select_by_bank_read_port[j]; k++)
	 {
	   (*(_RegisterFile_Multi_Banked_Glue->out_READ_SELECT_VAL [i][j][k])) (*(READ_SELECT_VAL [i][j][k]));
	   (*(_RegisterFile_Multi_Banked_Glue-> in_READ_SELECT_ACK [i][j][k])) (*(READ_SELECT_ACK [i][j][k]));
	 }

   for (uint32_t i=0; i<_param._nb_bank; i++)
       for (uint32_t j=0; j<_param._nb_port_read_by_bank; j++)
	 {
	   (*(_RegisterFile_Multi_Banked_Glue->out_READ_OUT_VAL      [i][j]))       (*(READ_OUT_VAL      [i][j]));
	   (*(_RegisterFile_Multi_Banked_Glue-> in_READ_OUT_ACK      [i][j]))       (*(READ_OUT_ACK      [i][j]));
	   (*(_RegisterFile_Multi_Banked_Glue->out_READ_OUT_ADDRESS  [i][j]))       (*(READ_OUT_ADDRESS  [i][j]));
	   (*(_RegisterFile_Multi_Banked_Glue-> in_READ_OUT_DATA     [i][j]))       (*(READ_OUT_DATA     [i][j]));
	 }

   for (uint32_t i=0; i<_param._nb_port_write; i++)
     {
       (*(_RegisterFile_Multi_Banked_Glue-> in_WRITE_IN_VAL      [i]))       (*(WRITE_IN_VAL      [i]));
       (*(_RegisterFile_Multi_Banked_Glue->out_WRITE_IN_ACK      [i]))       (*(WRITE_IN_ACK      [i]));
       (*(_RegisterFile_Multi_Banked_Glue-> in_WRITE_IN_ADDRESS  [i]))       (*(WRITE_IN_ADDRESS  [i]));
       (*(_RegisterFile_Multi_Banked_Glue-> in_WRITE_IN_DATA     [i]))       (*(WRITE_IN_DATA     [i]));
     }

   for (uint32_t i=0; i<_param._nb_bank; i++)
     for (uint32_t j=0; j<_param._nb_port_write_by_bank; j++)
       for (uint32_t k=0; k<_param._nb_port_select_by_bank_write_port[j]; k++)
	 {
	   (*(_RegisterFile_Multi_Banked_Glue->out_WRITE_SELECT_VAL [i][j][k])) (*(WRITE_SELECT_VAL [i][j][k]));
	   (*(_RegisterFile_Multi_Banked_Glue-> in_WRITE_SELECT_ACK [i][j][k])) (*(WRITE_SELECT_ACK [i][j][k]));
	 }

   for (uint32_t i=0; i<_param._nb_bank; i++)
       for (uint32_t j=0; j<_param._nb_port_write_by_bank; j++)
	 {
	   (*(_RegisterFile_Multi_Banked_Glue->out_WRITE_OUT_VAL     [i][j]))       (*(WRITE_OUT_VAL     [i][j]));
	   (*(_RegisterFile_Multi_Banked_Glue-> in_WRITE_OUT_ACK     [i][j]))       (*(WRITE_OUT_ACK     [i][j]));
	   (*(_RegisterFile_Multi_Banked_Glue->out_WRITE_OUT_ADDRESS [i][j]))       (*(WRITE_OUT_ADDRESS [i][j]));
	   (*(_RegisterFile_Multi_Banked_Glue->out_WRITE_OUT_DATA    [i][j]))       (*(WRITE_OUT_DATA    [i][j]));
	 }


  cout << "<" << name << "> Start Simulation ............" << endl;
  
  /********************************************************
   * Simulation - Begin
   ********************************************************/

  // Initialisation

  const uint32_t seed = 0;
//const uint32_t seed = static_cast<uint32_t>(time(NULL));

  srand(seed);

  sc_start(0);

  LABEL("Initialisation");

  uint32_t   read_in_num_bank [_param._nb_port_read]; // Number of bank
//Tcontrol_t read_in_valid    [_param._nb_port_read];
  Tcontrol_t read_in_ack      [_param._nb_port_read]; // to test
  Tdata_t    read_in_data     [_param._nb_port_read]; // to test
  Tcontrol_t read_out_val     [_param._nb_bank][_param._nb_port_read_by_bank];  
  Tcontrol_t read_out_ack     [_param._nb_bank][_param._nb_port_read_by_bank];  
  Taddress_t read_out_address [_param._nb_bank][_param._nb_port_read_by_bank];  
  Tcontrol_t read_is_busy     [_param._nb_port_read];
  Tcontrol_t read_select_val  [_param._nb_bank][_param._nb_port_read        ];
  Tcontrol_t read_select_ack  [_param._nb_bank][_param._nb_port_read        ];

  LABEL("Loop of Test");

  for (uint32_t iteration=0; iteration<NB_ITERATION; iteration ++)
    {
      LABEL("Iteration "+toString(iteration));
      
      LABEL("Test read_in");
      
      // Write in interface "read_in"
      for (uint32_t i=0; i<_param._nb_port_read; i++)
	{
	  read_in_num_bank  [i] =  rand() % _param._nb_bank;
	  Tcontrol_t read_in_valid = (rand() % 2) != 0;

	  Taddress_t address    = (read_in_num_bank[i] << _param._shift_address) | (gen_mask<Taddress_t>(_param._size_address-_param._shift_address) & i);

	  read_is_busy      [i] = (read_in_valid == 0);
	  read_in_ack       [i] = 0;
	  read_in_data      [i] = 0;
	  READ_IN_VAL       [i]->write(read_in_valid);
	  READ_IN_ADDRESS   [i]->write(address);

	  for (uint32_t j=0; j<_param._nb_bank; j++)
	    read_select_ack [j][i] = 0;
	}

      for (uint32_t i=0; i<_param._nb_bank; i++)
	for (uint32_t j=0; j<_param._nb_port_read_by_bank; j++)
	  {
	    read_out_ack      [i][j] = (rand() % 2) != 0;
	    READ_OUT_ACK      [i][j]->write(read_out_ack      [i][j]);
	    READ_OUT_DATA     [i][j]->write((j<<1)|1); // (j<<1)|1 afin de n'avoir jamais 0
	  }
      
      // compute the good read_select
      for (uint32_t i=0; i<_param._nb_bank; i++)
	for (uint32_t j=0; j<_param._nb_port_read_by_bank; j++)
	  {
	    bool find = false; // have find a port_in to link with this port_out
	    for (uint32_t k=0; k<_param._nb_port_select_by_bank_read_port[j]; k++)
	      {

		uint32_t num_port; // number of port
		
		// compute the good number of port
		if (_param._crossbar == FULL_CROSSBAR)
		  num_port = k;
		else
		  num_port = _param._link_port_read [i];

		read_select_val [i][num_port] = read_out_ack [i][j] && not read_is_busy [num_port];
		
		if ((read_out_ack [i][j] == 0) || find)
		  read_select_ack [i][num_port] = 0; // read_out is busy or already find
		else
		  {
		    // find a busy port?
		    find = not read_is_busy [num_port];
		    read_is_busy       [num_port]|= find;
		    read_select_ack [i][num_port] = find;

		    if (find)
		      {
			read_in_ack      [num_port] = 1;
			read_in_data     [num_port] = ((j<<1)|1);
			read_out_val     [i][j]     = 1;
			read_out_address [i][j]     = (read_in_num_bank[i] << _param._shift_address) | (gen_mask<Taddress_t>(_param._size_address-_param._shift_address) & i);
		      }
		  }
		
		READ_SELECT_ACK [i][j][k]->write(read_select_ack [i][num_port]);
	      }
	  }

      // next cycle
      sc_start(1);

//       // lot of test
//   public    : SC_OUT(Tcontrol_t)           ** out_READ_IN_ACK       ;
//   public    : SC_OUT(Tdata_t   )           ** out_READ_IN_DATA      ;

//   public    : SC_OUT(Tcontrol_t)         **** out_READ_SELECT_VAL   ;

//   public    : SC_OUT(Tcontrol_t)          *** out_READ_OUT_VAL      ;
//   public    : SC_OUT(Taddress_t)          *** out_READ_OUT_ADDRESS  ;

    }

  /********************************************************
   * Simulation - End
   ********************************************************/

  cout << "<" << name << "> ............ Stop Simulation" << endl;

  delete CLOCK;

  for (uint32_t i=0; i<_param._nb_port_read; i++)
    {
      delete READ_IN_VAL       [i];
      delete READ_IN_ACK       [i];
      delete READ_IN_ADDRESS   [i];
      delete READ_IN_DATA      [i];
    }
  						      
  delete READ_IN_VAL    ;
  delete READ_IN_ACK    ;
  delete READ_IN_ADDRESS;
  delete READ_IN_DATA   ;

   for (uint32_t i=0; i<_param._nb_bank; i++)
     {
       for (uint32_t j=0; j<_param._nb_port_read_by_bank; j++)
	 {
	   for (uint32_t k=0; k<_param._nb_port_select_by_bank_read_port[j]; k++)
	     {
	       delete READ_SELECT_VAL [i][j][k];
	       delete READ_SELECT_ACK [i][j][k];
	     }
	   delete READ_SELECT_VAL [i][j];
	   delete READ_SELECT_ACK [i][j];
	 }
       delete READ_SELECT_VAL [i];
       delete READ_SELECT_ACK [i];
     }
   delete READ_SELECT_VAL;
   delete READ_SELECT_ACK;

   for (uint32_t i=0; i<_param._nb_bank; i++)
     {
  	for (uint32_t j=0; j<_param._nb_port_read_by_bank; j++)
  	  {
  	    delete READ_OUT_VAL      [i][j];
  	    delete READ_OUT_ACK      [i][j];
  	    delete READ_OUT_ADDRESS  [i][j];
  	    delete READ_OUT_DATA     [i][j];
  	  }

  	delete READ_OUT_VAL      [i];
  	delete READ_OUT_ACK      [i];
  	delete READ_OUT_ADDRESS  [i];
  	delete READ_OUT_DATA     [i];
     }

  delete READ_OUT_VAL    ;
  delete READ_OUT_ACK    ;
  delete READ_OUT_ADDRESS;
  delete READ_OUT_DATA   ;

  for (uint32_t i=0; i<_param._nb_port_write; i++)
    {
      delete WRITE_IN_VAL      [i];
      delete WRITE_IN_ACK      [i];
      delete WRITE_IN_ADDRESS  [i];
      delete WRITE_IN_DATA     [i];
    }

  delete WRITE_IN_VAL    ;
  delete WRITE_IN_ACK    ;
  delete WRITE_IN_ADDRESS;
  delete WRITE_IN_DATA   ;

  for (uint32_t i=0; i<_param._nb_bank; i++)
    {
      for (uint32_t j=0; j<_param._nb_port_write_by_bank; j++)
	{
	  for (uint32_t k=0; k<_param._nb_port_select_by_bank_write_port[j]; k++)
	    {
	      delete WRITE_SELECT_VAL [i][j][k];
	      delete WRITE_SELECT_ACK [i][j][k];
	    }
	  delete WRITE_SELECT_VAL [i][j];
	  delete WRITE_SELECT_ACK [i][j];
	}
      delete WRITE_SELECT_VAL [i];
      delete WRITE_SELECT_ACK [i];
    }
  delete WRITE_SELECT_VAL;
  delete WRITE_SELECT_ACK;
  
  for (uint32_t i=0; i<_param._nb_bank; i++)
    {
      for (uint32_t j=0; j<_param._nb_port_write_by_bank; j++)
  	 {
  	   delete WRITE_OUT_VAL     [i][j];
  	   delete WRITE_OUT_ACK     [i][j];
  	   delete WRITE_OUT_ADDRESS [i][j];
  	   delete WRITE_OUT_DATA    [i][j];
  	 }
      
      delete WRITE_OUT_VAL     [i];
      delete WRITE_OUT_ACK     [i];
      delete WRITE_OUT_ADDRESS [i];
      delete WRITE_OUT_DATA    [i];
    }
     
  delete WRITE_OUT_VAL    ;
  delete WRITE_OUT_ACK    ;
  delete WRITE_OUT_ADDRESS;
  delete WRITE_OUT_DATA   ;

#endif

  delete _RegisterFile_Multi_Banked_Glue;
}
