#ifndef ENVIRONMENT_CACHE_CACHE_ONELEVEL_H
#define ENVIRONMENT_CACHE_CACHE_ONELEVEL_H

#include "Cache_OneLevel_Access_Port.h"
#include "Cache_OneLevel_Address.h"
#include "Cache_OneLevel_Tag.h"
#include "Cache_OneLevel_Write_Buffer.h"
#include "Cache_OneLevel_Parameters.h"
#include "../../Queue/include/Sort_Queue_Dynamic.h"
#include "../../Common/include/Debug.h"

namespace environment {
namespace cache {
namespace cache_onelevel {

  class Cache_OneLevel
  {
  protected : std::string    name;
  protected : Parameters   * param;
  private   : Tag         ** tag;
  private   : Access_Port  * access_port;
  private   : Address        size_address;
  private   : queue::Sort_Queue_Dynamic<Write_Buffer> * write_buffer;

  protected : queue::Parameters * param_write_buffer;

  public    :  Cache_OneLevel (std::string name,
			    Parameters * param);

  public    : ~Cache_OneLevel (void);



  public    : void             reset                  (void);
  public    : void             transition             (void);
  private   : void             update_lru             (uint32_t familly, uint32_t num_associativity);
  private   : uint32_t         index_victim           (uint32_t familly);
  private   : Address          translate_address      (uint32_t address);
  public    : type_rsp_cache_t access                 (uint32_t num_port, uint32_t address, uint32_t trdid, type_req_cache_t type, direction_req_cache_t dir);
  private   : type_rsp_cache_t access_cached          (uint32_t num_port, uint32_t address, uint32_t trdid,                        direction_req_cache_t dir);
  private   : type_rsp_cache_t access_uncached        (uint32_t num_port, uint32_t address, uint32_t trdid);
  private   : type_rsp_cache_t access_invalidate      (uint32_t num_port, uint32_t address, uint32_t trdid);
  private   : type_rsp_cache_t access_flush           (uint32_t num_port, uint32_t address, uint32_t trdid);
  private   : type_rsp_cache_t access_lock            (uint32_t num_port, uint32_t address, uint32_t trdid);
  private   : type_rsp_cache_t access_prefetch        (uint32_t num_port, uint32_t address, uint32_t trdid);
  private   : type_rsp_cache_t access_synchronization (uint32_t num_port, uint32_t address, uint32_t trdid);
  private   : uint32_t         hit_write_buffer       (uint32_t trdid, Address address);
  private   : uint32_t         hit_cache              (uint32_t trdid, Address address);
  private   : uint32_t         hit_access_port        (uint32_t trdid, Address address);
  public    : uint32_t         need_slot              (void);
  public    : uint32_t         latence                (uint32_t num_port);
  public    : uint32_t         update_latence         (uint32_t num_port, uint32_t latence);
  public    : std::string      information            (uint32_t depth);

  public    : friend std::ostream& operator<< (std::ostream& output, Cache_OneLevel & x);
    };

};
};
};
#endif
