#include "cache.h"
#include "type_req_cache.h"
#include <iostream>
using namespace hierarchy_memory;
using namespace hierarchy_memory::cache;
using namespace std;

//-----[ Routine de test ]---------------------------------------

void test_ko (char * file, uint32_t line)
{
  cerr << "***** Test KO *****" << endl
       << " - File : " << file << endl
       << " - Line : " << line << endl;
  exit (line);
};

void test_ok ()
{
  cout << "***** Test OK *****" << endl;
  exit (0);
};

template <class T>
void test(T exp1, T exp2, char * file, uint32_t line)
{
  if (exp1 != exp2)
    {
      cerr << "Expression is different : " << endl
	   << " - exp1 : " << exp1 << endl
	   << " - exp2 : " << exp2 << endl;

      test_ko (file,line);
    }
};

#define TEST(type,exp1,exp2) do { test<type> (exp1,exp2,__FILE__,__LINE__);} while(0)

//-----[ main ]--------------------------------------------------
int main ()
{
  cout << "<main> Begin" << endl;

  //              name       , nb_line, size_line, size_word, associativity, hit_latence, miss_penality
#define L1a_CACHE "L1a_CACHE",       4,         2,         4,             4,           1,             5
#define L1b_CACHE "L1b_CACHE",       4,         4,         4,             2,           2,             4
#define L1c_CACHE "L1c_CACHE",       4,         2,         4,             1,           1,             6
#define L1d_CACHE "L1d_CACHE",       4,         2,         4,             4,           2,             3
#define L2_CACHE  "L2_CACHE" ,       8,         4,         4,             2,           2,             8
#define L3_CACHE  "L3_CACHE" ,      16,         8,         4,             1,           3,            15

  cout << " * 3 caches" << endl;
  cout << "   * L1 :  4 lines - 2 words - associtivity 4 ways" << endl;
  cout << "   * L2 :  8 lines - 4 words - associtivity 2 ways" << endl;
  cout << "   * L3 : 16 lines - 8 words - associtivity 1 ways" << endl;
  
  {
    const uint32_t NB_CACHE = 2;
    const uint32_t NB_PORT  = 3;

    cout << "<main> Test de \"Cache_Multilevel\"" << endl;
    
    param_cache_t param_cache [NB_CACHE] = { param_cache_t (L1a_CACHE) ,
					     param_cache_t (L2_CACHE) };
    Cache_Multilevel my_cache (cache_multilevel::param_t("my_cache_multilevel",NB_CACHE, NB_PORT, param_cache));
    
    my_cache.reset();
    
    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  0] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;
    
    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),16);
      }
    
    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  1] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;
    
    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;
    
    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),15);
      }
    
    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  2] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;
    
    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;
    
    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),14);
      }
    
    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  3] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;
    
    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;

    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x200+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),16);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  4] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  5] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  6] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  7] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;

    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),9);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  8] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  9] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 10] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 11] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 12] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 13] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 14] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 15] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 16] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 17] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 18] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 19] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 20] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;

    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),1);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 21] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;

    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x200+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),1);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 22] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;

    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x300+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),16);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 23] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;

    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x400+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),16);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 24] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;

    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x500+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),(uint32_t)16);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [+40] **********" << endl;
    cout << "**************************************" << endl;
    for (uint32_t it = 24; it < 40; it ++)
      {
	cout << it << endl;
	my_cache.transition();
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 40] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    cout << my_cache << endl;

    cout << "***** Read of " << NB_PORT << " consecutive address *****" << endl;

    for (uint32_t i = 0; i < NB_PORT; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (i,address,0,CACHED,READ),16);
      }

  }//end test Cache_Multilevel

  cout << "-------------------------------------------------------------------------" << endl;
  cout << "-------------------------------------------------------------------------" << endl;
  cout << "-------------------------------------------------------------------------" << endl;

  {
    const uint32_t nb_entity = 2;
    const uint32_t nb_iport  = 3;
    const uint32_t nb_dport  = 2;
   
    cout << "<main> Test de \"Cache\"" << endl;

    param_cache_t             param_cache_1a     [1] = { param_cache_t (L1a_CACHE) };
    param_cache_t             param_cache_1b     [1] = { param_cache_t (L1b_CACHE) };
    param_cache_t             param_cache_1c     [1] = { param_cache_t (L1c_CACHE) };
    param_cache_t             param_cache_1d     [1] = { param_cache_t (L1d_CACHE) };
    param_cache_t             param_cache_2      [2] = { param_cache_t (L2_CACHE) ,
							 param_cache_t (L3_CACHE) };
   
    cache_multilevel::param_t param_icache_dedicated [nb_entity] = {cache_multilevel::param_t ("param_icache_dedicated[0]",1,nb_iport,param_cache_1a),
								    cache_multilevel::param_t ("param_icache_dedicated[1]",1,nb_iport,param_cache_1b)};

    cache_multilevel::param_t param_dcache_dedicated [nb_entity] = {cache_multilevel::param_t ("param_dcache_dedicated[0]",1,nb_dport,param_cache_1c),
								    cache_multilevel::param_t ("param_dcache_dedicated[1]",1,nb_dport,param_cache_1d)};

    cache_multilevel::param_t param_cache_shared   ("param_cache_shared", 2, nb_entity*(nb_iport+nb_dport), param_cache_2);

    cache::param_t            param_cache          ("cache"                ,
						    nb_entity              ,
						    param_icache_dedicated ,
						    param_dcache_dedicated ,
						    param_cache_shared     );

    Cache my_cache (param_cache);

    ////cout << my_cache << endl;
    my_cache.reset();

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  0] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;
    
    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,1,i,address,0,CACHED,READ),34);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  1] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    // cout << my_cache << endl;
    
    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x200+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,1,i,address,0,CACHED,READ),34);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  2] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;
    
    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x300+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,1,i,address,0,CACHED,READ),(uint32_t)34);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  3] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    cout << my_cache << endl;

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,1,i,address,0,CACHED,READ),31);
      }

    //cout << my_cache << endl;

    cout << "***** Read of " << nb_dport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_dport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (DATA_CACHE,1,i,address,0,CACHED,READ),30); // miss penality is 3 
      }

    //cout << my_cache << endl;

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  4] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    cout << my_cache << endl;

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,1,i,address,1,CACHED,READ),(uint32_t)34);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [+34] **********" << endl;
    cout << "**************************************" << endl;
    for (uint32_t it = 0; it < 30; it ++)
      {
	cout << it << endl;
	my_cache.transition();
	if (it == 0)
	  cout << my_cache << endl;

      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 34] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    cout << my_cache << endl;

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x200+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,1,i,address,0,CACHED,READ), 2);
      }

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_dport; i ++)
      {
	uint address = 0x200+i*4;
	TEST(uint32_t, my_cache.latence (DATA_CACHE,0,i,address,0,CACHED,READ),20); // Miss L1-L2 Hit L3
      }
    
    
  }//end test Cache

  cout << "-------------------------------------------------------------------------" << endl;
  cout << "-------------------------------------------------------------------------" << endl;
  cout << "-------------------------------------------------------------------------" << endl;


  {
    const uint32_t nb_entity = 1;
    const uint32_t nb_iport  = 3;
    const uint32_t nb_dport  = 2;
   
    cout << "<main> Test de \"Cache\"" << endl;

    param_cache_t             param_cache_1a     [1] = { param_cache_t (L1a_CACHE) };
    param_cache_t             param_cache_1b     [1] = { param_cache_t (L1b_CACHE) };
   
    cache_multilevel::param_t param_icache_dedicated [nb_entity] = {cache_multilevel::param_t ("param_icache_dedicated[0]",1,nb_iport,param_cache_1a)};

    cache_multilevel::param_t param_dcache_dedicated [nb_entity] = {cache_multilevel::param_t ("param_dcache_dedicated[0]",1,nb_dport,param_cache_1b)};

    cache_multilevel::param_t param_cache_shared   ("param_cache_shared",0, 0, NULL);

    cache::param_t            param_cache          ("cache"                ,
						    nb_entity              ,
						    param_icache_dedicated ,
						    param_dcache_dedicated ,
						    param_cache_shared     );

    Cache my_cache (param_cache);

    cout << my_cache << endl;
   
    my_cache.reset();

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  0] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)6);
      }

    cout << "***** Read of " << nb_dport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_dport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (DATA_CACHE,0,i,address,1,CACHED,READ),(uint32_t)6);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  1] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)5);
      }


  }

  {
    const uint32_t nb_entity = 1;
    const uint32_t nb_iport  = 3;
    const uint32_t nb_dport  = 2;
   
    cout << "<main> Test de \"Cache\"" << endl;

    param_cache_t             param_cache_2      [1] = { param_cache_t (L2_CACHE)};

    cache_multilevel::param_t param_icache_dedicated [nb_entity] = {cache_multilevel::param_t ("param_icache_dedicated[0]",0,nb_iport,NULL)};

    cache_multilevel::param_t param_dcache_dedicated [nb_entity] = {cache_multilevel::param_t ("param_dcache_dedicated[0]",0,nb_dport,NULL)};

    cache_multilevel::param_t param_cache_shared   ("param_cache_shared",1, nb_entity * (nb_iport + nb_dport), param_cache_2);

    cache::param_t            param_cache          ("cache"                ,
						    nb_entity              ,
						    param_icache_dedicated ,
						    param_dcache_dedicated ,
						    param_cache_shared     );

    Cache my_cache (param_cache);

    cout << my_cache << endl;
   
    my_cache.reset();

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  0] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)10);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  1] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)9);
      }

    cout << "***** Read of " << nb_dport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_dport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (DATA_CACHE,0,i,address,1,CACHED,READ),(uint32_t)9);
      }


  }

  cout << "-------------------------------------------------------------------------" << endl;
  cout << "-------------------------------------------------------------------------" << endl;
  cout << "-------------------------------------------------------------------------" << endl;

  {
    const uint32_t nb_entity = 1;
    const uint32_t nb_iport  = 3;
    const uint32_t nb_dport  = 2;
    
    cout << "<main> Test des Types et direction" << endl;

    param_cache_t             param_cache_1a     [1] = { param_cache_t (L1a_CACHE) };
    param_cache_t             param_cache_1b     [1] = { param_cache_t (L1b_CACHE) };
    param_cache_t             param_cache_2      [1] = { param_cache_t (L2_CACHE)  };
   
    cache_multilevel::param_t param_icache_dedicated [nb_entity] = {cache_multilevel::param_t ("param_icache_dedicated[0]",1,nb_iport,param_cache_1a)};
    cache_multilevel::param_t param_dcache_dedicated [nb_entity] = {cache_multilevel::param_t ("param_dcache_dedicated[0]",1,nb_dport,param_cache_1b)};
    cache_multilevel::param_t param_cache_shared   ("param_cache_shared",1, nb_entity*(nb_iport+nb_dport), param_cache_2);

    cache::param_t            param_cache          ("cache"                ,
						    nb_entity              ,
						    param_icache_dedicated ,
						    param_dcache_dedicated ,
						    param_cache_shared     );

    Cache my_cache (param_cache);

    //    cout << my_cache << endl;
    my_cache.reset();


    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  0] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
    //cout << my_cache << endl;

    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)16);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [+ 9] **********" << endl;
    cout << "**************************************" << endl;
    for (uint32_t it = 1; it < 9; it ++)
      {
	cout << it << endl;
	my_cache.transition();
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  9] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
         cout << my_cache << endl;
    
    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x200+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)16);
      }

    cout << "***** Read of " << nb_dport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_dport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (DATA_CACHE,0,i,address,1,CACHED,READ),(uint32_t)8);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  5] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
