/*
 * SecBus - This file is part of SecBus
 * Copyright (C) 2012 - Telecom ParisTech
 * 
 * This file must be used under the terms of the CeCILL.
 * This source file is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at    
 * http://www.cecill.info/licences/Licence_CeCILL_V1.1-US.txt
 *
 */


#ifndef _MTCACHECONTROLLER_H_
#define _MTCACHECONTROLLER_H_

#include "cache.h"
#include "types.h"
#include "global.h"
#include "buffer.h"
#include "systemc.h"
#include "secbus_lib.h"
#include "my_interfaces.h"
#include <iostream>

SC_MODULE(MTCache_Ctrl)
{

  sc_in<bool>               p_clk;
  sc_in<bool>               p_resetn;
  //input inteface
  CACHE_CTRL_CMD_IN         in_cmd;
  DATA_IN <2>               in_wdata;
  CACHE_CTRL_ACK_OUT        out_ack;
  DATA_OUT <2>              out_rdata;
  //output interfaces
  MEMORY_CTRL_CMD_OUT       out_cmd;
  DATA_OUT <2>              out_wdata;
//  ACK_IN                    in_ack;
  DATA_REGISTER_READ_IN     register_2_in;

  enum rd_state_e
  {
    RD_IDLE = 0,
    RD_TEST_HIT_SIGNAL,
    RD_START_READ_BLOCK,	
    RD_WAIT_READ_BLOCK
  };

  enum i_state_e
  {
    I_IDLE = 0,
    I_TEST_HIT_SIGNAL
  };

  enum s_state_e
  {
    S_IDLE = 0,
    S_TEST_HIT_SIGNAL,
    S_START_READ_BLOCK,//4	
    S_START_WRITE_BLOCK,
    S_WAIT_WRITE_BLOCK,
    S_WAIT_READ_BLOCK
  };

  enum rst_state_e
  {
    RST_IDLE = 0,
    RST_TEST_HIT_SIGNAL,
    RST_START_RESTORE,
    RST_WAIT_RESTORE,
    RST_START_READ_BLOCK,
    RST_WAIT_READ_BLOCK,
    RST_WRITE_CACHE

  };
  enum wr_state_e
  {
    WR_IDLE = 0,
    WR_TEST_HIT_SIGNAL,
    WR_TEST_FULL_SIGNAL,
    WR_WRITE_CACHE
  };

  //internal signals

  sc_signal<int> i_state;
  sc_signal<int> s_state;
  sc_signal<int> rd_state;
  sc_signal<int> rst_state;
  sc_signal<int> wr_state;
  sc_signal<addr_t> address_in_s;
  sc_signal<addr_t> address_256_s;
  sc_signal<unsigned int> index_s;
  addr_t victim_address_s;
  bool hit_s;
  bool dirty_s;
  bool full_s;

  //instantiation of memory elements
  ComplexCache *cache0;
  uint32_t *block_s;

  //others
  cache_param_s cache_param;

  //Synchronous process
  void ps();
  //Conbinatory process
  void pc();

  //cache statistics
  uint64_t invalidate_accesses;
  uint64_t read_accesses;
  uint64_t write_accesses;
  uint64_t restore_accesses;
  uint64_t synchronize_accesses;
  uint64_t read_misses;
  uint64_t write_misses;
  uint64_t restore_misses;
  uint64_t synchronize_misses;

  void print_stats();
  void reset_stats();

  //Constructor
  MTCache_Ctrl(sc_module_name name, const cache_param_s & parameters);

  SC_HAS_PROCESS(MTCache_Ctrl);
};

#endif
