/*
 * 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 _MSCACHE_CTRL_H_
#define _MSCACHE_CTRL_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(MSCache_Ctrl)
{
  
public:
  
  sc_in<bool>               p_clk;
  sc_in<bool>               p_resetn;
  //internal interface
  CACHE_CTRL_CMD_IN         in_cmd;
  DATA_IN<2>                in_wdata;
  CACHE_CTRL_ACK_OUT        out_ack;
  DATA_OUT<2>               out_rdata;
  //memory interface
  MEMORY_CTRL_CMD_OUT       out_cmd;
  DATA_OUT <2>              out_wdata;
//  ACK_IN                    in_ack;
  DATA_REGISTER_READ_IN     register_2_in;
  
  
  enum cc_read_step_e
  {
    R_IDLE = 0,
    R_TEST_HIT_SIGNAL,
    R_START_READ_BLOCK,	
    R_WAIT_READ_BLOCK,
    R_START_WRITE_BACK_BLOCK,
    R_WAIT_WRITE_BACK_BLOCK
  };

  enum cc_write_step_e
  {
    W_IDLE = 0,
    W_TEST_HIT_SIGNAL,
    W_START_WRITE_BLOCK,//2
    W_START_WRITE_THROUGH_BLOCK,
    W_START_WRITE_BACK_BLOCK,//4
    W_WAIT_WRITE_BLOCK,
    W_WAIT_WRITE_THROUGH_BLOCK,//6
    W_WAIT_WRITE_BACK_BLOCK

  };

  //internal signals
  sc_signal<int> read_state;
  sc_signal<int> write_state;
  sc_signal<addr_t> address_in_s;
  sc_signal<addr_t> address_256_s;
  sc_signal<unsigned int> index_s;

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

  //others
  cache_param_s cache_param;
  bool hit_s;
  pCacheblock_t victim_block;

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

  //cache statistics
  uint64_t read_misses;
  uint64_t write_misses;
  uint64_t write_back;
  uint64_t read_accesses;
  uint64_t write_accesses;


  void print_stats();
  void reset_stats();

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

  SC_HAS_PROCESS(MSCache_Ctrl);

};

#endif
