#ifndef _SCCONTROLLER_H_
#define _SCCONTROLLER_H_

#include "systemc.h"
#include "global.h"
#include "types.h"
#include "my_interfaces.h"
#include "secbus_lib.h"
#include "cache_controller.h"

SC_MODULE(SecurityContextController)
{

private:

	enum security_context_state_e
	{
		IDLE = 0,
		TEST_PSPE_HIT_SIGNAL,
		START_READ_PSPE_BLOCK,
		WAIT_READ_PSPE_BLOCK,             //3
	  START_WRITE_BACK_PSPE_BLOCK, 
	  WAIT_WRITE_BACK_PSPE_BLOCK,
    START_WRITE_PSPE_BLOCK,
	  WAIT_WRITE_PSPE_BLOCK,
	  START_WRITE_THROUGH_PSPE_BLOCK,
	  WAIT_WRITE_THROUGH_PSPE_BLOCK,
	  WRITE_SPSPE_REGISTER,           //10
	  WRITE_4M_ALAP_SPSPE_REGISTER,
	  WRITE_4M_MPSPE_REGISTER,
	  TEST_SP_HIT_SIGNAL,             //13
    START_WRITE_SP_BLOCK,
		WAIT_WRITE_SP_BLOCK,
	  START_WRITE_THROUGH_SP_BLOCK,
	  START_READ_SP_BLOCK,            //17
	  START_WRITE_BACK_SP_BLOCK,
	  WAIT_WRITE_BACK_SP_BLOCK,
	  WAIT_WRITE_THROUGH_SP_BLOCK,
	  WAIT_READ_SP_BLOCK,             //21
	  ERROR
	};

	//internal signals
	sc_signal<security_context_state_e> state;
	sc_signal<addr_t>	sp_address_s;
	sc_signal<addr_t>	pspe_address_s;
  sc_signal<leveltype_e>	level_s;
  sc_signal<initiator_e>	initiator_s;

	//Only 4k pages
	bool mode_4K;

public :

	sc_in<bool>			          clk;
	sc_in<bool>               reset;
	//regular input cmd
	SECURITY_CONTEXT_CMD_IN   reg_in_cmd;
	DATA_IN <4>               reg_in_data;
	//htm input cmd
	SECURITY_CONTEXT_CMD_IN   htm_in_cmd;
	DATA_IN <2>               htm_in_data;
	//output ack
	ACK_OUT                   out_ack;
	//memory interface
	MEMORY_CONTROLLER_CMD_OUT sc_out_cmd;
	DATA_OUT <4>              sc_out_wdata;
	ACK_IN                    sc_in_ack;
	DATA_IN <4>               sc_in_rdata;
	//Current Security Context
  SECURITY_CONTEXT_REGISTER_READ_IN scr_out;

	//instantiation of cache elements
	Cache * pspe_cache;
	Cache * sp_cache;
	cache_param_st pspe_cache_param;
	cache_param_st sp_cache_param;
	bool hit_s;
	pCacheblock_t sp_victim_block;
	pCacheblock_t pspe_victim_block;

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

	sec_cmd_e	cmd_in;
	addr_t	address_in;
	bool	en_in;
	int *pspe;
	int *sp;
	int addr;
	master_security_context_st m_scontext;
	slave_security_context_st s_scontext;

  // cycle counters
  unsigned long int m_cpt_r;
  unsigned long int m_cpt_rpspe;
  unsigned long int m_cpt_rsp;
	//cache statistics
	uint64_t sp_read_misses;
	uint64_t sp_write_misses;
	uint64_t sp_write_back;
	uint64_t sp_read_accesses;
	uint64_t sp_write_accesses;
	uint64_t pspe_read_misses;
	uint64_t pspe_write_misses;
	uint64_t pspe_write_back;
	uint64_t pspe_read_accesses;
	uint64_t pspe_write_accesses;

	ofstream *doutput;
	ofstream *soutput;

	unsigned int i;
	//Constructor
	SecurityContextController(sc_module_name name, const cache_param_st & pspe_parameters, const cache_param_st & sp_parameters, ofstream * dfile, ofstream * sfile);

	SC_HAS_PROCESS(SecurityContextController);

	

};
#endif


