/*
 * 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 MY_INTERFACES__H_
#define MY_INTERFACES__H_

#include "systemc.h"
#include "types.h"

#include "if_helpers.h"

/** MEMORY CTRL CMD **/

CREATE_IF(MEMORY_CTRL_CMD)
{
public:
  IN<addr_t>       start_address;
  IN<unsigned int> plen;
  IN<unsigned int> id;
  IN<bool>         direct_write;
  IN<int>    cmd;
  IN<bool>         cmdval;
  OUT<bool>        cmdack;
  OUT<bool>        rspval;
};

class MEMORY_CTRL_CMD_IN;
class MEMORY_CTRL_CMD_OUT;

CREATE_SIGNAL(MEMORY_CTRL_CMD)
{
  ADD_OPERATOR(MEMORY_CTRL_CMD, IN);
  ADD_OPERATOR(MEMORY_CTRL_CMD, OUT);
};

CREATE_IN(MEMORY_CTRL_CMD)
{
  ADD_OPERATOR(MEMORY_CTRL_CMD, SIGNALS);
  void operator = (MEMORY_CTRL_CMD_SIGNALS &sig);
};

CREATE_OUT(MEMORY_CTRL_CMD)
{
  ADD_OPERATOR(MEMORY_CTRL_CMD, SIGNALS);
  void operator = (MEMORY_CTRL_CMD_SIGNALS &sig);
};

CREATE_SENSITIVE(MEMORY_CTRL_CMD, IN);
CREATE_SENSITIVE(MEMORY_CTRL_CMD, OUT);

/** DATA REGISTER READ **/

CREATE_IF(DATA_REGISTER_READ)
{
public:
  IN<int>          data[8];
  IN<unsigned int> be;
  IN<addr_t>       address;
};

CREATE_SIGNAL(DATA_REGISTER_READ)
{
};

CREATE_IN(DATA_REGISTER_READ)
{
  ADD_OPERATOR(DATA_REGISTER_READ, SIGNALS);
};

CREATE_OUT(DATA_REGISTER_READ)
{
  ADD_OPERATOR(DATA_REGISTER_READ, SIGNALS);
};

/** DATA REGISTER WRITE **/

CREATE_IF(DATA_REGISTER_WRITE)
{
public:
  IN<addr_t>       address;
  IN<bool>         enable;
  IN<bool>         flush;
  IN<int>          data[8];
  IN<unsigned int> be;
};

CREATE_SIGNAL(DATA_REGISTER_WRITE)
{
};

class DATA_REGISTER_WRITE_OUT;

CREATE_IN(DATA_REGISTER_WRITE)
{
  ADD_OPERATOR(DATA_REGISTER_WRITE, SIGNALS);
  ADD_OPERATOR(DATA_REGISTER_WRITE, OUT);
};

CREATE_SENSITIVE(DATA_REGISTER_WRITE, IN);

CREATE_OUT(DATA_REGISTER_WRITE)
{
  ADD_OPERATOR(DATA_REGISTER_WRITE, SIGNALS);
  ADD_OPERATOR(DATA_REGISTER_WRITE, IN);
};

/** SECURITY CTX CMD **/

CREATE_IF(SECURITY_CTX_CMD)
{
public:
  IN<bool>      enable;
  IN<int> cmd;
  IN<addr_t>    address;
  IN<bool>      mt;
  OUT<bool>     ack;
};
	
CREATE_SIGNAL(SECURITY_CTX_CMD)
{
};

class SECURITY_CTX_CMD_OUT;

CREATE_IN(SECURITY_CTX_CMD)
{
  ADD_OPERATOR(SECURITY_CTX_CMD, SIGNALS);
  ADD_OPERATOR(SECURITY_CTX_CMD, OUT);
};

CREATE_OUT(SECURITY_CTX_CMD)
{
  ADD_OPERATOR(SECURITY_CTX_CMD, SIGNALS);
  ADD_OPERATOR(SECURITY_CTX_CMD, IN);
};

CREATE_SENSITIVE(SECURITY_CTX_CMD, IN);

/** MASTER CTX REGISTER READ **/

CREATE_IF(MASTER_CTX_REG_READ)
{
public:
  IN<bool>     enable;
  IN<uint32_t> sp[SP_SIZE_IN_WORDS];
  IN<uint32_t> pspe[PSPE_SIZE_IN_WORDS];
};

CREATE_SIGNAL(MASTER_CTX_REG_READ)
{
};

CREATE_IN(MASTER_CTX_REG_READ)
{
  ADD_OPERATOR(MASTER_CTX_REG_READ, SIGNALS);
};

