#include "../include/Cache_OneLevel.h"

namespace environment {
namespace cache {
namespace cache_onelevel {

  void Cache_OneLevel::transition (void)
  {
    // scan all port - test if have a transaction
    for (int32_t x = param->nb_port-1; x >= 0; x --)
      {
	if (access_port[x].valid == true)
	  {
	    access_port[x].valid = false;
	    
	    // Update LRU
	    //  * hit  : now
	    //  * miss : after the return of next cache
	    
	    if (access_port[x].hit == HIT_CACHE)
	      {// Hit
		update_lru(access_port[x].address.familly,access_port[x].num_associativity);
	      }
	    
	    if (access_port[x].hit == MISS)
	      {// Miss
		// Write in write_buffer
		write_buffer->push(access_port[x].latence,Write_Buffer(access_port[x].address,access_port[x].trdid));
	      }
	  }
      }
    
    write_buffer->transition();

    // Test if a write_buffer have the result
    while ((write_buffer->empty() == false) and 
	   (write_buffer->read(0)._delay == 0))
      {
	// Save in the cache
	Write_Buffer val = write_buffer->pop();
	
	uint32_t num_tag           = val.address.tag;
	uint32_t num_familly       = val.address.familly;
	uint32_t num_associativity = index_victim(num_familly);
	
	tag [num_familly][num_associativity].valid    = true;
	tag [num_familly][num_associativity].address  = num_tag;
	tag [num_familly][num_associativity].trdid    = val.trdid;
	
	update_lru(num_familly,num_associativity);
      }
    
  }
};
};
};