//     cout << my_cache << endl;
    
    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)6);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  6] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
//     cout << my_cache << endl;
    
    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,UNCACHED,READ),(uint32_t)16);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [  7] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
//  cout << my_cache << endl;
    
    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)4);
      }
    
    cout << "**************************************" << endl;
    cout << "********** TRANSITION [+18] **********" << endl;
    cout << "**************************************" << endl;
    for (uint32_t it = 8; it < 18; it ++)
      {
	cout << it << endl;
	my_cache.transition();
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 18] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
//  cout << my_cache << endl;
    
    cout << "***** Read of " << nb_iport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_iport; i ++)
      {
	uint address = 0x100+i*4;
	TEST(uint32_t, my_cache.latence (INSTRUCTION_CACHE,0,i,address,1,CACHED,READ),(uint32_t)1);
      }

    cout << "***** Read of " << nb_dport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_dport; i ++)
      {
	uint address = 0x200+i*4;
	TEST(uint32_t, my_cache.latence (DATA_CACHE,0,i,address,1,CACHED,READ),(uint32_t)8);
      }

    cout << "**************************************" << endl;
    cout << "********** TRANSITION [ 19] **********" << endl;
    cout << "**************************************" << endl;
    my_cache.transition();
//  cout << my_cache << endl;
    
    cout << "***** Read of " << nb_dport << " consecutive address *****" << endl;
    for (uint32_t i = 0; i < nb_dport; i ++)
      {
	uint address = 0x200+i;
	TEST(uint32_t, my_cache.latence (DATA_CACHE,0,i,address,1,CACHED,READ),(uint32_t)7);
      }

  }

  test_ok ();
}//end main  