CREATE_OUT(MASTER_CTX_REG_READ)
{
  ADD_OPERATOR(MASTER_CTX_REG_READ, SIGNALS);
};

/** CTX REGISTER READ **/

CREATE_IF(CTX_REGISTER_READ)
{
public:
  IN<addr_t>   page_address;
  IN<uint32_t> m_pspe[PSPE_SIZE_IN_WORDS];
  IN<uint32_t> s_pspe_address;
  IN<addr_t>   s_page_address;
  IN<uint32_t> s_pspe[PSPE_SIZE_IN_WORDS];
  IN<uint32_t> sp[SP_SIZE_IN_WORDS];
};

CREATE_SIGNAL(CTX_REGISTER_READ)
{
};

CREATE_IN(CTX_REGISTER_READ)
{
  ADD_OPERATOR(CTX_REGISTER_READ, SIGNALS);
};

CREATE_OUT(CTX_REGISTER_READ)
{
  ADD_OPERATOR(CTX_REGISTER_READ, SIGNALS);
};

/** IRQ **/

CREATE_IF(IRQ)
{
public:
  IN<bool>             irq;
  IN<addr_t>           address;
  IN<int> type;
  IN<int> op;
  OUT<bool>            ack;
};

CREATE_SIGNAL(IRQ)
{
};

CREATE_IN(IRQ)
{
  ADD_OPERATOR(IRQ, SIGNALS);
};

CREATE_OUT(IRQ)
{
  ADD_OPERATOR(IRQ, SIGNALS);
};

/** SECURITY_RQ **/

CREATE_IF(SECURITY_RQ)
{
public:
  IN<addr_t>    address;
  IN<bool>      enable;
  IN<int> cmd;
  IN<bool>      cmdval;
  IN<uint32_t>  be;
  IN<bool>      mb;
  OUT<bool>     cmdack;
  OUT<bool>     rspval;
};

CREATE_SIGNAL(SECURITY_RQ)
{
};

CREATE_IN(SECURITY_RQ)
{
  ADD_OPERATOR(SECURITY_RQ, SIGNALS);
};

CREATE_SENSITIVE(SECURITY_RQ, IN);

CREATE_OUT(SECURITY_RQ)
{
  ADD_OPERATOR(SECURITY_RQ, SIGNALS);
};

CREATE_SENSITIVE(SECURITY_RQ, OUT);

/** ACK **/

CREATE_IF(ACK)
{
public:
  IN<bool> rack;
  IN<bool> wack;
};

CREATE_SIGNAL(ACK)
{
};

CREATE_IN(ACK)
{
  ADD_OPERATOR(ACK, SIGNALS);
};

CREATE_OUT(ACK)
{
  ADD_OPERATOR(ACK, SIGNALS);
};

/** DATA **/

CREATE_IF(DATA, int size_in_words)
{
public:
  IN<bool> enable;
  IN<uint32_t> data[size_in_words];
};

template<int size_in_words>
CREATE_SIGNAL(DATA, size_in_words)
{
};

template<int size_in_words>
class DATA_OUT;

template<int size_in_words>
CREATE_IN(DATA, size_in_words)
{
  TPL_IN(DATA, size_in_words);
  ADD_TPLOPERATOR(DATA, SIGNALS, size_in_words);
  ADD_TPLOPERATOR(DATA, OUT, size_in_words);
};

template<int size_in_words>
CREATE_OUT(DATA, size_in_words)
{
  TPL_OUT(DATA, size_in_words);
  ADD_TPLOPERATOR(DATA, SIGNALS, size_in_words);
  ADD_TPLOPERATOR(DATA, IN, size_in_words);
};

/** CRYPTO CMD **/

CREATE_IF(CRYPTO_CMD)
{
public:
  IN<bool>         cipher;
  IN<bool>         enable;
  IN<int> mode;
  IN<bool>         cmdval;
  IN<size_t>       id_src;
  IN<size_t>       id_dest;
  IN<bool>         reg_ready;
  IN<bool>         direct_data;
  IN<bool>         no_init;
  IN<uint32_t>     key[DES_KEY_SIZE_IN_WORDS];
  IN<uint32_t>     iv[IV_SIZE_IN_WORDS];
  IN<addr_t>       address;
  IN<size_t>       size;

  OUT<bool>        cmdack;
  OUT<bool>        rspval;
};

class CRYPTO_CMD_IN;
class CRYPTO_CMD_OUT;

CREATE_SIGNAL(CRYPTO_CMD)
{
  ADD_OPERATOR(CRYPTO_CMD, IN);
  ADD_OPERATOR(CRYPTO_CMD, OUT);
};

