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


#include "secbus_lib.h"
#include <systemc>
#include "types.h"
#include "my_interfaces.h"

SC_MODULE(MS_Ctrl)
{
public:
  sc_in<bool>                         p_clk;
  sc_in<bool>                         p_resetn;

/*  sc_in<uint32_t>                     p_b_address;
  sc_in<uint32_t>                     p_mb_address;
  sc_in<uint32_t>                     p_size;
*/
  sc_in<bool>                         p_cache;

  //input inteface
  INTEGRITY_CTRL_CMD_IN               cmd_in;
  INTEGRITY_CTRL_ACK_OUT              ack_out;
  //mac cache controller if
  CACHE_CTRL_CMD_OUT                  cache_out_cmd;
  DATA_OUT<2>                         cache_out_wdata;
  CACHE_CTRL_ACK_IN                   cache_in_ack;
  DATA_IN<2>                          cache_in_rdata;
  //mac generator if
  CRYPTO_CMD_OUT                      mac_generator_out_cmd;
  DATA_OUT<12>                        mac_generator_out_data;
  DATA_IN<2>                          mac_generator_in_data;
  //mac engine is able to read security context registers
  CTX_REGISTER_READ_IN                sc_register;
  DATA_REGISTER_READ_IN               register_0_in;
  //register 1
  DATA_REGISTER_READ_IN               register_1_in;
  //register 2
  DATA_REGISTER_READ_IN               register_2_in;
  //memory interface for initialisation
  MEMORY_CTRL_CMD_OUT                 memory_out_cmd;
  DATA_OUT <2>                        memory_out_wdata;

  IRQ_OUT                             irq;

  enum mc_step_e
  {
    IDLE = 0,
    //check
    C_START_IV_GENERATION, 
    C_START_MAC_GENERATION, 
    C_WAIT_MAC_GENERATION, 
    C_START_READ_PARENT,
    C_WAIT_READ_PARENT,
    //update
    U_START_UPDATE_PARENT,
    U_WAIT_UPDATE_PARENT,
    U_START_WRITE_PARENT,
    U_WAIT_WRITE_PARENT,
    //initialize
    I_START_READ_SET, //7
    I_START_MAC_GENERATION,
    I_WAIT_MAC_GENERATION,
    I_START_WRITE_PARENT,
    I_WAIT_WRITE_PARENT,
    //
    MAC_INTEGRITY_ERROR
  };

  //internal signals
  sc_signal<int> state;
  sc_signal<addr_t> set_address_s;
  sc_signal<unsigned int> index_s;
  sc_signal<addr_t> mac_start_address_s;
  sc_signal<addr_t> mac_address_s;
  sc_signal<size_t> mac_page_size_s;
  sc_signal<int> cmd_in_s;
  sc_signal<uint32_t>  src_s;

  uint32_t m_cycle;
  uint32_t *key_s;
  uint32_t *mac_s;
  uint32_t *reference_mac_s;

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

  unsigned long int mac_count;

  void print_stats();
  void reset_stats();

  //Constructor
  MS_Ctrl(sc_module_name name);

  SC_HAS_PROCESS(MS_Ctrl);
};

#endif