CREATE_IN(CRYPTO_CMD)
{
  ADD_OPERATOR(CRYPTO_CMD, SIGNALS);
  ADD_OPERATOR(CRYPTO_CMD, OUT);
  void operator = (CRYPTO_CMD_SIGNALS &sig);
};

CREATE_OUT(CRYPTO_CMD)
{
  ADD_OPERATOR(CRYPTO_CMD, SIGNALS);
  ADD_OPERATOR(CRYPTO_CMD, IN);
  void operator = (CRYPTO_CMD_SIGNALS &sig);
};

CREATE_SENSITIVE(CRYPTO_CMD, IN);
CREATE_SENSITIVE(CRYPTO_CMD, OUT);

/** IO BLOCK **/

CREATE_IF(IO_BLOCK, int size_in_words)
{
public:
  IN<uint32_t>     data[size_in_words];
  IN<int> cmd;
  IN<addr_t>       addr;
};

template<int size_in_words>
CREATE_SIGNAL(IO_BLOCK, size_in_words)
{
};

template<int size_in_words>
CREATE_IN(IO_BLOCK, size_in_words)
{
  TPL_IN(IO_BLOCK, size_in_words);
  ADD_TPLOPERATOR(IO_BLOCK, SIGNALS, size_in_words);
};

template<int size_in_words>
CREATE_OUT(IO_BLOCK, size_in_words)
{
  TPL_OUT(IO_BLOCK, size_in_words);
  ADD_TPLOPERATOR(IO_BLOCK, SIGNALS, size_in_words);
};  

/** CACHE_CTRL_ACK **/

CREATE_IF(CACHE_CTRL_ACK)
{
public:
  IN<bool>   rack;
  IN<bool>   wack; 
  IN<bool>   sack; 
  IN<bool>   rstack;
  IN<bool>   full; 
  IN<bool>   hit;  
  IN<bool>   dirty;
  IN<addr_t> victim_address;
};

CREATE_SIGNAL(CACHE_CTRL_ACK)
{
};

CREATE_IN(CACHE_CTRL_ACK)
{
  ADD_OPERATOR(CACHE_CTRL_ACK, SIGNALS);
};

CREATE_OUT(CACHE_CTRL_ACK)
{
  ADD_OPERATOR(CACHE_CTRL_ACK, SIGNALS);
};

/** CACHE_CTRL_CMD **/

CREATE_IF(CACHE_CTRL_CMD)
{
public:
  IN<addr_t>          address;
  IN<bool>            enable;
  IN<int>  cmd;
};

CREATE_SIGNAL(CACHE_CTRL_CMD)
{
};

CREATE_IN(CACHE_CTRL_CMD)
{
  ADD_OPERATOR(CACHE_CTRL_CMD, SIGNALS);
};

CREATE_OUT(CACHE_CTRL_CMD)
{
  ADD_OPERATOR(CACHE_CTRL_CMD, SIGNALS);
};

/** INTEGRITY_CTRL_CMD **/

CREATE_IF(INTEGRITY_CTRL_CMD)
{
public:
  IN<addr_t>          address;
  IN<bool>            enable;
  IN<int> cmd;
  IN<uint32_t>        src;
};

CREATE_SIGNAL(INTEGRITY_CTRL_CMD)
{
};

class INTEGRITY_CTRL_CMD_OUT;

CREATE_IN(INTEGRITY_CTRL_CMD)
{
  ADD_OPERATOR(INTEGRITY_CTRL_CMD, SIGNALS);
  ADD_OPERATOR(INTEGRITY_CTRL_CMD, OUT);
};

CREATE_OUT(INTEGRITY_CTRL_CMD)
{
  ADD_OPERATOR(INTEGRITY_CTRL_CMD, SIGNALS);
  ADD_OPERATOR(INTEGRITY_CTRL_CMD, IN);
};

CREATE_SENSITIVE(INTEGRITY_CTRL_CMD, IN);
CREATE_SENSITIVE(INTEGRITY_CTRL_CMD, OUT);

/** INTEGRITY_CTRL_ACK **/
CREATE_IF(INTEGRITY_CTRL_ACK)
{
public:
  IN<bool> cack;
  IN<bool> uack;
  IN<bool> alap_ack;
  IN<bool> iack;
};

CREATE_SIGNAL(INTEGRITY_CTRL_ACK)
{
};

CREATE_IN(INTEGRITY_CTRL_ACK)
{
  ADD_OPERATOR(INTEGRITY_CTRL_ACK, SIGNALS);
};

CREATE_OUT(INTEGRITY_CTRL_ACK)
{
  ADD_OPERATOR(INTEGRITY_CTRL_ACK, SIGNALS);
};

#endif
